class ReflectionPropertyDispatcher implements PropertyDispatcher {

    @Override
    public <V> boolean isPushable(Aspect<V> aspect) {
        @CheckForNull
        Object boundObject = getBoundObject();

        if (boundObject == null) {
            return fallbackDispatcher.isPushable(aspect);
        }

        String propertyAspectName = getPropertyAspectName(aspect);
        if (aspect.isValuePresent()) {
            // the FallbackDispatcher should only be called if the BoundObject has no read method.
            // Otherwise a #push() could result in a #write() to the ModelObject even if it is not
            // declared within the PMO
            return (hasReadMethod(propertyAspectName) && hasWriteMethod(propertyAspectName))
                    || (!hasReadMethod(propertyAspectName) && fallbackDispatcher.isPushable(aspect));
        } else {
            return hasInvokeMethod(propertyAspectName)
                    || fallbackDispatcher.isPushable(aspect);
        }
    }

    public  ReflectionPropertyDispatcher(Supplier<?> boundObjectSupplier, String property,
            PropertyDispatcher fallbackDispatcher);

}