class PropertyDispatcherFactory {

    public PropertyDispatcher createDispatcherChain(Object pmo,
            BoundProperty boundProperty,
            PropertyBehaviorProvider behaviorProvider) {
        requireNonNull(pmo, "pmo must not be null");
        requireNonNull(boundProperty, "boundProperty must not be null");
        requireNonNull(behaviorProvider, "behaviorProvider must not be null");

        // @formatter:off
        String modelPropertyName = boundProperty.getModelAttribute();
        String modelObjectName = boundProperty.getModelObject();
        String pmoPropertyName = boundProperty.getPmoProperty();
        ExceptionPropertyDispatcher exceptionDispatcher = newExceptionDispatcher(pmo, modelObjectName, pmoPropertyName);
        ReflectionPropertyDispatcher reflectionDispatcher = newReflectionDispatcher(pmo, pmoPropertyName, modelObjectName, modelPropertyName, exceptionDispatcher);
        StaticValueDispatcher bindingAnnotationDispatcher = new StaticValueDispatcher(reflectionDispatcher);
        PropertyDispatcher customDispatchers = createCustomDispatchers(pmo, boundProperty, bindingAnnotationDispatcher);
        return new BehaviorDependentDispatcher(customDispatchers, behaviorProvider);
        // @formatter:on
    }

}