Filters: new feature, initial implementation

Filters provides a capability to manipulate mapping behavior dynamically at runtime.

Filters may be registered on the MapperFactory, using the **_registerFilter(Filter<?,?> filter)_** method.

Filters should implement the **_Filter_** interface, as defined below. The recommended approach is to extend the **_CustomFilter_** class.

```
/**
 * Filter defines the contract for manipulating the runtime behavior of
 * generated mappers.
 * 
 * @author mattdeboer
 * 
 * @param <A>
 * @param <B>
 */
public interface Filter<A, B> extends MappedTypePair<A, B> {
    
    /**
     * This method will be called at build time to determine if this filter
     * should be applied to the mapping of the specified properties
     * 
     * @param source
     *            the source property
     * @param destination
     *            the destination property
     * @return true if this Filter applies
     */
    public boolean appliesTo(Property source, Property destination);
    
    /**
     * Called at code generation time to determine whether this filter modifies
     * the source.
     * <p>
     * Implementations should not implement dynamic behavior here, as this
     * method will most likely be called only once (at generation time) for a
     * given Filter instance.
     * 
     * @return true if this Filter should be called to filter the source value
     *         the mapping results
     */
    public boolean filtersSource();
    
    /**
     * Called at code generation time to determine whether this filter modifies
     * the destination.
     * <p>
     * Implementations should not implement dynamic behavior here, as this
     * method will most likely be called only once (at generation time) for a
     * given Filter instance.
     * 
     * @return true if this Filter should be called to filter the destination of
     *         the mapping results
     */
    public boolean filtersDestination();
    
    /**
     * This method is called at runtime to determine whether the mapping implied
     * by the field names and types should be performed; if <code>false</code>
     * is returned, the mapping is skipped.
     * 
     * @param sourceType
     *            the type of the source field
     * @param sourceName
     *            the name of the source field
     * @param destType
     *            the type of the destination field
     * @param destName
     *            the name of the destination field
     * @param mappingContext
     *            the current mapping context
     * @return true if the fields represented by these types and names
     */
    public boolean shouldMap(Type<?> sourceType, String sourceName, Type<?> destType, String destName, MappingContext mappingContext);
    
    /**
     * This method is called to provide the Filter an opportunity to modify the destination
     * field's value in some way before it is mapped onto the destination type. 
     * <p>
     * Note that the
     * return value should still be an instance of the provided destination type, else ClassCastException 
     * will likely occur. 
     * 
     * @param destinationValue
     *            the destination value
     * @param sourceType
     *            the type of the source field
     * @param sourceName
     *            the name of the source field
     * @param destType
     *            the type of the destination field
     * @param destName
     *            the name of the destination field
     * @param mappingContext
     *            the current mapping context
     * @return the filtered output value
     */
    public <D> D filterDestination(D destinationValue, Type<?> sourceType, String sourceName, Type<D> destType, String destName,
            MappingContext mappingContext);
    
    /**
     * This method is called to provide the Filter an opportunity to replace the source
     * field value before it is passed into the mapping code which transforms it to the 
     * destination type. 
     * <p>
     * It's recommended that the filter should return a new instance if it's necessary to 
     * modify the source, as a mapping request is not generally expected to have side 
     * effects on the source.
     * 
     * @param sourceValue
     *            the source value
     * @param sourceType
     *            the type of the source field
     * @param sourceName
     *            the name of the source field
     * @param destType
     *            the type of the destination field
     * @param destName
     *            the name of the destination field
     * @param mappingContext
     *            the current mapping context
     * @return the filtered output value
     */
    public <S> S filterSource(S sourceValue, Type<S> sourceType, String sourceName, Type<?> destType, String destName,
            MappingContext mappingContext);
    
}
```