Commits

Dimitris Zenios  committed e2ef20a

1.Major refactoring
2.Documentation

  • Participants
  • Parent commits 1f18e1c

Comments (0)

Files changed (29)

 	</developers>
 
 	<scm>
-		<connection>scm:git:git@bitbucket.org:zenios/tapestry-zbreadcrumbs.git</connection>
-		<developerConnection>scm:git:git@bitbucket.org:zenios/tapestry-zbreadcrumbs.git</developerConnection>
-		<url>git@bitbucket.org:zenios/tapestry-zbreadcrumbs.git</url>
+		<connection>scm:git:http://bitbucket.org/zenios/tapestry-zbreadcrumbs</connection>
+		<developerConnection>scm:git:https://bitbucket.org/zenios/tapestry-zbreadcrumbs</developerConnection>
+		<url>http://bitbucket.org/zenios/tapestry-zbreadcrumbs</url>
 	</scm>
 
 	<issueManagement>
 			<groupId>org.apache.tapestry</groupId>
 			<artifactId>tapestry-core</artifactId>
 			<version>${tapestry-release-version}</version>
+			<scope>compile</scope>
 		</dependency>
 
 		<dependency>
 			<groupId>org.apache.tapestry</groupId>
 			<artifactId>tapestry-ioc</artifactId>
 			<version>${tapestry-release-version}</version>
+			<scope>compile</scope>
 		</dependency>
 
+		<!-- <dependency>
+			<groupId>org.apache.tapestry</groupId>
+			<artifactId>tapestry-test</artifactId>
+			<version>${tapestry-release-version}</version>
+			<scope>test</scope>
+		</dependency> -->
+
 		<dependency>
 			<groupId>javax.servlet</groupId>
 			<artifactId>servlet-api</artifactId>
 	</dependencies>
 
 	<build>
-		<pluginManagement>
-			<plugins>
-
-				<plugin>
-					<groupId>org.codehaus.mojo</groupId>
-					<artifactId>findbugs-maven-plugin</artifactId>
-					<version>2.4.0</version>
-				</plugin>
-			</plugins>
-		</pluginManagement>
-
 		<plugins>
 			<plugin>
 				<groupId>org.apache.maven.plugins</groupId>
 					<configLocation>src/test/resources/checkstyle/checkstyle.xml</configLocation>
 				</configuration>
 			</plugin>
+			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-site-plugin</artifactId>
+				<version>3.0-beta-3</version>
+			</plugin>
 		</plugins>
 	</build>
 
 	<reporting>
 		<plugins>
 			<plugin>
+				<groupId>org.apache.maven.plugins</groupId>
+				<artifactId>maven-javadoc-plugin</artifactId>
+				<version>2.8.1</version>
+				<configuration>
+					<taglet>org.apache.tapestry5.javadoc.TapestryDocTaglet</taglet>
+					<tagletArtifact>
+						<groupId>org.apache.tapestry</groupId>
+						<artifactId>tapestry-javadoc</artifactId>
+						<version>${tapestry-release-version}</version>
+					</tagletArtifact>
+				</configuration>
+			</plugin>
+			<plugin>
 				<groupId>org.codehaus.mojo</groupId>
 				<artifactId>findbugs-maven-plugin</artifactId>
 				<version>2.4.0</version>
 				<artifactId>maven-jxr-plugin</artifactId>
 				<version>2.2</version>
 			</plugin>
-
-			<plugin>
-				<groupId>org.apache.maven.plugins</groupId>
-				<artifactId>maven-surefire-report-plugin</artifactId>
-				<version>2.12</version>
-			</plugin>
-
+			<!-- <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-surefire-report-plugin</artifactId> 
+				<version>2.12</version> </plugin> -->
 			<plugin>
 				<groupId>org.codehaus.mojo</groupId>
 				<artifactId>taglist-maven-plugin</artifactId>
 		</plugins>
 	</reporting>
 
-	<profiles>
-		<profile>
-			<id>sonatype-oss-release</id>
-			<build>
-				<plugins>
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-source-plugin</artifactId>
-						<version>2.1.2</version>
-						<executions>
-							<execution>
-								<id>attach-sources</id>
-								<goals>
-									<goal>jar-no-fork</goal>
-								</goals>
-							</execution>
-						</executions>
-					</plugin>
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-javadoc-plugin</artifactId>
-						<version>2.7</version>
-						<executions>
-							<execution>
-								<id>attach-javadocs</id>
-								<goals>
-									<goal>jar</goal>
-								</goals>
-							</execution>
-						</executions>
-					</plugin>
-					<plugin>
-						<groupId>org.apache.maven.plugins</groupId>
-						<artifactId>maven-gpg-plugin</artifactId>
-						<version>1.1</version>
-						<executions>
-							<execution>
-								<id>sign-artifacts</id>
-								<phase>verify</phase>
-								<goals>
-									<goal>sign</goal>
-								</goals>
-							</execution>
-						</executions>
-					</plugin>
-				</plugins>
-			</build>
-		</profile>
-	</profiles>
-
 	<properties>
 		<jdk.version>1.6</jdk.version>
 		<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>

File src/main/java/com/zenios/tapestry/breadcrumbs/annotation/BreadCrumb.java

 import java.lang.annotation.RetentionPolicy;
 import java.lang.annotation.Target;
 
+import org.apache.tapestry5.ioc.annotations.AnnotationUseContext;
+import org.apache.tapestry5.ioc.annotations.UseWith;
+
+
+/**
+ * A marker annotation that controls breadcrumb behaviour on the attached page
+ *
+ */
 @Target(ElementType.TYPE)
 @Retention(RetentionPolicy.RUNTIME)
 @Documented
+@UseWith(AnnotationUseContext.PAGE)
 public @interface BreadCrumb
 {
+	/**
+	 * Whether to ignore the attached page and not include it in the breadcrumbs trail.
+	 */
 	boolean ignore() default false;
 
+	
+	/**
+	 * Whether to reset the whole breadcrumbs list.
+	 * <p/>
+	 * If used in association with the {@link BreadCrumb#ignore()} property then it will first 
+	 * reset the list and then ignore the page
+	 */
 	boolean reset() default false;
-
-	boolean dynamicTitle() default false;
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/components/BreadCrumbInfo.java

 import org.apache.tapestry5.ioc.Messages;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.annotations.Symbol;
-import org.apache.tapestry5.ioc.internal.util.TapestryException;
 import org.apache.tapestry5.runtime.Component;
 import org.apache.tapestry5.services.ComponentSource;
 
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
 import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsEvents;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsEventConstants;
 
+/**
+ * Part of BreadCrumbsTrail that renders the markup inside a single data  &lt;li&gt;.
+ * 
+ * @tapestrydoc
+ */
 public class BreadCrumbInfo
 {
 	@Inject
 	private ComponentSource componentSource;
 
+
+    /**
+     * The current breadcrumb being rendered.
+     */
 	@Property
 	@Parameter(required = true, principal = true, autoconnect = true)
-	private BreadCrumbObject crumb;
+	private BreadCrumbElement value;
 
+	
+    /**
+     * A Block to render before each breadcrumb. The default is null. This parameter is used to change the default, possibly including components to
+     * allow the user to create new objects.
+     */
 	@Parameter(value = "block:before", defaultPrefix = BindingConstants.LITERAL)
 	private Block before;
 
+	
+    /**
+     * A Block to render after each breadcrumb. The default is null. This parameter is used to change the default, possibly including components to
+     * allow the user to create new objects.
+     */
 	@Parameter(value = "block:after", defaultPrefix = BindingConstants.LITERAL)
 	private Block after;
 
+	
+    /**
+     * A Block to render each breadcrumb. The default is @{link org.apache.tapestry5.corelib.components.PageLink} along with the page title.
+     * <p>
+     * The page title is calculated by:
+     * <ul>
+     * <li>Using a page event {@link com.zenios.tapestry.breadcrumbs.other.BreadCrumbsEventConstants#GET_TITLE}</li>
+     * <li>Using message catalogues by appending {@link com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants#BREADCRUMBS_TITLE_SUFFIX} </li>
+     * <li>Logical page name {@link com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement#getLogicalPageName()}</li>
+     * </ul>
+     * </p>
+     * The user can override this block in order to change default value, possibly including components to
+     * allow the user to create new objects.
+     */
 	@SuppressWarnings("unused")
 	@Property
-	@Parameter(value = "block:title", defaultPrefix = BindingConstants.LITERAL)
-	private Block title;
+	@Parameter(value = "block:inside", defaultPrefix = BindingConstants.LITERAL)
+	private Block inside;
 
 	@Inject
 	@Symbol(BreadCrumbsConstants.BREADCRUMBS_TITLE_SUFFIX)
 	}
 
 	public String getNameTitle() {
-		String pageName = crumb.getLogicalPageName();
+		String pageName = value.getLogicalPageName();
 		Component page = componentSource.getPage(pageName);
 		String title = null;
-		if (crumb.isTitleEvent()) {
-			final Holder<String> valueHolder = Holder.create();
-			ComponentEventCallback<String> callback = new ComponentEventCallback<String>()
-			{
-				public boolean handleResult(String result) {
-					valueHolder.put(result);
-
-					return true;
-				}
-			};
-
-			boolean handled = page.getComponentResources().triggerContextEvent(BreadCrumbsEvents.GET_TITLE, crumb.getActivationContext(), callback);
-			if (!handled) {
-				throw new TapestryException(String.format("Request event '%s' (on component %s) was not handled; you must provide a matching event handler method in the component or in one of its containers.", BreadCrumbsEvents.GET_TITLE, page.getComponentResources().getCompleteId()), page, null);
+		final Holder<String> valueHolder = Holder.create();
+		ComponentEventCallback<String> callback = new ComponentEventCallback<String>()
+		{
+			public boolean handleResult(String result) {
+				valueHolder.put(result);
+
+				return true;
 			}
-			title = valueHolder.get();
+		};
+
+		boolean handled = page.getComponentResources().triggerContextEvent(BreadCrumbsEventConstants.GET_TITLE, value.getActivationContext(), callback);
+		if(handled) {
+			return valueHolder.get();
 		}
 
 		if (title == null) {
 	}
 
 	public String getPage() {
-		return componentSource.getPage(crumb.getLogicalPageName()).getComponentResources().getCompleteId();
+		return componentSource.getPage(value.getLogicalPageName()).getComponentResources().getCompleteId();
 	}
 
 	public Object[] getActivationContext() {
-		EventContext context = crumb.getActivationContext();
+		EventContext context = value.getActivationContext();
 		int count = context.getCount();
 
 		Object[] pageActivationContext = new Object[count];

File src/main/java/com/zenios/tapestry/breadcrumbs/components/BreadCrumbsLoop.java

 
 import java.util.List;
 
+import org.apache.tapestry5.ComponentAction;
 import org.apache.tapestry5.annotations.Component;
 import org.apache.tapestry5.annotations.Parameter;
 import org.apache.tapestry5.annotations.Property;
-import org.apache.tapestry5.grid.GridConstants;
+import org.apache.tapestry5.corelib.components.Form;
 import org.apache.tapestry5.internal.TapestryInternalUtils;
 import org.apache.tapestry5.ioc.annotations.Inject;
 import org.apache.tapestry5.ioc.internal.util.CollectionFactory;
 import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.FormSupport;
 
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
 import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsModel;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsTrailConstantsValues;
 
+
+/**
+ * Part of {@link BreadCrumbsTrail} that renders out a series of crumbs within the  &lt;ul&gt;.
+ * 
+ * @tapestrydoc
+ */
 @SuppressWarnings("unused")
 public class BreadCrumbsLoop
 {
-
+	
+	private static final String BREADCRUMBS_FIRST_CLASS = "z-first";
+	private static final String BREADCRUMBS_LAST_CLASS = "z-last";
+	private static final String BREADCRUMBS_ACTIVE_CLASS = "z-active";
+
+    /**
+     * Parameter used to set the CSS class for each breadcrumb (each &lt;li&gt; element) within the &lt;ul&gt;. This is not
+     * cached, so it will be recomputed for each breadcrumb.
+     */
 	@Parameter(cache = false)
-	private String rowClass;
+	private String crumbClass;
 
+	
+    /**
+     * Optional output parameter (only set during rendering) that identifies the current breadcrumb index. This is the index on
+     * the page (i.e., always numbered from zero).
+     */
 	@Parameter
-	private int rowIndex;
+	private int index;
 
+	
+    /**
+     * Object that provides access to the crumb and data models used to render the BreadCrumbTrail.
+     */
 	@Parameter(value = "componentResources.container")
 	private BreadCrumbsModel breadCrumbsModel;
 
+	
+    /**
+     * The current crumb being rendered, this is primarily an output parameter used to allow the BreadCrumbTrail, and the BreadCrumbTrail's
+     * container, to know what object is being rendered.
+     */
 	@Parameter(required = true)
 	@Property(write = false)
-	private BreadCrumbObject row;
+	private BreadCrumbElement value;
 
 	@Inject
 	private ComponentSource componentSource;
 
-	@Component(parameters = "crumb=row", publishParameters = "before,after,title")
+	@Component(parameters = "value=value", publishParameters = "before,after,inside")
 	private BreadCrumbInfo breadCrumb;
 
-	private int dataRowIndex;
-
-	private int endRow;
+	private int endCrumb;
 
-	private int startRow;
 
-	public String getRowClass() {
+	public String getCrumbClass() {
 		List<String> classes = CollectionFactory.newList();
 
-		String rc = rowClass;
+		String rc = crumbClass;
 
 		if (rc != null)
 			classes.add(rc);
 
-		if (dataRowIndex == startRow)
-			classes.add(BreadCrumbsTrailConstantsValues.BREADCRUMBS_FIRST_CLASS);
+		if (index == 0)
+			classes.add(BREADCRUMBS_FIRST_CLASS);
 
-		if (dataRowIndex == endRow)
-			classes.add(BreadCrumbsTrailConstantsValues.BREADCRUMBS_LAST_CLASS);
+		if (index == endCrumb)
+			classes.add(BREADCRUMBS_LAST_CLASS);
 
-		if (componentSource.getActivePage().getComponentResources().getCompleteId().equals(componentSource.getPage(row.getLogicalPageName()).getComponentResources().getCompleteId())) {
-			classes.add(BreadCrumbsTrailConstantsValues.BREADCRUMBS_ACTIVE_CLASS);
+		if (componentSource.getActivePage().getComponentResources().getCompleteId().equals(componentSource.getPage(value.getLogicalPageName()).getComponentResources().getCompleteId())) {
+			classes.add(BREADCRUMBS_ACTIVE_CLASS);
 		}
 
 		return TapestryInternalUtils.toClassAttributeValue(classes);
 	}
 
-	void setupForRow(int rowIndex) {
-		row = breadCrumbsModel.getRow(rowIndex);
+	void setupForCrumb(int index) {
+		value = breadCrumbsModel.getCrumb(index);
 	}
 
 	boolean setupRender() {
 		int size = breadCrumbsModel.getSize();
-		startRow = 0;
-		endRow = size - 1;
-
-		dataRowIndex = startRow;
+		endCrumb = size - 1;
+		index = 0;
 
 		return size != 0;
 	}
 
 	boolean beginRender() {
-		// Setup for this row.
-
-		setupForRow(dataRowIndex);
+		// Setup for this crumb.
 
-		// Update the index parameter (which starts from zero).
-		rowIndex = dataRowIndex - startRow;
+		setupForCrumb(index);
 
-		return row != null;
+		return value != null;
 	}
 
 	boolean afterRender() {
-		dataRowIndex++;
+		index++;
 
-		// Abort the loop when we hit a null row, or when we've exhausted the
+		// Abort the loop when we hit a null crumb, or when we've exhausted the
 		// range we need to
 		// display.
 
-		return row == null || dataRowIndex > endRow;
+		return value == null || index > endCrumb;
 	}
 
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/components/BreadCrumbsTrail.java

 import java.util.List;
 
 import org.apache.tapestry5.BindingConstants;
-import org.apache.tapestry5.Block;
 import org.apache.tapestry5.annotations.Component;
 import org.apache.tapestry5.annotations.Parameter;
 import org.apache.tapestry5.annotations.Property;
 import org.apache.tapestry5.annotations.SessionState;
 import org.apache.tapestry5.annotations.SupportsInformalParameters;
 import org.apache.tapestry5.corelib.components.Any;
-import org.apache.tapestry5.services.PageRenderRequestParameters;
 
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
 import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants;
 import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsModel;
 import com.zenios.tapestry.breadcrumbs.session.BreadCrumbsList;
 
+/**
+ * A BreadCrumbsTrail presents breadcrumbs data. It is a composite component, created in terms of several sub-components. The
+ * sub-components are statically wired to the BreadCrumbsTrail, as it provides access to the data and other models that they need.
+ *
+ * @tapestrydoc
+ * @see BreadCrumbsModel
+ */
 @SuppressWarnings("unused")
 @SupportsInformalParameters
 public class BreadCrumbsTrail implements BreadCrumbsModel
 	@SessionState
 	private BreadCrumbsList breadCrumbs;
 
+    /**
+     * CSS class for the &lt;ul&gt; element. In addition, informal parameters to the Grid are rendered in the &lt;ul&gt;
+     * element.
+     */
 	@Parameter(name = "class", defaultPrefix = BindingConstants.LITERAL, value = BindingConstants.SYMBOL + ":" + BreadCrumbsConstants.BREADCRUMBS_TRAIL_CSS_CLASS)
 	@Property(write = false)
 	private String trailClass;
 	@Property
 	private Any trail;
 
-	@Component(parameters = "row=row", publishParameters = "rowIndex,rowClass,before,after,title")
+	@Component(parameters = "value=value", publishParameters = "index,crumbClass,before,after,inside")
 	@Property
 	private BreadCrumbsLoop trailCrumbs;
 
+    /**
+     * Used to store the current object being rendered (for the current breadcrumb). This is used when parameter blocks are
+     * provided to override the default rendering of a breadcrumb. the components within the block can
+     * use the property bound to the crumb parameter to know what they should render.
+     */
 	@Parameter(principal = true)
-	private BreadCrumbObject row;
+	@Property
+	private BreadCrumbElement value;
+
 
+    /**
+     * A wrapper around the provided List<BreadCrumbElement> that caches access to the availableCrumbs property.
+     */
 	private CachingBreadCrumbSource cachingSource;
 
 	boolean setupRender() {
 		cachingSource = new CachingBreadCrumbSource(breadCrumbs.getBreadCrumbs());
 
-		return cachingSource.getAvailableRows() == 0 ? false : true;
+		return cachingSource.getAvailableCrumbs() == 0 ? false : true;
 	}
 
 	static class CachingBreadCrumbSource
 	{
-		private final List<BreadCrumbObject> delegate;
+		private final List<BreadCrumbElement> delegate;
 
-		private boolean availableRowsCached;
+		private boolean availableCrumbsCached;
 
-		private int availableRows;
+		private int availableCrumbs;
 
-		CachingBreadCrumbSource(List<BreadCrumbObject> delegate) {
+		CachingBreadCrumbSource(List<BreadCrumbElement> delegate) {
 			this.delegate = delegate;
 		}
 
-		public int getAvailableRows() {
-			if (!availableRowsCached) {
-				availableRows = delegate.size();
-				availableRowsCached = true;
+		public int getAvailableCrumbs() {
+			if (!availableCrumbsCached) {
+				availableCrumbs = delegate.size();
+				availableCrumbsCached = true;
 			}
 
-			return availableRows;
+			return availableCrumbs;
 		}
 
-		public BreadCrumbObject getRowValue(int index) {
+		public BreadCrumbElement getCrumbValue(int index) {
 			return delegate.get(index);
 		}
 	}
 
 	public int getSize() {
-		return cachingSource.getAvailableRows();
-	}
-
-	public BreadCrumbObject getRow(int rowIndex) {
-		return cachingSource.getRowValue(rowIndex);
+		return cachingSource.getAvailableCrumbs();
 	}
 
-	public BreadCrumbObject getRow() {
-		return row;
+	public BreadCrumbElement getCrumb(int crumbIndex) {
+		return cachingSource.getCrumbValue(crumbIndex);
 	}
-
-	public void setRow(BreadCrumbObject row) {
-		this.row = row;
-	}
-
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/filter/BreadcrumbsPageRenderRequestFilter.java

-package com.zenios.tapestry.breadcrumbs.filter;
-
-import java.io.IOException;
-
-import org.apache.tapestry5.services.PageRenderRequestFilter;
-import org.apache.tapestry5.services.PageRenderRequestHandler;
-import org.apache.tapestry5.services.PageRenderRequestParameters;
-
-import com.zenios.tapestry.breadcrumbs.services.BreadCrumbsService;
-
-public class BreadcrumbsPageRenderRequestFilter implements PageRenderRequestFilter
-{
-	private final BreadCrumbsService breadCrumbsService;
-
-	public BreadcrumbsPageRenderRequestFilter(BreadCrumbsService breadCrumbsService) {
-		this.breadCrumbsService = breadCrumbsService;
-	}
-
-	public void handle(PageRenderRequestParameters arg0, PageRenderRequestHandler arg1) throws IOException {
-		breadCrumbsService.addToBreadCrumbs(arg0);
-		arg1.handle(arg0);
-	}
-
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/internal/services/BreadCrumbsService.java

+package com.zenios.tapestry.breadcrumbs.internal.services;
+
+import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
+
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbRule;
+
+
+/**
+ * General interface for work with BreadCrumbs.Used for adding breadcrumbs to the list
+ */
+@UsesConfiguration(BreadCrumbRule.class)
+public interface BreadCrumbsService
+{
+	/**
+	 * Examines the parameters to find which page is being rendered and add it to the breadcrumbs list
+	 * <p/>
+	 * It then checks if there are contributions {@link BreadCrumbRule} or {@link com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb} annotation 
+	 * attached on that page. In the end it adds the page along with the context to the
+	 * breadcrumbs list.
+	 * 
+	 * @param params PageRenderRequestParameters parameters passed through from PageRenderFilter
+	 */
+	public void addToBreadCrumbs(PageRenderRequestParameters params);
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/internal/services/impl/BreadCrumbsServiceImpl.java

+package com.zenios.tapestry.breadcrumbs.internal.services.impl;
+
+import java.lang.annotation.Annotation;
+import java.util.Collection;
+import java.util.Iterator;
+
+import org.apache.tapestry5.runtime.Component;
+import org.apache.tapestry5.services.ApplicationStateManager;
+import org.apache.tapestry5.services.ComponentSource;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
+
+import com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb;
+import com.zenios.tapestry.breadcrumbs.internal.services.BreadCrumbsService;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbAttribute;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbRule;
+import com.zenios.tapestry.breadcrumbs.session.BreadCrumbsList;
+import com.zenios.tapestry.breadcrumbs.session.impl.BreadCrumbsListImpl;
+import com.zenios.tapestry.breadcrumbs.utils.AntPathMatcher;
+
+
+/**
+ * 
+ * Implementation class for {@link BreadCrumbsService}
+ *
+ */
+public class BreadCrumbsServiceImpl implements BreadCrumbsService
+{
+
+	private final ApplicationStateManager applicationStateManager;
+	private final AntPathMatcher patternMatcher;
+	private final Collection<BreadCrumbRule> pathRules;
+	private final ComponentSource componentSource;
+	
+	/**
+	 * Default constructor for that service.All the parameters are injected through 
+	 * tapestry-ioc.
+	 * 
+	 * @param applicationStateManager 
+	 * @param pathRules
+	 * @param componentSource
+	 */
+
+	public BreadCrumbsServiceImpl(ApplicationStateManager applicationStateManager, Collection<BreadCrumbRule> pathRules, ComponentSource componentSource) {
+		this.applicationStateManager = applicationStateManager;
+		this.patternMatcher = createPathMatcher();
+		this.pathRules = pathRules;
+		this.componentSource = componentSource;
+	}
+
+	public void addToBreadCrumbs(PageRenderRequestParameters params) {
+
+		if (params.isLoopback()) {
+			throw new RuntimeException("IS loopback");
+		}
+		BreadCrumbsListImpl breadCrumbsList = (BreadCrumbsListImpl) applicationStateManager.get(BreadCrumbsList.class);
+		String pageName = params.getLogicalPageName();
+		boolean ignorePage = false;
+		boolean resetCrumbs = false;
+		Iterator<BreadCrumbRule> iter = pathRules.iterator();
+		while (iter.hasNext()) {
+			BreadCrumbRule filter = iter.next();
+			if (patternMatcher.matches(filter.getPattern(), pageName)) {
+				BreadCrumbAttribute attribute = filter.getAttribute();
+				if (attribute == BreadCrumbAttribute.IGNORE) {
+					ignorePage = true;
+				}
+
+				if (attribute == BreadCrumbAttribute.RESET) {
+					resetCrumbs = true;
+				}
+			}
+		}
+		Component page = componentSource.getPage(pageName);
+		BreadCrumb breadCrumb = findAnnotation(page.getClass(), BreadCrumb.class);
+		if (breadCrumb != null) {
+			if (breadCrumb.ignore()) {
+				ignorePage = true;
+			}
+
+			if (breadCrumb.reset()) {
+				resetCrumbs = true;
+			}
+		}
+
+		if (resetCrumbs) {
+			breadCrumbsList.clear();
+		}
+
+		if (ignorePage) {
+			return;
+		}
+		breadCrumbsList.add(new BreadCrumbElement(pageName, params.getActivationContext()));
+	}
+
+	private AntPathMatcher createPathMatcher() {
+		return new AntPathMatcher()
+		{
+			public boolean matches(String pattern, String source) {
+				return super.matches(pattern, source.toLowerCase());
+			}
+		};
+	}
+	
+	/*
+	 * Loop through the class and superclass and search for a specific annotation
+	 */
+	private <T extends Annotation> T findAnnotation(final Class<?> clazz, final Class<T> annotation) {
+
+		Class<?> current = clazz;
+		while (current != Object.class) {
+			T result = clazz.getAnnotation(annotation);
+			if(result != null) {
+				return result;
+			}
+			current = current.getSuperclass();
+		}
+		return null;
+	}
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbAttribute.java

+package com.zenios.tapestry.breadcrumbs.other;
+
+/**
+ *	Breadcrumb attributes when breadcrumbs are configured using contribution
+ *	and not annotations.Semantics are the same with the annotation.
+ *
+ *	@see com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb
+ */
+public enum BreadCrumbAttribute
+{
+	/**
+	 * @see  com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb#ignore()
+	 */
+	IGNORE,
+	
+	/**
+	 * @see  com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb#reset()
+	 */
+	RESET
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbElement.java

+package com.zenios.tapestry.breadcrumbs.other;
+
+import java.io.Serializable;
+
+import org.apache.tapestry5.EventContext;
+import org.apache.tapestry5.internal.TapestryInternalUtils;
+
+
+/**
+ * Object that holds information for one specific breadcrumb
+ */
+public class BreadCrumbElement implements Serializable
+{
+	private static final long serialVersionUID = -6160551440249774901L;
+	private final String logicalPageName;
+	private final EventContext activationContext;
+
+    /**
+     * Constructs a new {@link BreadCrumbElement}.
+     * 
+     * @param logicalPageName The name of the page      
+     * @param activationContext The activation context 
+     */
+	public BreadCrumbElement(String logicalPageName, EventContext activationContext) {
+		this.logicalPageName = logicalPageName;
+		this.activationContext = activationContext;
+	}
+	
+	/**
+	 * @return Logical name of the page
+	 * 
+	 * @see org.apache.tapestry5.services.PageRenderRequestParameters#getLogicalPageName()
+	 */
+
+	public String getLogicalPageName() {
+		return logicalPageName;
+	}
+
+	
+	/**
+	 * @return {@link org.apache.tapestry5.EventContext} of the page
+	 * 
+	 * @see org.apache.tapestry5.services.PageRenderRequestParameters#getActivationContext()
+	 */
+	public EventContext getActivationContext() {
+		return activationContext;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((activationContext == null) ? 0 : activationContext.hashCode());
+		result = prime * result + ((logicalPageName == null) ? 0 : logicalPageName.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+
+		if (obj == null || getClass() != obj.getClass())
+			return false;
+
+		BreadCrumbElement other = (BreadCrumbElement) obj;
+		return TapestryInternalUtils.isEqual(activationContext, other.getActivationContext()) && other.getLogicalPageName().equals(this.logicalPageName);
+	}
+
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbObject.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-import org.apache.tapestry5.EventContext;
-import org.apache.tapestry5.internal.TapestryInternalUtils;
-
-public class BreadCrumbObject
-{
-	private final String logicalPageName;
-	private final EventContext activationContext;
-	private final boolean titleEvent;
-
-	public BreadCrumbObject(String logicalPageName, EventContext activationContext, boolean titleEvent) {
-		this.logicalPageName = logicalPageName;
-		this.activationContext = activationContext;
-		this.titleEvent = titleEvent;
-	}
-
-	public String getLogicalPageName() {
-		return logicalPageName;
-	}
-
-	public EventContext getActivationContext() {
-		return activationContext;
-	}
-
-	public boolean isTitleEvent() {
-		return titleEvent;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((activationContext == null) ? 0 : activationContext.hashCode());
-		result = prime * result + ((logicalPageName == null) ? 0 : logicalPageName.hashCode());
-		result = prime * result + (titleEvent ? 1231 : 1237);
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-
-		if (obj == null || getClass() != obj.getClass())
-			return false;
-
-		BreadCrumbObject other = (BreadCrumbObject) obj;
-		return TapestryInternalUtils.isEqual(activationContext, other.getActivationContext()) && other.getLogicalPageName().equals(this.logicalPageName) && other.isTitleEvent() == this.titleEvent;
-	}
-
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbRule.java

+package com.zenios.tapestry.breadcrumbs.other;
+
+import com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb;
+import com.zenios.tapestry.breadcrumbs.utils.AntPathMatcher;
+
+
+/**
+ * Object that holds rule information for a specific breadcrumb when configuring through contribution .Alternative to 
+ * using {@link BreadCrumb}
+ */
+public class BreadCrumbRule
+{
+	private final String pattern;
+	private final BreadCrumbAttribute attribute;
+
+	
+    /**
+     * Constructs a new {@link BreadCrumbRule}.
+     * 
+     * @param pattern Path pattern for page rule matching.Mathing will be done using {@link AntPathMatcher}   
+     * @param attribute The attribute for this rule
+     */
+	public BreadCrumbRule(String pattern, BreadCrumbAttribute attribute) {
+		this.pattern = pattern;
+		this.attribute = attribute;
+	}
+
+	
+	/**
+	 * 
+	 * @return Path pattern
+	 */
+	public String getPattern() {
+		return pattern;
+	}
+
+	
+	/**
+	 * 
+	 * @return The attribute for this rule
+	 */
+	public BreadCrumbAttribute getAttribute() {
+		return attribute;
+	}
+
+	@Override
+	public int hashCode() {
+		final int prime = 31;
+		int result = 1;
+		result = prime * result + ((attribute == null) ? 0 : attribute.hashCode());
+		result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
+		return result;
+	}
+
+	@Override
+	public boolean equals(Object obj) {
+		if (this == obj)
+			return true;
+		if (obj == null)
+			return false;
+		if (getClass() != obj.getClass())
+			return false;
+		BreadCrumbRule other = (BreadCrumbRule) obj;
+		if (attribute != other.attribute)
+			return false;
+		if (pattern == null) {
+			if (other.pattern != null)
+				return false;
+		} else if (!pattern.equals(other.pattern))
+			return false;
+		return true;
+	}
+
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsConstants.java

 package com.zenios.tapestry.breadcrumbs.other;
 
+
+/**
+ * Defines the names of symbols used to configure BreadCrumbs module.
+ */
 public class BreadCrumbsConstants
 {
-	public static final String BREADCRUMBS_FILTER = "zbreadcrumbs";
+	/**
+	 * Number of breadcrumbs to save.If exceeded the list will wrap around.
+	 * The default value is: 10.
+	 */
 	public static final String BREADCRUMBS_MAX_CRUMBS_TO_SAVE = "zbreadcrumbs-to-save";
+	
+	/**
+	 * Whether or not to discard duplicate breadcrumbs
+	 * The default value is: true.
+	 */
 	public static final String BREADCRUMBS_DISCARD_DUPLICATES = "zbreadcrumbs-discrd-duplicates";
+	
+	/**
+	 * Default class name that is added to the breadCrumbTrailComponent
+	 * The default value is: t-zbreadcrumbs.
+	 * 
+	 * @see  com.zenios.tapestry.breadcrumbs.components.BreadCrumbsTrail
+	 */
 	public static final String BREADCRUMBS_TRAIL_CSS_CLASS = "zbreadcrumbs-css_class";
+	
+	/**
+	 * Default suffix that will be appended to the logical page name when using
+	 * message catalogue to get the title of the breadcrumb
+	 * The default value is: -crumb.
+	 */
 	public static final String BREADCRUMBS_TITLE_SUFFIX = "zbreadcrumbs-title-suffix";
+	
+    /**
+     * The default breadcrumbs stylesheet automatically injected into every rendered HTML page.
+     */
 	public static final String BREADCRUMBS_DEFAULT_STYLESHEET = "zbreadcrumbs-default-stylesheet";
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsConstantsValues.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-public class BreadCrumbsConstantsValues
-{
-	public static final String BREADCRUMBS_MAX_CRUMBS_TO_SAVE_VALUE = "10";
-	public static final String BREADCRUMB_TRAIL_CSS_CLASS_VALUE = "t-zbreadcrumbs";
-	public static final String BREADCRUMBS_DISCARD_DUPLICATES_VALUE = "true";
-	public static final String BREADCRUMBS_TITLE_SUFFIX_VALUE = "-crumb";
-	public static final String BREADCRUMBS_DEFAULT_STYLESHEET_VALUE = "classpath:/com/zenios/tapestry/breadcrumbs/Assets/default.css";
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsEventConstants.java

+package com.zenios.tapestry.breadcrumbs.other;
+
+
+/**
+ * Constant values for common event names fired by BreadCrumbs components.
+ */
+public class BreadCrumbsEventConstants
+{
+	
+    /**
+     * Event triggered when extracting breadcrumb title from page.The component event handler will be
+     * passed the activationContext
+     */
+	public static final String GET_TITLE = "zbreadcrumbs-get-title";
+}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsEvents.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-public class BreadCrumbsEvents
-{
-	public static final String GET_TITLE = "zbreadcrumbs-get-title";
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsFilter.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-public class BreadCrumbsFilter
-{
-	private final String pattern;
-	private final BreadCrumbsFilterType filterType;
-
-	public BreadCrumbsFilter(String pattern, BreadCrumbsFilterType filterType) {
-		this.pattern = pattern;
-		this.filterType = filterType;
-	}
-
-	public String getPattern() {
-		return pattern;
-	}
-
-	public BreadCrumbsFilterType getFilterType() {
-		return filterType;
-	}
-
-	@Override
-	public int hashCode() {
-		final int prime = 31;
-		int result = 1;
-		result = prime * result + ((filterType == null) ? 0 : filterType.hashCode());
-		result = prime * result + ((pattern == null) ? 0 : pattern.hashCode());
-		return result;
-	}
-
-	@Override
-	public boolean equals(Object obj) {
-		if (this == obj)
-			return true;
-		if (obj == null)
-			return false;
-		if (getClass() != obj.getClass())
-			return false;
-		BreadCrumbsFilter other = (BreadCrumbsFilter) obj;
-		if (filterType != other.filterType)
-			return false;
-		if (pattern == null) {
-			if (other.pattern != null)
-				return false;
-		} else if (!pattern.equals(other.pattern))
-			return false;
-		return true;
-	}
-
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsFilterType.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-public enum BreadCrumbsFilterType
-{
-	RESET, IGNORE, DYNAMIC_TITLE
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsModel.java

 package com.zenios.tapestry.breadcrumbs.other;
 
+
+/**
+ * A provider of model data to the sub-components of the {@link com.zenios.tapestry.breadcrumbs.components.BreadCrumbsTrail} component.
+ * The primary implementor of this component is the BreadCrumbsTrail component itself. This is effectively a way to package two
+ * values as a single parameter to components such as {@link com.zenios.tapestry.breadcrumbs.components.BreadCrumbsLoop}
+ */
 public interface BreadCrumbsModel
 {
+	/**
+	 * @return The number of breadcrumbs available
+	 */
 	int getSize();
 
-	BreadCrumbObject getRow(int rowIndex);
+	
+	/**
+	 * @return {@link BreadCrumbElement} which has the specified index
+	 */
+	BreadCrumbElement getCrumb(int crumbIndex);
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/other/BreadCrumbsTrailConstantsValues.java

-package com.zenios.tapestry.breadcrumbs.other;
-
-public class BreadCrumbsTrailConstantsValues
-{
-	public static final String BREADCRUMBS_FIRST_CLASS = "z-first";
-	public static final String BREADCRUMBS_LAST_CLASS = "z-last";
-	public static final String BREADCRUMBS_ACTIVE_CLASS = "z-active";
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/services/BreadCrumbsModule.java

 package com.zenios.tapestry.breadcrumbs.services;
 
+import java.io.IOException;
+
 import org.apache.tapestry5.Asset;
 import org.apache.tapestry5.MarkupWriter;
 import org.apache.tapestry5.annotations.Path;
 import org.apache.tapestry5.services.MarkupRenderer;
 import org.apache.tapestry5.services.MarkupRendererFilter;
 import org.apache.tapestry5.services.PageRenderRequestFilter;
+import org.apache.tapestry5.services.PageRenderRequestHandler;
+import org.apache.tapestry5.services.PageRenderRequestParameters;
 import org.apache.tapestry5.services.javascript.StylesheetLink;
 
-import com.zenios.tapestry.breadcrumbs.filter.BreadcrumbsPageRenderRequestFilter;
+import com.zenios.tapestry.breadcrumbs.internal.services.BreadCrumbsService;
+import com.zenios.tapestry.breadcrumbs.internal.services.impl.BreadCrumbsServiceImpl;
 import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstantsValues;
-import com.zenios.tapestry.breadcrumbs.services.impl.BreadCrumbsServiceImpl;
 import com.zenios.tapestry.breadcrumbs.session.BreadCrumbsList;
 import com.zenios.tapestry.breadcrumbs.session.impl.BreadCrumbsListImpl;
 
 	}
 
 	public static void contributeFactoryDefaults(final MappedConfiguration<String, String> configuration) {
-		configuration.add(BreadCrumbsConstants.BREADCRUMBS_MAX_CRUMBS_TO_SAVE, BreadCrumbsConstantsValues.BREADCRUMBS_MAX_CRUMBS_TO_SAVE_VALUE);
-		configuration.add(BreadCrumbsConstants.BREADCRUMBS_DISCARD_DUPLICATES, BreadCrumbsConstantsValues.BREADCRUMBS_DISCARD_DUPLICATES_VALUE);
-		configuration.add(BreadCrumbsConstants.BREADCRUMBS_TRAIL_CSS_CLASS, BreadCrumbsConstantsValues.BREADCRUMB_TRAIL_CSS_CLASS_VALUE);
-		configuration.add(BreadCrumbsConstants.BREADCRUMBS_TITLE_SUFFIX, BreadCrumbsConstantsValues.BREADCRUMBS_TITLE_SUFFIX_VALUE);
-		configuration.add(BreadCrumbsConstants.BREADCRUMBS_DEFAULT_STYLESHEET, BreadCrumbsConstantsValues.BREADCRUMBS_DEFAULT_STYLESHEET_VALUE);
+		configuration.add(BreadCrumbsConstants.BREADCRUMBS_MAX_CRUMBS_TO_SAVE, "10");
+		configuration.add(BreadCrumbsConstants.BREADCRUMBS_DISCARD_DUPLICATES, "true");
+		configuration.add(BreadCrumbsConstants.BREADCRUMBS_TRAIL_CSS_CLASS, "t-zbreadcrumbs");
+		configuration.add(BreadCrumbsConstants.BREADCRUMBS_TITLE_SUFFIX, "-crumb");
+		configuration.add(BreadCrumbsConstants.BREADCRUMBS_DEFAULT_STYLESHEET, "classpath:/com/zenios/tapestry/breadcrumbs/Assets/default.css");
 	}
 
-	public static void contributePageRenderRequestHandler(OrderedConfiguration<PageRenderRequestFilter> configuration) {
-		configuration.addInstance(BreadCrumbsConstants.BREADCRUMBS_FILTER, BreadcrumbsPageRenderRequestFilter.class);
+	public static void contributePageRenderRequestHandler(OrderedConfiguration<PageRenderRequestFilter> configuration,final BreadCrumbsService breadCrumbsService) {
+		PageRenderRequestFilter breadCrumbsFilter = new PageRenderRequestFilter()
+        {
+            public void handle(PageRenderRequestParameters parameters, PageRenderRequestHandler handler)
+                    throws IOException
+            {
+
+				breadCrumbsService.addToBreadCrumbs(parameters);
+
+                handler.handle(parameters);
+            }
+        };
+		configuration.add("zbreadcrumbs", breadCrumbsFilter);
 	}
 
 	public void contributeMarkupRenderer(OrderedConfiguration<MarkupRendererFilter> configuration, final Environment environment, @Path("${zbreadcrumbs-default-stylesheet}") final Asset defaultStylesheet) {

File src/main/java/com/zenios/tapestry/breadcrumbs/services/BreadCrumbsService.java

-package com.zenios.tapestry.breadcrumbs.services;
-
-import org.apache.tapestry5.ioc.annotations.UsesConfiguration;
-import org.apache.tapestry5.services.PageRenderRequestParameters;
-
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsFilter;
-
-@UsesConfiguration(BreadCrumbsFilter.class)
-public interface BreadCrumbsService
-{
-	public void addToBreadCrumbs(PageRenderRequestParameters params);
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/services/impl/BreadCrumbsServiceImpl.java

-package com.zenios.tapestry.breadcrumbs.services.impl;
-
-import java.lang.annotation.Annotation;
-import java.util.Collection;
-import java.util.Iterator;
-
-import org.apache.tapestry5.runtime.Component;
-import org.apache.tapestry5.services.ApplicationStateManager;
-import org.apache.tapestry5.services.ComponentSource;
-import org.apache.tapestry5.services.PageRenderRequestParameters;
-
-import com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsFilter;
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbsFilterType;
-import com.zenios.tapestry.breadcrumbs.services.BreadCrumbsService;
-import com.zenios.tapestry.breadcrumbs.session.BreadCrumbsList;
-import com.zenios.tapestry.breadcrumbs.session.impl.BreadCrumbsListImpl;
-import com.zenios.tapestry.breadcrumbs.utils.AntPathMatcher;
-import com.zenios.tapestry.breadcrumbs.utils.PatternMatcher;
-
-public class BreadCrumbsServiceImpl implements BreadCrumbsService
-{
-
-	private final ApplicationStateManager applicationStateManager;
-	private final PatternMatcher patternMatcher;
-	private final Collection<BreadCrumbsFilter> pathFilters;
-	private final ComponentSource componentSource;
-
-	public BreadCrumbsServiceImpl(ApplicationStateManager applicationStateManager, Collection<BreadCrumbsFilter> pathFilters, ComponentSource componentSource) {
-		this.applicationStateManager = applicationStateManager;
-		this.patternMatcher = createPathMatcher();
-		this.pathFilters = pathFilters;
-		this.componentSource = componentSource;
-	}
-
-	public void addToBreadCrumbs(PageRenderRequestParameters params) {
-
-		if (params.isLoopback()) {
-			throw new RuntimeException("IS loopback");
-		}
-		BreadCrumbsListImpl breadCrumbsList = (BreadCrumbsListImpl) applicationStateManager.get(BreadCrumbsList.class);
-		String pageName = params.getLogicalPageName();
-		boolean ignorePage = false;
-		boolean resetCrumbs = false;
-		boolean dynamicTitle = false;
-		Iterator<BreadCrumbsFilter> iter = pathFilters.iterator();
-		while (iter.hasNext()) {
-			BreadCrumbsFilter filter = iter.next();
-			if (patternMatcher.matches(filter.getPattern(), pageName)) {
-				BreadCrumbsFilterType type = filter.getFilterType();
-				if (type == BreadCrumbsFilterType.IGNORE) {
-					ignorePage = true;
-				}
-
-				if (type == BreadCrumbsFilterType.RESET) {
-					resetCrumbs = true;
-				}
-
-				if (type == BreadCrumbsFilterType.DYNAMIC_TITLE) {
-					dynamicTitle = true;
-				}
-			}
-		}
-		Component page = componentSource.getPage(pageName);
-		BreadCrumb breadCrumb = findAnnotation(page.getClass(), BreadCrumb.class);
-		if (breadCrumb != null) {
-			if (breadCrumb.ignore()) {
-				ignorePage = true;
-			}
-
-			if (breadCrumb.reset()) {
-				resetCrumbs = true;
-			}
-
-			if (breadCrumb.dynamicTitle()) {
-				dynamicTitle = true;
-			}
-		}
-
-		if (resetCrumbs) {
-			breadCrumbsList.clear();
-		}
-
-		if (ignorePage) {
-			return;
-		}
-		breadCrumbsList.add(new BreadCrumbObject(pageName, params.getActivationContext(), dynamicTitle));
-	}
-
-	private PatternMatcher createPathMatcher() {
-		return new AntPathMatcher()
-		{
-			public boolean matches(String pattern, String source) {
-				return super.matches(pattern, source.toLowerCase());
-			}
-		};
-	}
-
-	private <T extends Annotation> T findAnnotation(final Class<?> clazz, final Class<T> annotation) {
-		T result = clazz.getAnnotation(annotation);
-
-		if (result == null && clazz.getSuperclass() != null) {
-			result = this.findAnnotation(clazz.getSuperclass(), annotation);
-		}
-
-		return result;
-	}
-}

File src/main/java/com/zenios/tapestry/breadcrumbs/session/BreadCrumbsList.java

 import java.io.Serializable;
 import java.util.List;
 
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
 
+/**
+ *	General interface responsible for saving breadcrumbs list on session.
+ */
 public interface BreadCrumbsList extends Serializable
 {
-	public List<BreadCrumbObject> getBreadCrumbs();
+	
+	/**
+	 * 
+	 * @return Copy of the list containing all the breadcrumbs currently saved. 
+	 */
+	public List<BreadCrumbElement> getBreadCrumbs();
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/session/impl/BreadCrumbsListImpl.java

 import java.util.ArrayList;
 import java.util.List;
 
-import com.zenios.tapestry.breadcrumbs.other.BreadCrumbObject;
+import com.zenios.tapestry.breadcrumbs.other.BreadCrumbElement;
 import com.zenios.tapestry.breadcrumbs.session.BreadCrumbsList;
 
+/**
+ * Implementation class for {@link BreadCrumbsList}
+ * <p/>
+ * All operations on the breadcrumbs list are protected with a mutex in order
+ * to avoid concurrent modifications.
+ */
 public class BreadCrumbsListImpl implements BreadCrumbsList
 {
 	private static final long serialVersionUID = -8457209111821626779L;
-	private final List<BreadCrumbObject> items;
+	private final ArrayList<BreadCrumbElement> items;
 	private final Object mutex;
 	private final int size;
 	private final boolean discardDuplicates;
 
+	/**
+	 * Default constructor for that service.All the parameters are injected through 
+	 * tapestry-ioc.
+	 * 
+	 * @param size Maximum breadcrumbs to save on the list
+	 * @param discardDuplicates Whether to discard duplicated breadcrumbs
+	 * 
+	 * @see com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants#BREADCRUMBS_MAX_CRUMBS_TO_SAVE
+	 * @see com.zenios.tapestry.breadcrumbs.other.BreadCrumbsConstants#BREADCRUMBS_DISCARD_DUPLICATES
+	 */
+
 	public BreadCrumbsListImpl(int size, boolean discardDuplicates) {
-		this.items = new ArrayList<BreadCrumbObject>(size);
+		this.items = new ArrayList<BreadCrumbElement>(size);
 		this.mutex = new Object();
 		this.size = size;
 		this.discardDuplicates = discardDuplicates;
 	}
 
+	
+	/**
+	 * Clear the whole breadcrumbs list
+	 * <p/>
+	 * This function is invoked from {@link com.zenios.tapestry.breadcrumbs.internal.services.impl.BreadCrumbsServiceImpl}
+	 * when it finds a contribution that specifies {@link  com.zenios.tapestry.breadcrumbs.other.BreadCrumbAttribute#RESET} attribute or
+	 * a {@link com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb} that specifies {@link com.zenios.tapestry.breadcrumbs.annotation.BreadCrumb#reset()} 
+	 */
 	public void clear() {
 		synchronized (mutex) {
 			items.clear();
 		}
 	}
-
-	public void add(BreadCrumbObject breadCrumb) {
+	
+	/**
+	 * Function responsible for adding the specified breadCrumb on the list
+	 * <p/>
+	 * If the breadcrumb is already the last element of the list then its ignored.This is 
+	 * useful in order to avoid post after redirect patters.
+	 * <p/>
+	 * If discardDuplicates is true it also clears the list starting from the last breadcrumb
+	 * which is the same as the passed parameter
+	 * 
+	 * @param breadCrumb BreadCrumb to add to the list
+	 * 
+	 */
+	public void add(BreadCrumbElement breadCrumb) {
 		synchronized (mutex) {
 			final int index = items.lastIndexOf(breadCrumb);
 			/*
 				return;
 			}
 			if (discardDuplicates) {
-				;
 				if (index != -1) {
 					items.subList(index + 1, items.size()).clear();
 					return;
 		}
 	}
 
-	public List<BreadCrumbObject> getBreadCrumbs() {
+	public List<BreadCrumbElement> getBreadCrumbs() {
 		synchronized (mutex) {
-			return new ArrayList<BreadCrumbObject>(items);
+			return new ArrayList<BreadCrumbElement>(items);
 		}
 	}
 }

File src/main/java/com/zenios/tapestry/breadcrumbs/utils/AntPathMatcher.java

  * 
  * <p>
  * <b>N.B.</b>: This class was borrowed (with much appreciation) from the <a
- * href="http://www.springframework.org">Spring Framework</a> with
- * modifications. We didn't want to reinvent the wheel of great work they've
- * done, but also didn't want to force every Shiro user to depend on Spring
+ * href="http://shiro.apache.org">Apache shiro</a> with
+ * modifications.
  * </p>
  * 
  * <p>
  * As per the Apache 2.0 license, the original copyright notice and all author
  * and copyright information have remained in tact.
  * </p>
- * 
- * @borrowed: org.apache.shiro.util.AntPathMatcher
  */
-public class AntPathMatcher implements PatternMatcher
+public class AntPathMatcher
 {
 
-	// TODO - complete JavaDoc
-
 	/**
 	 * Default path separator: "/"
 	 */
-	public static final String DEFAULT_PATH_SEPARATOR = "/";
+	private static final String DEFAULT_PATH_SEPARATOR = "/";
 
 	private String pathSeparator = DEFAULT_PATH_SEPARATOR;
 

File src/main/java/com/zenios/tapestry/breadcrumbs/utils/PatternMatcher.java

-/*
- * Licensed to the Apache Software Foundation (ASF) under one
- * or more contributor license agreements.  See the NOTICE file
- * distributed with this work for additional information
- * regarding copyright ownership.  The ASF licenses this file
- * to you under the Apache License, Version 2.0 (the
- * "License"); you may not use this file except in compliance
- * with the License.  You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing,
- * software distributed under the License is distributed on an
- * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
- * KIND, either express or implied.  See the License for the
- * specific language governing permissions and limitations
- * under the License.
- */
-package com.zenios.tapestry.breadcrumbs.utils;
-
-/**
- * Interface for components that can match source strings against a specified
- * pattern string.
- * <p/>
- * Different implementations can support different pattern types, for example,
- * Ant style path expressions, or regular expressions, or other types of text
- * based patterns.
- * 
- * borrowed: org.apache.shiro.util.PatternMatche
- */
-public interface PatternMatcher
-{
-
-	/**
-	 * Returns <code>true</code> if the given <code>source</code> matches the
-	 * specified <code>pattern</code>, <code>false</code> otherwise.
-	 * 
-	 * @param pattern
-	 *            the pattern to match against
-	 * @param source
-	 *            the source to match
-	 * @return <code>true</code> if the given <code>source</code> matches the
-	 *         specified <code>pattern</code>, <code>false</code> otherwise.
-	 */
-	boolean matches(String pattern, String source);
-}

File src/main/resources/com/zenios/tapestry/breadcrumbs/components/BreadCrumbInfo.tml

 <t:container xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
     <t:block id="before" />
-	<t:delegate to="title"/>
+	<t:delegate to="inside"/>
 	<t:block id="after" />
 	
-	<t:block id="title">
+	<t:block id="inside">
     	<t:pageLink t:page="${page}" t:context="activationContext">
 			${nameTitle}
 		</t:pageLink>

File src/main/resources/com/zenios/tapestry/breadcrumbs/components/BreadCrumbsLoop.tml

-<li class="${rowClass}" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
+<li class="${crumbClass}" xmlns:t="http://tapestry.apache.org/schema/tapestry_5_3.xsd">
 	<div t:id="breadCrumb"/>
 </li>