You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@bval.apache.org by mb...@apache.org on 2018/02/25 19:38:24 UTC

[4/6] bval git commit: clean up no-longer-used code from JSR module

http://git-wip-us.apache.org/repos/asf/bval/blob/92c64b3c/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
deleted file mode 100644
index d7b4640..0000000
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ClassValidator.java
+++ /dev/null
@@ -1,1292 +0,0 @@
-/*
- * 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 org.apache.bval.jsr;
-
-import java.lang.reflect.Constructor;
-import java.lang.reflect.Member;
-import java.lang.reflect.Method;
-import java.lang.reflect.Modifier;
-import java.util.ArrayList;
-import java.util.Arrays;
-import java.util.Collection;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-import javax.validation.ConstraintDeclarationException;
-import javax.validation.ConstraintDefinitionException;
-import javax.validation.ConstraintTarget;
-import javax.validation.ConstraintViolation;
-import javax.validation.ElementKind;
-import javax.validation.ValidationException;
-import javax.validation.executable.ExecutableValidator;
-import javax.validation.groups.Default;
-import javax.validation.metadata.BeanDescriptor;
-import javax.validation.metadata.ConstraintDescriptor;
-import javax.validation.metadata.ElementDescriptor;
-import javax.validation.metadata.ParameterDescriptor;
-import javax.validation.metadata.PropertyDescriptor;
-
-import org.apache.bval.DynamicMetaBean;
-import org.apache.bval.MetaBeanFinder;
-import org.apache.bval.jsr.groups.Group;
-import org.apache.bval.jsr.groups.Groups;
-import org.apache.bval.jsr.groups.GroupsComputer;
-import org.apache.bval.jsr.util.ClassHelper;
-import org.apache.bval.jsr.util.NodeImpl;
-import org.apache.bval.jsr.util.PathImpl;
-import org.apache.bval.jsr.util.PathNavigation;
-import org.apache.bval.jsr.util.Proxies;
-import org.apache.bval.jsr.util.ValidationContextTraversal;
-import org.apache.bval.model.Features;
-import org.apache.bval.model.FeaturesCapable;
-import org.apache.bval.model.MetaBean;
-import org.apache.bval.model.MetaProperty;
-import org.apache.bval.model.Validation;
-import org.apache.bval.util.AccessStrategy;
-import org.apache.bval.util.ValidationHelper;
-import org.apache.bval.util.ObjectUtils;
-import org.apache.bval.util.reflection.Reflection;
-import org.apache.bval.util.reflection.TypeUtils;
-import org.apache.commons.weaver.privilizer.Privilizing;
-import org.apache.commons.weaver.privilizer.Privilizing.CallTo;
-
-/**
- * Objects of this class are able to validate bean instances (and the associated object graphs).
- * <p/>
- * Implementation is thread-safe.
- * <p/>
- * API class
- *
- * @version $Rev: 1514672 $ $Date: 2013-08-16 14:15:12 +0200 (ven., 16 août 2013) $
- * 
- * @author Roman Stumm
- * @author Carlos Vara
- */
-@Privilizing(@CallTo(Reflection.class))
-public class ClassValidator implements CascadingPropertyValidator, ExecutableValidator {
-    private static final Object VALIDATE_PROPERTY = new Object() {
-        @Override
-        public String toString() {
-            return "VALIDATE_PROPERTY";
-        }
-    };
-
-    /**
-     * {@link ApacheFactoryContext} used
-     */
-    protected final ApacheFactoryContext factoryContext;
-
-    /**
-     * {@link GroupsComputer} used
-     */
-    protected final GroupsComputer groupsComputer = new GroupsComputer();
-
-    private final MetaBeanFinder metaBeanFinder;
-
-    /**
-     * Create a new ClassValidator instance.
-     *
-     * @param factoryContext
-     */
-    public ClassValidator(ApacheFactoryContext factoryContext) {
-        this.factoryContext = factoryContext;
-        metaBeanFinder = factoryContext.getMetaBeanFinder();
-    }
-
-    // Validator implementation
-    // --------------------------------------------------
-
-    /**
-     * {@inheritDoc} Validates all constraints on <code>object</code>.
-     *
-     * @param object object to validate
-     * @param groups group or list of groups targeted for validation (default to
-     *               {@link javax.validation.groups.Default})
-     * @return constraint violations or an empty Set if none
-     * @throws IllegalArgumentException if object is null or if null is passed to the varargs groups
-     * @throws ValidationException      if a non recoverable error happens during the validation
-     *                                  process
-     */
-    @Override
-    @SuppressWarnings("unchecked")
-    public <T> Set<ConstraintViolation<T>> validate(T object, Class<?>... groups) {
-        notNull("validated object", object);
-        checkGroups(groups);
-
-        try {
-            final Class<T> objectClass = (Class<T>) object.getClass();
-            final MetaBean objectMetaBean = metaBeanFinder.findForClass(objectClass);
-            final GroupValidationContext<T> context = createContext(objectMetaBean, object, objectClass, groups);
-            return validateBeanWithGroups(context, context.getGroups());
-        } catch (final RuntimeException ex) {
-            throw unrecoverableValidationError(ex, object);
-        }
-    }
-
-    private <T> Set<ConstraintViolation<T>> validateBeanWithGroups(final GroupValidationContext<T> context,
-        final Groups sequence) {
-        final ConstraintValidationListener<T> result = context.getListener();
-
-        // 1. process groups
-        for (final Group current : sequence.getGroups()) {
-            context.setCurrentGroup(current);
-            validateBeanNet(context);
-        }
-
-        // 2. process sequences
-        for (final List<Group> eachSeq : sequence.getSequences()) {
-            for (final Group current : eachSeq) {
-                context.setCurrentGroup(current);
-                validateBeanNet(context);
-                // if one of the group process in the sequence leads to one
-                // or more validation failure,
-                // the groups following in the sequence must not be
-                // processed
-                if (!result.isEmpty()) {
-                    break;
-                }
-            }
-            if (!result.isEmpty()) {
-                break;
-            }
-        }
-        return result.getConstraintViolations();
-    }
-
-    /**
-     * {@inheritDoc} Validates all constraints placed on the property of <code>object</code> named
-     * <code>propertyName</code>.
-     *
-     * @param object       object to validate
-     * @param propertyName property to validate (ie field and getter constraints). Nested
-     *                     properties may be referenced (e.g. prop[2].subpropA.subpropB)
-     * @param groups       group or list of groups targeted for validation (default to
-     *                     {@link javax.validation.groups.Default})
-     * @return constraint violations or an empty Set if none
-     * @throws IllegalArgumentException if <code>object</code> is null, if <code>propertyName</code>
-     *                                  null, empty or not a valid object property or if null is
-     *                                  passed to the varargs groups
-     * @throws ValidationException      if a non recoverable error happens during the validation
-     *                                  process
-     */
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, Class<?>... groups) {
-        return validateProperty(object, propertyName, false, groups);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateProperty(T object, String propertyName, boolean cascade,
-        Class<?>... groups) {
-        notNull("validated object", object);
-
-        @SuppressWarnings("unchecked")
-        final Set<ConstraintViolation<T>> result =
-            validateValueImpl((Class<T>) object.getClass(), object, propertyName, VALIDATE_PROPERTY, cascade, groups);
-        return result;
-    }
-
-    /**
-     * {@inheritDoc} Validates all constraints placed on the property named <code>propertyName</code> of the class
-     * <code>beanType</code> would the property value be <code>value</code>
-     * <p/>
-     * <code>ConstraintViolation</code> objects return null for {@link ConstraintViolation#getRootBean()} and
-     * {@link ConstraintViolation#getLeafBean()}
-     *
-     * @param beanType     the bean type
-     * @param propertyName property to validate
-     * @param value        property value to validate
-     * @param groups       group or list of groups targeted for validation (default to
-     *                     {@link javax.validation.groups.Default})
-     * @return constraint violations or an empty Set if none
-     * @throws IllegalArgumentException if <code>beanType</code> is null, if
-     *                                  <code>propertyName</code> null, empty or not a valid object
-     *                                  property or if null is passed to the varargs groups
-     * @throws ValidationException      if a non recoverable error happens during the validation
-     *                                  process
-     */
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
-        Class<?>... groups) {
-        return validateValue(beanType, propertyName, value, false, groups);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateValue(Class<T> beanType, String propertyName, Object value,
-        boolean cascade, Class<?>... groups) {
-        return validateValueImpl(notNull("bean type", beanType), null, propertyName, value, cascade, groups);
-    }
-
-    /**
-     * {@inheritDoc} Return the descriptor object describing bean constraints. The returned object (and associated
-     * objects including <code>ConstraintDescriptor<code>s) are immutable.
-     *
-     * @param clazz class or interface type evaluated
-     * @return the bean descriptor for the specified class.
-     * @throws IllegalArgumentException if clazz is null
-     * @throws ValidationException      if a non recoverable error happens during the metadata
-     *                                  discovery or if some constraints are invalid.
-     */
-    @Override
-    public BeanDescriptor getConstraintsForClass(final Class<?> clazz) {
-        notNull("class", clazz);
-        try {
-            final MetaBean metaBean = metaBeanFinder.findForClass(clazz); // don't throw an exception because of a missing validator here
-            BeanDescriptorImpl edesc = metaBean.getFeature(JsrFeatures.Bean.BEAN_DESCRIPTOR);
-            if (edesc == null) {
-                edesc = metaBean.initFeature(JsrFeatures.Bean.BEAN_DESCRIPTOR, createBeanDescriptor(metaBean));
-            }
-            return edesc;
-        } catch (final ConstraintDefinitionException definitionEx) {
-            throw definitionEx;
-        } catch (final ConstraintDeclarationException declarationEx) {
-            throw declarationEx;
-        } catch (final RuntimeException ex) {
-            throw new ValidationException("error retrieving constraints for " + clazz, ex);
-        }
-    }
-
-    /**
-     * {@inheritDoc} Return an instance of the specified type allowing access to provider-specific APIs. If the Bean
-     * Validation provider implementation does not support the specified class, <code>ValidationException</code> is
-     * thrown.
-     *
-     * @param type the class of the object to be returned.
-     * @return an instance of the specified class
-     * @throws ValidationException if the provider does not support the call.
-     */
-    @Override
-    public <T> T unwrap(Class<T> type) {
-        // FIXME 2011-03-27 jw:
-        // This code is unsecure.
-        // It should allow only a fixed set of classes.
-        // Can't fix this because don't know which classes this method should support.
-
-        if (type.isAssignableFrom(getClass())) {
-            @SuppressWarnings("unchecked")
-            final T result = (T) this;
-            return result;
-        }
-        if (!(type.isInterface() || Modifier.isAbstract(type.getModifiers()))) {
-            return newInstance(type);
-        }
-        try {
-            final Class<?> cls = Reflection.toClass(type.getName() + "Impl");
-            if (type.isAssignableFrom(cls)) {
-                @SuppressWarnings("unchecked")
-                final Class<? extends T> implClass = (Class<? extends T>) cls;
-                return newInstance(implClass);
-            }
-        } catch (ClassNotFoundException e) {
-        }
-        throw new ValidationException("Type " + type + " not supported");
-    }
-
-    @Override
-    public ExecutableValidator forExecutables() {
-        return this;
-    }
-
-    private <T> T newInstance(final Class<T> cls) {
-        final Constructor<T> cons = Reflection.getDeclaredConstructor(cls, ApacheFactoryContext.class);
-        if (cons == null) {
-            throw new ValidationException("Cannot instantiate " + cls);
-        }
-        final boolean mustUnset = Reflection.setAccessible(cons, true);
-        try {
-            return cons.newInstance(factoryContext);
-        } catch (final Exception ex) {
-            throw new ValidationException("Cannot instantiate " + cls, ex);
-        } finally {
-            if (mustUnset) {
-                Reflection.setAccessible(cons, false);
-            }
-        }
-    }
-
-    // Helpers
-    // -------------------------------------------------------------------
-
-    /**
-     * Validates a bean and all its cascaded related beans for the currently defined group.
-     * <p/>
-     * Special code is present to manage the {@link Default} group.
-     *
-     * @param context The current context of this validation call. Must have its
-     *                          {@link GroupValidationContext#getCurrentGroup()} field set.
-     */
-    protected void validateBeanNet(GroupValidationContext<?> context) {
-
-        // If reached a cascaded bean which is null
-        if (context.getBean() == null) {
-            return;
-        }
-
-        // If reached a cascaded bean which has already been validated for the
-        // current group
-        if (!context.collectValidated()) {
-            return;
-        }
-
-        // ### First, validate the bean
-
-        // Default is a special case
-        if (context.getCurrentGroup().isDefault()) {
-
-            List<Group> defaultGroups = expandDefaultGroup(context);
-            final ConstraintValidationListener<?> result = context.getListener();
-
-            // If the rootBean defines a GroupSequence
-            if (defaultGroups != null && defaultGroups.size() > 1) {
-
-                int numViolations = result.violationsSize();
-
-                // Validate the bean for each group in the sequence
-                final Group currentGroup = context.getCurrentGroup();
-                for (final Group each : defaultGroups) {
-                    context.setCurrentGroup(each);
-
-                    // ValidationHelper.validateBean(context);, doesn't match anymore because of @ConvertGroup
-                    validateBean(context);
-
-                    // Spec 3.4.3 - Stop validation if errors already found
-                    if (result.violationsSize() > numViolations) {
-                        break;
-                    }
-                }
-                context.setCurrentGroup(currentGroup);
-            } else {
-
-                // For each class in the hierarchy of classes of rootBean,
-                // validate the constraints defined in that class according
-                // to the GroupSequence defined in the same class
-
-                // Obtain the full class hierarchy
-                final List<Class<?>> classHierarchy = new ArrayList<Class<?>>();
-                ClassHelper.fillFullClassHierarchyAsList(classHierarchy, context.getMetaBean().getBeanClass());
-                final Class<?> initialOwner = context.getCurrentOwner();
-
-                // For each owner in the hierarchy
-                for (final Class<?> owner : classHierarchy) {
-
-                    context.setCurrentOwner(owner);
-
-                    int numViolations = result.violationsSize();
-
-                    // Obtain the group sequence of the owner, and use it for
-                    // the constraints that belong to it
-                    final List<Group> ownerDefaultGroups =
-                        context.getMetaBean().getFeature("{GroupSequence:" + owner.getCanonicalName() + "}");
-                    for (Group each : ownerDefaultGroups) {
-                        context.setCurrentGroup(each);
-                        validateBean(context);
-                        // Spec 3.4.3 - Stop validation if errors already found
-                        if (result.violationsSize() > numViolations) {
-                            break;
-                        }
-                    }
-                }
-                context.setCurrentOwner(initialOwner);
-                context.setCurrentGroup(Group.DEFAULT);
-            }
-        }
-        // if not the default group, proceed as normal
-        else {
-            validateBean(context);
-        }
-
-        // ### Then, the cascaded beans (@Valid)
-        for (final MetaProperty prop : context.getMetaBean().getProperties()) {
-            final Group group = context.getCurrentGroup();
-            final Group mappedGroup;
-
-            final Object feature = prop.getFeature(JsrFeatures.Property.PropertyDescriptor);
-            if (feature == null) {
-                mappedGroup = group;
-            } else {
-                mappedGroup = PropertyDescriptorImpl.class.cast(feature).mapGroup(group);
-            }
-
-            if (group == mappedGroup) {
-                validateCascadedBean(context, prop, null);
-            } else {
-                final Groups propertyGroup = groupsComputer.computeGroups(new Class<?>[] { mappedGroup.getGroup() });
-                validateCascadedBean(context, prop, propertyGroup);
-            }
-            context.setCurrentGroup(group);
-        }
-    }
-
-    // TODO: maybe add a GroupMapper to bval-core to ease this kind of thing and void to fork this method from ValidationHelper
-    private void validateBean(final GroupValidationContext<?> context) {
-        // execute all property level validations
-        for (final PropertyDescriptor prop : getConstraintsForClass(context.getMetaBean().getBeanClass())
-            .getConstrainedProperties()) {
-            final PropertyDescriptorImpl impl = PropertyDescriptorImpl.class.cast(prop);
-            if (!impl.isValidated(impl)) {
-                checkValidationAppliesTo(impl.getConstraintDescriptors(), ConstraintTarget.PARAMETERS);
-                checkValidationAppliesTo(impl.getConstraintDescriptors(), ConstraintTarget.RETURN_VALUE);
-                impl.setValidated(impl); // we don't really care about concurrency here
-            }
-
-            final MetaProperty metaProperty = context.getMetaBean().getProperty(prop.getPropertyName());
-            context.setMetaProperty(metaProperty);
-            final Group current = context.getCurrentGroup();
-            context.setCurrentGroup(impl.mapGroup(current));
-            ValidationHelper.validateProperty(context);
-            context.setCurrentGroup(current);
-        }
-
-        // execute all bean level validations
-        context.setMetaProperty(null);
-        for (final Validation validation : context.getMetaBean().getValidations()) {
-            if (ConstraintValidation.class.isInstance(validation)) {
-                final ConstraintValidation<?> constraintValidation = ConstraintValidation.class.cast(validation);
-                if (!constraintValidation.isValidated()) {
-                    checkValidationAppliesTo(constraintValidation.getValidationAppliesTo(),
-                        ConstraintTarget.PARAMETERS);
-                    checkValidationAppliesTo(constraintValidation.getValidationAppliesTo(),
-                        ConstraintTarget.RETURN_VALUE);
-                    constraintValidation.setValidated(true);
-                }
-            }
-            validation.validate(context);
-        }
-    }
-
-    /**
-     * Checks if the the meta property <code>prop</code> defines a cascaded bean, and in case it does, validates it.
-     *
-     * @param context The current validation context.
-     * @param prop    The property to cascade from (in case it is possible).
-     */
-    private void validateCascadedBean(final GroupValidationContext<?> context, final MetaProperty prop,
-        final Groups groups) {
-        final AccessStrategy[] access = prop.getFeature(Features.Property.REF_CASCADE);
-        if (access != null) { // different accesses to relation
-            // save old values from context
-            final Object bean = context.getBean();
-            final MetaBean mbean = context.getMetaBean();
-            // TODO implement Validation.groups support on related bean
-            //            Class[] groups = prop.getFeature(JsrFeatures.Property.REF_GROUPS);
-            for (final AccessStrategy each : access) {
-                if (isCascadable(context, prop, each)) {
-                    // modify context state for relationship-target bean
-                    context.moveDown(prop, each);
-                    // validate
-                    if (groups == null) {
-                        ValidationHelper.validateContext(context, new JsrValidationCallback(context),
-                            factoryContext.isTreatMapsLikeBeans());
-                    } else {
-                        ValidationHelper.validateContext(context, new ValidationHelper.ValidateCallback() {
-                            @Override
-                            public void validate() {
-                                validateBeanWithGroups(context, groups);
-                            }
-                        }, factoryContext.isTreatMapsLikeBeans());
-                    }
-                    // restore old values in context
-                    context.moveUp(bean, mbean);
-                }
-            }
-        }
-    }
-
-    /**
-     * Before accessing a related bean (marked with {@link javax.validation.Valid}), the validator has to check if it is
-     * reachable and cascadable.
-     *
-     * @param context The current validation context.
-     * @param prop    The property of the related bean.
-     * @param access  The access strategy used to get the related bean value.
-     * @return <code>true</code> if the validator can access the related bean, <code>false</code> otherwise.
-     */
-    private boolean isCascadable(GroupValidationContext<?> context, MetaProperty prop, AccessStrategy access) {
-
-        PathImpl beanPath = context.getPropertyPath();
-        final NodeImpl node = new NodeImpl.PropertyNodeImpl(prop.getName());
-        if (beanPath == null) {
-            beanPath = PathImpl.create();
-        }
-        try {
-            if (!context.getTraversableResolver().isReachable(context.getBean(), node,
-                context.getRootMetaBean().getBeanClass(), beanPath, access.getElementType())) {
-                return false;
-            }
-        } catch (RuntimeException e) {
-            throw new ValidationException("Error in TraversableResolver.isReachable() for " + context.getBean(), e);
-        }
-
-        try {
-            if (!context.getTraversableResolver().isCascadable(context.getBean(), node,
-                context.getRootMetaBean().getBeanClass(), beanPath, access.getElementType())) {
-                return false;
-            }
-        } catch (RuntimeException e) {
-            throw new ValidationException("Error TraversableResolver.isCascadable() for " + context.getBean(), e);
-        }
-        return true;
-    }
-
-    /**
-     * in case of a default group return the list of groups for a redefined default GroupSequence
-     *
-     * @return null when no in default group or default group sequence not redefined
-     */
-    private List<Group> expandDefaultGroup(GroupValidationContext<?> context) {
-        if (context.getCurrentGroup().isDefault()) {
-            // mention if metaBean redefines the default group
-            final List<Group> groupSeq = context.getMetaBean().getFeature(JsrFeatures.Bean.GROUP_SEQUENCE);
-            if (groupSeq != null) {
-                context.getGroups().assertDefaultGroupSequenceIsExpandable(groupSeq);
-            }
-            return groupSeq;
-        }
-        return null;
-    }
-
-    /**
-     * Generate an unrecoverable validation error
-     *
-     * @param ex
-     * @param object
-     * @return a {@link RuntimeException} of the appropriate type
-     */
-    protected static RuntimeException unrecoverableValidationError(RuntimeException ex, Object object) {
-        if (ex instanceof UnknownPropertyException || ex instanceof IncompatiblePropertyValueException) {
-            // Convert to IllegalArgumentException
-            return new IllegalArgumentException(ex.getMessage(), ex);
-        }
-        if (ex instanceof ValidationException) {
-            return ex; // do not wrap specific ValidationExceptions (or instances from subclasses)
-        }
-        String objectId;
-        if (object == null) {
-            objectId = "<null>";
-        } else {
-            try {
-                objectId = object.toString();
-            } catch (Exception e) {
-                objectId = "<unknown>";
-            }
-        }
-        return new ValidationException("error during validation of " + objectId, ex);
-    }
-
-    private void validatePropertyInGroup(final GroupValidationContext<?> context) {
-        final Runnable helper;
-        if (context.getMetaProperty() == null) {
-            helper = new Runnable() {
-
-                @Override
-                public void run() {
-                    ValidationHelper.validateBean(context);
-                }
-            };
-        } else {
-            helper = new Runnable() {
-
-                @Override
-                public void run() {
-                    ValidationHelper.validateProperty(context);
-                }
-            };
-        }
-        final List<Group> defaultGroups = expandDefaultGroup(context);
-        if (defaultGroups == null) {
-            helper.run();
-        } else {
-            final Group currentGroup = context.getCurrentGroup();
-            for (Group each : defaultGroups) {
-                context.setCurrentGroup(each);
-                helper.run();
-                // continue validation, even if errors already found
-            }
-            context.setCurrentGroup(currentGroup); // restore
-        }
-    }
-
-    /**
-     * Create a {@link GroupValidationContext}.
-     *
-     * @param <T>
-     * @param metaBean
-     * @param object
-     * @param objectClass
-     * @param groups
-     * @return {@link GroupValidationContext} instance
-     */
-    protected <T> GroupValidationContext<T> createContext(MetaBean metaBean, T object, Class<T> objectClass,
-        Class<?>... groups) {
-        final ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object, objectClass);
-        final GroupValidationContextImpl<T> context = new GroupValidationContextImpl<T>(listener,
-            factoryContext.getMessageInterpolator(), factoryContext.getTraversableResolver(),
-            factoryContext.getParameterNameProvider(), factoryContext.getConstraintValidatorFactory(), metaBean);
-        context.setBean(object, metaBean);
-        context.setGroups(groupsComputer.computeGroups(groups));
-        return context;
-    }
-
-    protected <T> GroupValidationContext<T> createInvocableContext(MetaBean metaBean, T object, Class<T> objectClass,
-        Class<?>... groups) {
-        final ConstraintValidationListener<T> listener = new ConstraintValidationListener<T>(object, objectClass);
-        final GroupValidationContextImpl<T> context = new GroupValidationContextImpl<T>(listener,
-            factoryContext.getMessageInterpolator(), factoryContext.getTraversableResolver(),
-            factoryContext.getParameterNameProvider(), factoryContext.getConstraintValidatorFactory(), metaBean);
-        context.setBean(object, metaBean);
-        final Groups computedGroup = groupsComputer.computeGroups(groups);
-        if (Collections.singletonList(Group.DEFAULT).equals(computedGroup.getGroups())
-            && metaBean.getFeature(JsrFeatures.Bean.GROUP_SEQUENCE) != null) {
-            final Groups sequence = new Groups();
-            @SuppressWarnings("unchecked")
-            final List<? extends Group> sequenceGroups =
-                List.class.cast(metaBean.getFeature(JsrFeatures.Bean.GROUP_SEQUENCE));
-            sequence.getGroups().addAll(sequenceGroups);
-            context.setGroups(sequence);
-        } else {
-            context.setGroups(computedGroup);
-        }
-        return context;
-    }
-
-    /**
-     * Create a {@link BeanDescriptorImpl}
-     *
-     * @param metaBean
-     * @return {@link BeanDescriptorImpl} instance
-     */
-    protected BeanDescriptorImpl createBeanDescriptor(MetaBean metaBean) {
-        return new BeanDescriptorImpl(factoryContext, metaBean);
-    }
-
-    /**
-     * Checks that the property name is valid according to spec Section 4.1.1 i. Throws an
-     * {@link IllegalArgumentException} if it is not.
-     *
-     * @param propertyName Property name to check.
-     */
-    private void checkPropertyName(String propertyName) {
-        if (propertyName == null || propertyName.trim().isEmpty()) {
-            throw new IllegalArgumentException("Property path cannot be null or empty.");
-        }
-    }
-
-    /**
-     * Checks that the groups array is valid according to spec Section 4.1.1 i. Throws an
-     * {@link IllegalArgumentException} if it is not.
-     *
-     * @param groups The groups to check.
-     */
-    private void checkGroups(Class<?>[] groups) {
-        for (final Class<?> c : notNull("groups", groups)) {
-            notNull("group", c);
-        }
-    }
-
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateConstructorParameters(Constructor<? extends T> constructor,
-        Object[] parameterValues, Class<?>... gps) {
-        notNull("Constructor", constructor);
-        notNull("Groups", gps);
-        notNull("Parameters", parameterValues);
-
-        final Class<?> declaringClass = constructor.getDeclaringClass();
-        final ConstructorDescriptorImpl constructorDescriptor = ConstructorDescriptorImpl.class
-            .cast(getConstraintsForClass(declaringClass).getConstraintsForConstructor(constructor.getParameterTypes()));
-        if (constructorDescriptor == null) { // no constraint
-            return Collections.emptySet();
-        }
-
-        // sanity checks
-        if (!constructorDescriptor.isValidated(constructor)) {
-            if (parameterValues.length == 0) {
-                checkValidationAppliesTo(Collections.singleton(constructorDescriptor.getCrossParameterDescriptor()),
-                    ConstraintTarget.PARAMETERS);
-                checkValidationAppliesTo(constructorDescriptor.getParameterDescriptors(), ConstraintTarget.PARAMETERS);
-            } else {
-                checkValidationAppliesTo(Collections.singleton(constructorDescriptor.getCrossParameterDescriptor()),
-                    ConstraintTarget.IMPLICIT);
-                checkValidationAppliesTo(constructorDescriptor.getParameterDescriptors(), ConstraintTarget.IMPLICIT);
-            }
-            constructorDescriptor.setValidated(constructor);
-        }
-
-        // validations
-        return validateInvocationParameters(constructor, parameterValues, constructorDescriptor, gps,
-            new NodeImpl.ConstructorNodeImpl(declaringClass.getSimpleName(),
-                Arrays.asList(constructor.getParameterTypes())),
-            null);
-    }
-
-    private <T> Set<ConstraintViolation<T>> validateInvocationParameters(final Member invocable,
-        final Object[] parameterValues, final InvocableElementDescriptor constructorDescriptor, final Class<?>[] gps,
-        final NodeImpl rootNode, final Object rootBean) {
-        final Set<ConstraintViolation<T>> violations = new HashSet<ConstraintViolation<T>>();
-
-        @SuppressWarnings("unchecked")
-        final GroupValidationContext<ConstraintValidationListener<?>> parametersContext = createInvocableContext(
-            constructorDescriptor.getMetaBean(), rootBean, Class.class.cast(invocable.getDeclaringClass()), gps);
-
-        @SuppressWarnings("unchecked")
-        final GroupValidationContext<Object> crossParameterContext = createContext(constructorDescriptor.getMetaBean(),
-            rootBean, Class.class.cast(invocable.getDeclaringClass()), gps);
-
-        if (rootBean == null) {
-            final Constructor<?> m = Constructor.class.cast(invocable);
-            parametersContext.setConstructor(m);
-            crossParameterContext.setConstructor(m);
-        } else { // could be more sexy but that's ok for now
-            final Method m = Method.class.cast(invocable);
-            parametersContext.setMethod(m);
-            crossParameterContext.setMethod(m);
-        }
-
-        final Groups groups = parametersContext.getGroups();
-
-        final List<ParameterDescriptor> parameterDescriptors = constructorDescriptor.getParameterDescriptors();
-        final ElementDescriptorImpl crossParamDescriptor =
-            ElementDescriptorImpl.class.cast(constructorDescriptor.getCrossParameterDescriptor());
-        final Set<ConstraintDescriptor<?>> crossParamConstraints = crossParamDescriptor.getConstraintDescriptors();
-
-        crossParameterContext.setBean(parameterValues);
-        crossParameterContext.moveDown(rootNode);
-        crossParameterContext.moveDown("<cross-parameter>");
-        crossParameterContext.setKind(ElementKind.CROSS_PARAMETER);
-
-        parametersContext.moveDown(rootNode);
-        parametersContext.setParameters(parameterValues);
-
-        for (final Group current : groups.getGroups()) {
-            for (int i = 0; i < parameterValues.length; i++) {
-                final ParameterDescriptorImpl paramDesc =
-                    ParameterDescriptorImpl.class.cast(parameterDescriptors.get(i));
-                parametersContext.setBean(parameterValues[i]);
-                parametersContext.moveDown(new NodeImpl.ParameterNodeImpl(paramDesc.getName(), i));
-                for (final ConstraintDescriptor<?> constraintDescriptor : paramDesc.getConstraintDescriptors()) {
-                    final ConstraintValidation<?> validation = ConstraintValidation.class.cast(constraintDescriptor);
-                    parametersContext.setCurrentGroup(paramDesc.mapGroup(current));
-                    validation.validateGroupContext(parametersContext);
-                }
-                parametersContext.moveUp(null, null);
-            }
-
-            for (final ConstraintDescriptor<?> d : crossParamConstraints) {
-                final ConstraintValidation<?> validation = ConstraintValidation.class.cast(d);
-                crossParameterContext.setCurrentGroup(crossParamDescriptor.mapGroup(current));
-                validation.validateGroupContext(crossParameterContext);
-            }
-
-            if (gps.length == 0 && parametersContext.getListener().getConstraintViolations().size()
-                + crossParameterContext.getListener().getConstraintViolations().size() > 0) {
-                break;
-            }
-        }
-
-        for (final Group current : groups.getGroups()) {
-            for (int i = 0; i < parameterValues.length; i++) {
-                final ParameterDescriptorImpl paramDesc =
-                    ParameterDescriptorImpl.class.cast(parameterDescriptors.get(i));
-                if (paramDesc.isCascaded() && parameterValues[i] != null) {
-                    parametersContext.setBean(parameterValues[i]);
-                    parametersContext.moveDown(new NodeImpl.ParameterNodeImpl(paramDesc.getName(), i));
-                    initMetaBean(parametersContext, factoryContext.getMetaBeanFinder(), parameterValues[i].getClass());
-                    parametersContext.setCurrentGroup(paramDesc.mapGroup(current));
-                    ValidationHelper.validateContext(parametersContext, new JsrValidationCallback(parametersContext),
-                        factoryContext.isTreatMapsLikeBeans());
-                    parametersContext.moveUp(null, null);
-                }
-            }
-        }
-
-        for (final List<Group> eachSeq : groups.getSequences()) {
-            for (final Group current : eachSeq) {
-                for (int i = 0; i < parameterValues.length; i++) {
-                    final ParameterDescriptorImpl paramDesc =
-                        ParameterDescriptorImpl.class.cast(parameterDescriptors.get(i));
-                    parametersContext.setBean(parameterValues[i]);
-                    parametersContext.moveDown(new NodeImpl.ParameterNodeImpl(paramDesc.getName(), i));
-                    for (final ConstraintDescriptor<?> constraintDescriptor : paramDesc.getConstraintDescriptors()) {
-                        final ConstraintValidation<?> validation =
-                            ConstraintValidation.class.cast(constraintDescriptor);
-                        parametersContext.setCurrentGroup(paramDesc.mapGroup(current));
-                        validation.validateGroupContext(parametersContext);
-                    }
-                    parametersContext.moveUp(null, null);
-                }
-
-                for (final ConstraintDescriptor<?> d : crossParamConstraints) {
-                    final ConstraintValidation<?> validation = ConstraintValidation.class.cast(d);
-                    crossParameterContext.setCurrentGroup(crossParamDescriptor.mapGroup(current));
-                    validation.validateGroupContext(crossParameterContext);
-                }
-
-                if (parametersContext.getListener().getConstraintViolations().size()
-                    + crossParameterContext.getListener().getConstraintViolations().size() > 0) {
-                    break;
-                }
-            }
-
-            for (final Group current : eachSeq) {
-                for (int i = 0; i < parameterValues.length; i++) {
-                    final ParameterDescriptorImpl paramDesc =
-                        ParameterDescriptorImpl.class.cast(parameterDescriptors.get(i));
-                    if (paramDesc.isCascaded() && parameterValues[i] != null) {
-                        parametersContext.setBean(parameterValues[i]);
-                        parametersContext.moveDown(new NodeImpl.ParameterNodeImpl(paramDesc.getName(), i));
-                        initMetaBean(parametersContext, factoryContext.getMetaBeanFinder(),
-                            parameterValues[i].getClass());
-                        parametersContext.setCurrentGroup(paramDesc.mapGroup(current));
-                        ValidationHelper.validateContext(parametersContext,
-                            new JsrValidationCallback(parametersContext), factoryContext.isTreatMapsLikeBeans());
-                        parametersContext.moveUp(null, null);
-                    }
-                }
-            }
-        }
-        if (constructorDescriptor.isCascaded()) {
-            if (parametersContext.getValidatedValue() != null) {
-                initMetaBean(parametersContext, factoryContext.getMetaBeanFinder(),
-                    parametersContext.getValidatedValue().getClass());
-
-                for (final Group current : groups.getGroups()) {
-                    parametersContext.setCurrentGroup(constructorDescriptor.mapGroup(current));
-                    ValidationHelper.validateContext(parametersContext, new JsrValidationCallback(parametersContext),
-                        factoryContext.isTreatMapsLikeBeans());
-                }
-                for (final List<Group> eachSeq : groups.getSequences()) {
-                    for (final Group current : eachSeq) {
-                        parametersContext.setCurrentGroup(constructorDescriptor.mapGroup(current));
-                        ValidationHelper.validateContext(parametersContext,
-                            new JsrValidationCallback(parametersContext), factoryContext.isTreatMapsLikeBeans());
-                        if (!parametersContext.getListener().isEmpty()) {
-                            break;
-                        }
-                    }
-                }
-            }
-            if (crossParameterContext.getValidatedValue() != null) {
-                initMetaBean(crossParameterContext, factoryContext.getMetaBeanFinder(),
-                    crossParameterContext.getValidatedValue().getClass());
-
-                for (final Group current : groups.getGroups()) {
-                    crossParameterContext.setCurrentGroup(constructorDescriptor.mapGroup(current));
-                    ValidationHelper.validateContext(crossParameterContext,
-                        new JsrValidationCallback(crossParameterContext), factoryContext.isTreatMapsLikeBeans());
-                }
-                for (final List<Group> eachSeq : groups.getSequences()) {
-                    for (final Group current : eachSeq) {
-                        crossParameterContext.setCurrentGroup(constructorDescriptor.mapGroup(current));
-                        ValidationHelper.validateContext(crossParameterContext,
-                            new JsrValidationCallback(crossParameterContext), factoryContext.isTreatMapsLikeBeans());
-                        if (!crossParameterContext.getListener().isEmpty()) {
-                            break;
-                        }
-                    }
-                }
-            }
-        }
-
-        @SuppressWarnings("unchecked")
-        final Set<ConstraintViolation<T>> parameterViolations =
-            Set.class.cast(parametersContext.getListener().getConstraintViolations());
-        violations.addAll(parameterViolations);
-        @SuppressWarnings("unchecked")
-        final Set<ConstraintViolation<T>> crossParameterViolations =
-            Set.class.cast(crossParameterContext.getListener().getConstraintViolations());
-        violations.addAll(crossParameterViolations);
-
-        return violations;
-    }
-
-    private static void checkValidationAppliesTo(final Collection<? extends ElementDescriptor> descriptors,
-        final ConstraintTarget forbidden) {
-        for (final ElementDescriptor descriptor : descriptors) {
-            for (final ConstraintDescriptor<?> consDesc : descriptor.getConstraintDescriptors()) {
-                checkValidationAppliesTo(consDesc.getValidationAppliesTo(), forbidden);
-            }
-        }
-    }
-
-    private static void checkValidationAppliesTo(final Set<ConstraintDescriptor<?>> constraintDescriptors,
-        final ConstraintTarget forbidden) {
-        for (final ConstraintDescriptor<?> descriptor : constraintDescriptors) {
-            checkValidationAppliesTo(descriptor.getValidationAppliesTo(), forbidden);
-        }
-    }
-
-    private static void checkValidationAppliesTo(final ConstraintTarget configured, final ConstraintTarget forbidden) {
-        if (forbidden.equals(configured)) {
-            throw new ConstraintDeclarationException(forbidden.name() + " forbidden here");
-        }
-    }
-
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateConstructorReturnValue(final Constructor<? extends T> constructor,
-        final T createdObject, final Class<?>... gps) {
-        notNull("Constructor", constructor);
-        notNull("Returned value", createdObject);
-
-        final Class<? extends T> declaringClass = constructor.getDeclaringClass();
-        final ConstructorDescriptorImpl methodDescriptor = ConstructorDescriptorImpl.class
-            .cast(getConstraintsForClass(declaringClass).getConstraintsForConstructor(constructor.getParameterTypes()));
-        if (methodDescriptor == null) {
-            throw new ValidationException("Constructor " + constructor + " doesn't belong to class " + declaringClass);
-        }
-
-        return validateReturnedValue(
-            new NodeImpl.ConstructorNodeImpl(declaringClass.getSimpleName(),
-                Arrays.asList(constructor.getParameterTypes())),
-            createdObject, declaringClass, methodDescriptor, gps, null);
-    }
-
-    private <T> Set<ConstraintViolation<T>> validateReturnedValue(final NodeImpl rootNode, final T createdObject,
-        final Class<?> clazz, final InvocableElementDescriptor methodDescriptor, final Class<?>[] gps,
-        final Object rootBean) {
-        final ElementDescriptorImpl returnedValueDescriptor =
-            ElementDescriptorImpl.class.cast(methodDescriptor.getReturnValueDescriptor());
-        final Set<ConstraintDescriptor<?>> returnedValueConstraints =
-            returnedValueDescriptor.getConstraintDescriptors();
-
-        @SuppressWarnings("unchecked")
-        final GroupValidationContext<T> context = createInvocableContext(methodDescriptor.getMetaBean(), createdObject,
-            Class.class.cast(Proxies.classFor(clazz)), gps);
-        context.moveDown(rootNode);
-        context.moveDown(new NodeImpl.ReturnValueNodeImpl());
-        context.setReturnValue(rootBean);
-
-        final Groups groups = context.getGroups();
-
-        for (final Group current : groups.getGroups()) {
-            for (final ConstraintDescriptor<?> d : returnedValueConstraints) {
-                final ConstraintValidation<?> validation = ConstraintValidation.class.cast(d);
-                context.setCurrentGroup(returnedValueDescriptor.mapGroup(current));
-                validation.validateGroupContext(context);
-            }
-            if (gps.length == 0 && !context.getListener().getConstraintViolations().isEmpty()) {
-                break;
-            }
-        }
-
-        int currentViolationNumber = context.getListener().getConstraintViolations().size();
-        for (final Group current : groups.getGroups()) {
-            if (returnedValueDescriptor.isCascaded() && context.getValidatedValue() != null) {
-                context.setBean(createdObject);
-                initMetaBean(context, factoryContext.getMetaBeanFinder(), context.getValidatedValue().getClass());
-
-                context.setCurrentGroup(methodDescriptor.mapGroup(current));
-                ValidationHelper.validateContext(context, new JsrValidationCallback(context),
-                    factoryContext.isTreatMapsLikeBeans());
-
-                if (currentViolationNumber < context.getListener().getConstraintViolations().size()) {
-                    break;
-                }
-            }
-        }
-
-        for (final List<Group> eachSeq : groups.getSequences()) {
-            for (final Group current : eachSeq) {
-                for (final ConstraintDescriptor<?> d : returnedValueConstraints) {
-                    final ConstraintValidation<?> validation = ConstraintValidation.class.cast(d);
-                    context.setCurrentGroup(current);
-                    validation.validateGroupContext(context);
-                }
-                if (!context.getListener().getConstraintViolations().isEmpty()) {
-                    break;
-                }
-            }
-
-            currentViolationNumber = context.getListener().getConstraintViolations().size();
-            for (final Group current : eachSeq) {
-                if (returnedValueDescriptor.isCascaded() && context.getValidatedValue() != null) {
-                    context.setBean(createdObject);
-                    initMetaBean(context, factoryContext.getMetaBeanFinder(), context.getValidatedValue().getClass());
-
-                    context.setCurrentGroup(methodDescriptor.mapGroup(current));
-                    ValidationHelper.validateContext(context, new JsrValidationCallback(context),
-                        factoryContext.isTreatMapsLikeBeans());
-
-                    if (currentViolationNumber < context.getListener().getConstraintViolations().size()) {
-                        break;
-                    }
-                }
-            }
-        }
-
-        return context.getListener().getConstraintViolations();
-    }
-
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateParameters(T object, Method method, Object[] parameterValues,
-        Class<?>... groups) {
-        notNull("Object", object);
-        notNull("Parameters", parameterValues);
-        notNull("Method", method);
-        notNull("Groups", groups);
-        for (final Class<?> g : groups) {
-            notNull("Each group", g);
-        }
-
-        final MethodDescriptorImpl methodDescriptor = findMethodDescriptor(object, method);
-        if (methodDescriptor == null
-            || !(methodDescriptor.hasConstrainedParameters() || methodDescriptor.hasConstrainedReturnValue())) { // no constraint
-            return Collections.emptySet();
-        }
-
-        if (!methodDescriptor.isValidated(method)) {
-            if (method.getParameterTypes().length == 0) {
-                checkValidationAppliesTo(Collections.singleton(methodDescriptor.getCrossParameterDescriptor()),
-                    ConstraintTarget.PARAMETERS);
-                checkValidationAppliesTo(methodDescriptor.getParameterDescriptors(), ConstraintTarget.PARAMETERS);
-            } else if (!Void.TYPE.equals(method.getReturnType())) {
-                checkValidationAppliesTo(Collections.singleton(methodDescriptor.getCrossParameterDescriptor()),
-                    ConstraintTarget.IMPLICIT);
-                checkValidationAppliesTo(methodDescriptor.getParameterDescriptors(), ConstraintTarget.IMPLICIT);
-            }
-            methodDescriptor.setValidated(method);
-        }
-        return validateInvocationParameters(method, parameterValues, methodDescriptor, groups,
-            new NodeImpl.MethodNodeImpl(method.getName(), Arrays.asList(method.getParameterTypes())), object);
-    }
-
-    private static <T> T notNull(final String entity, final T shouldntBeNull) {
-        if (shouldntBeNull == null) {
-            throw new IllegalArgumentException(entity + " cannot be null");
-        }
-        return shouldntBeNull;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public <T> Set<ConstraintViolation<T>> validateReturnValue(T object, Method method, Object returnValue,
-        Class<?>... groups) {
-        notNull("object", object);
-        notNull("method", method);
-        notNull("groups", groups);
-
-        final MethodDescriptorImpl methodDescriptor = findMethodDescriptor(object, method);
-        if (methodDescriptor == null) {
-            throw new ValidationException("Method " + method + " doesn't belong to class " + object.getClass());
-        }
-
-        if (method.getReturnType() == Void.TYPE) {
-            checkValidationAppliesTo(methodDescriptor.getReturnValueDescriptor().getConstraintDescriptors(),
-                ConstraintTarget.RETURN_VALUE);
-        }
-
-        @SuppressWarnings("unchecked")
-        final Set<ConstraintViolation<T>> result = Set.class.cast(validateReturnedValue(
-            new NodeImpl.MethodNodeImpl(method.getName(), Arrays.asList(method.getParameterTypes())), returnValue,
-            object.getClass(), methodDescriptor, groups, object));
-        return result;
-    }
-
-    private <T> MethodDescriptorImpl findMethodDescriptor(final T object, final Method method) {
-        return MethodDescriptorImpl.class
-            .cast(BeanDescriptorImpl.class.cast(getConstraintsForClass(Proxies.classFor(method.getDeclaringClass())))
-                .getInternalConstraintsForMethod(method.getName(), method.getParameterTypes()));
-    }
-
-    private <T> void initMetaBean(final GroupValidationContext<T> context, final MetaBeanFinder metaBeanFinder,
-        final Class<?> directValueClass) {
-        if (directValueClass.isArray()) {
-            context.setMetaBean(metaBeanFinder.findForClass(directValueClass.getComponentType()));
-            return;
-        }
-        if (Collection.class.isAssignableFrom(directValueClass)) {
-            final Collection<?> coll = Collection.class.cast(context.getValidatedValue());
-            if (!coll.isEmpty()) {
-                context.setMetaBean(metaBeanFinder.findForClass(coll.iterator().next().getClass()));
-                return;
-            }
-        }
-        if (Map.class.isAssignableFrom(directValueClass)) {
-            final Map<?, ?> m = Map.class.cast(context.getValidatedValue());
-            if (!m.isEmpty()) {
-                context.setMetaBean(metaBeanFinder.findForClass(m.values().iterator().next().getClass()));
-                return;
-            }
-        }
-        context.setMetaBean(metaBeanFinder.findForClass(directValueClass));
-    }
-
-    /**
-     * Dispatches a call from {@link #validate()} to {@link ClassValidator#validateBeanNet(GroupValidationContext)} with
-     * the current context set.
-     */
-    protected class JsrValidationCallback implements ValidationHelper.ValidateCallback {
-
-        private final GroupValidationContext<?> context;
-
-        public JsrValidationCallback(GroupValidationContext<?> context) {
-            this.context = context;
-        }
-
-        @Override
-        public void validate() {
-            validateBeanNet(context);
-        }
-
-    }
-
-    /**
-     * Create a {@link ValidationContextTraversal} instance for this {@link ClassValidator}.
-     * 
-     * @param validationContext
-     * @return {@link ValidationContextTraversal}
-     */
-    protected ValidationContextTraversal createValidationContextTraversal(GroupValidationContext<?> validationContext) {
-        return new ValidationContextTraversal(validationContext);
-    }
-
-    /**
-     * Implement {@link #validateProperty(Object, String, boolean, Class[])} } and
-     * {@link #validateValue(Class, String, Object, boolean, Class...)}.
-     * 
-     * @param <T>
-     * @param beanType
-     * @param object
-     * @param propertyName
-     * @param value
-     * @param cascade
-     * @param groups
-     * @return {@link ConstraintViolation} {@link Set}
-     */
-    private <T> Set<ConstraintViolation<T>> validateValueImpl(Class<T> beanType, T object, String propertyName,
-        Object value, final boolean cascade, Class<?>... groups) {
-
-        assert (object == null) ^ (value == VALIDATE_PROPERTY);
-        checkPropertyName(propertyName);
-        checkGroups(groups);
-
-        try {
-            final MetaBean initialMetaBean = new DynamicMetaBean(metaBeanFinder);
-            initialMetaBean.setBeanClass(beanType);
-            GroupValidationContext<T> context = createContext(initialMetaBean, object, beanType, groups);
-            ValidationContextTraversal contextTraversal = createValidationContextTraversal(context);
-            PathNavigation.navigate(propertyName, contextTraversal);
-
-            MetaProperty prop = context.getMetaProperty();
-            boolean fixed = false;
-            if (value != VALIDATE_PROPERTY) {
-                assert !context.getPropertyPath().isRootPath();
-                if (prop == null && value != null) {
-                    context.setMetaBean(metaBeanFinder.findForClass(value.getClass()));
-                }
-                if (!cascade) {
-                    //TCK doesn't care what type a property is if there are no constraints to validate:
-                    FeaturesCapable meta = prop == null ? context.getMetaBean() : prop;
-
-                    Validation[] validations = meta.getValidations();
-                    if (validations == null || validations.length == 0) {
-                        return Collections.<ConstraintViolation<T>> emptySet();
-                    }
-                }
-                if (!TypeUtils.isAssignable(value == null ? null : value.getClass(), contextTraversal.getType())) {
-                    throw new IncompatiblePropertyValueException(String.format(
-                        "%3$s is not a valid value for property %2$s of type %1$s", beanType, propertyName, value));
-                }
-                if (prop == null) {
-                    context.setBean(value);
-                } else {
-                    context.setFixedValue(value);
-                    fixed = true;
-                }
-            }
-            boolean doCascade = cascade && (prop == null || prop.getMetaBean() != null);
-
-            Object bean = context.getBean();
-
-            ConstraintValidationListener<T> result = context.getListener();
-            Groups sequence = context.getGroups();
-
-            // 1. process groups
-
-            for (Group current : sequence.getGroups()) {
-                context.setCurrentGroup(current);
-
-                if (!doCascade || prop != null) {
-                    validatePropertyInGroup(context);
-                }
-                if (doCascade) {
-                    contextTraversal.moveDownIfNecessary();
-                    if (context.getMetaBean() instanceof DynamicMetaBean) {
-                        context.setMetaBean(context.getMetaBean().resolveMetaBean(
-                            ObjectUtils.defaultIfNull(context.getBean(), contextTraversal.getRawType())));
-                    }
-                    validateBeanNet(context);
-                    if (prop != null) {
-                        context.moveUp(bean, prop.getParentMetaBean());
-                        context.setMetaProperty(prop);
-                        if (fixed) {
-                            context.setFixedValue(value);
-                        }
-                    }
-                }
-            }
-
-            // 2. process sequences
-
-            int groupViolations = result.getConstraintViolations().size();
-
-            outer: for (List<Group> eachSeq : sequence.getSequences()) {
-                for (Group current : eachSeq) {
-                    context.setCurrentGroup(current);
-
-                    if (!doCascade || prop != null) {
-                        validatePropertyInGroup(context);
-                    }
-                    if (doCascade) {
-                        contextTraversal.moveDownIfNecessary();
-                        if (context.getMetaBean() instanceof DynamicMetaBean) {
-                            context.setMetaBean(context.getMetaBean().resolveMetaBean(
-                                ObjectUtils.defaultIfNull(context.getBean(), contextTraversal.getRawType())));
-                        }
-                        validateBeanNet(context);
-                        if (prop != null) {
-                            context.moveUp(bean, prop.getParentMetaBean());
-                            context.setMetaProperty(prop);
-                            if (fixed) {
-                                context.setFixedValue(value);
-                            }
-                        }
-                    }
-                    /**
-                     * if one of the group process in the sequence leads to one or more validation failure, the groups
-                     * following in the sequence must not be processed
-                     */
-                    if (result.getConstraintViolations().size() > groupViolations)
-                        break outer;
-                }
-            }
-            return result.getConstraintViolations();
-        } catch (RuntimeException ex) {
-            throw unrecoverableValidationError(ex, ObjectUtils.defaultIfNull(object, value));
-        }
-    }
-}

http://git-wip-us.apache.org/repos/asf/bval/blob/92c64b3c/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
index 28379b7..e412c30 100644
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
+++ b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintCached.java
@@ -28,7 +28,6 @@ import java.util.HashSet;
 import java.util.List;
 import java.util.Map;
 import java.util.Objects;
-import java.util.Optional;
 import java.util.Set;
 import java.util.stream.Collectors;
 import java.util.stream.Stream;

http://git-wip-us.apache.org/repos/asf/bval/blob/92c64b3c/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
deleted file mode 100644
index c4c9d99..0000000
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintDescriptorImpl.java
+++ /dev/null
@@ -1,236 +0,0 @@
-/*
- * 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 org.apache.bval.jsr;
-
-import javax.validation.ConstraintTarget;
-import javax.validation.Payload;
-import javax.validation.metadata.ConstraintDescriptor;
-import javax.validation.metadata.ValidateUnwrappedValue;
-
-import java.io.Serializable;
-import java.lang.annotation.Annotation;
-import java.util.List;
-import java.util.Map;
-import java.util.Set;
-
-/**
- * Immutable, {@link Serializable} {@link ConstraintDescriptor} implementation.
- *
- * User: roman.stumm<br>
- * Date: 22.04.2010<br>
- * Time: 10:21:23<br>
- */
-public class ConstraintDescriptorImpl<T extends Annotation> implements ConstraintDescriptor<T>, Serializable {
-    /** Serialization version */
-    private static final long serialVersionUID = 1L;
-
-    private final T annotation;
-    private final Set<Class<?>> groups;
-    private final Set<Class<? extends javax.validation.Payload>> payload;
-    private final List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> constraintValidatorClasses;
-    private final Map<String, Object> attributes;
-    private final Set<ConstraintDescriptor<?>> composingConstraints;
-    private final boolean reportAsSingleViolation;
-    private final ConstraintTarget validationAppliesTo;
-    private final String template;
-    private final int hashCode;
-
-    /**
-     * Create a new ConstraintDescriptorImpl instance.
-     * 
-     * @param descriptor
-     */
-    public ConstraintDescriptorImpl(final ConstraintDescriptor<T> descriptor) {
-        this(descriptor.getAnnotation(), descriptor.getGroups(), descriptor.getPayload(),
-            descriptor.getConstraintValidatorClasses(), descriptor.getAttributes(),
-            descriptor.getComposingConstraints(), descriptor.isReportAsSingleViolation(),
-            descriptor.getValidationAppliesTo(), descriptor.getMessageTemplate());
-    }
-
-    /**
-     * Create a new ConstraintDescriptorImpl instance.
-     * 
-     * @param annotation
-     * @param groups
-     * @param payload
-     * @param constraintValidatorClasses
-     * @param attributes
-     * @param composingConstraints
-     * @param reportAsSingleViolation
-     */
-    public ConstraintDescriptorImpl(T annotation, Set<Class<?>> groups,
-        Set<Class<? extends javax.validation.Payload>> payload,
-        List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> constraintValidatorClasses,
-        Map<String, Object> attributes, Set<ConstraintDescriptor<?>> composingConstraints,
-        boolean reportAsSingleViolation, ConstraintTarget validationAppliesTo, String messageTemplate) {
-        this.annotation = annotation;
-        this.groups = groups;
-        this.payload = payload;
-        this.constraintValidatorClasses = constraintValidatorClasses;
-        this.attributes = attributes;
-        this.composingConstraints = composingConstraints;
-        this.reportAsSingleViolation = reportAsSingleViolation;
-        this.validationAppliesTo = validationAppliesTo;
-        this.template = messageTemplate;
-        this.hashCode = computeHashCode();
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public T getAnnotation() {
-        return annotation;
-    }
-
-    @Override
-    public String getMessageTemplate() {
-        return template;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Set<Class<?>> getGroups() {
-        return groups;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Set<Class<? extends Payload>> getPayload() {
-        return payload;
-    }
-
-    @Override
-    public ConstraintTarget getValidationAppliesTo() {
-        return validationAppliesTo;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public List<java.lang.Class<? extends javax.validation.ConstraintValidator<T, ?>>> getConstraintValidatorClasses() {
-        return constraintValidatorClasses;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Map<String, Object> getAttributes() {
-        return attributes;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Set<ConstraintDescriptor<?>> getComposingConstraints() {
-        return composingConstraints;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean isReportAsSingleViolation() {
-        return reportAsSingleViolation;
-    }
-
-    /**
-     * generated equals on all fields except hashCode
-     */
-    @Override
-    public boolean equals(Object o) {
-        if (this == o) {
-            return true;
-        }
-        if (o == null || getClass() != o.getClass()) {
-            return false;
-        }
-
-        ConstraintDescriptorImpl<?> that = (ConstraintDescriptorImpl<?>) o;
-
-        if (reportAsSingleViolation != that.reportAsSingleViolation) {
-            return false;
-        }
-        if (annotation != null ? !annotation.equals(that.annotation) : that.annotation != null) {
-            return false;
-        }
-        if (groups != null ? !groups.equals(that.groups) : that.groups != null) {
-            return false;
-        }
-        if (payload != null ? !payload.equals(that.payload) : that.payload != null) {
-            return false;
-        }
-        if (constraintValidatorClasses != null ? !constraintValidatorClasses.equals(that.constraintValidatorClasses)
-            : that.constraintValidatorClasses != null) {
-            return false;
-        }
-        if (attributes != null ? !attributes.equals(that.attributes) : that.attributes != null) {
-            return false;
-        }
-        if (composingConstraints != null ? !composingConstraints.equals(that.composingConstraints)
-            : that.composingConstraints != null) {
-            return false;
-        }
-        if (validationAppliesTo != that.validationAppliesTo) {
-            return false;
-        }
-        return template != null ? template.equals(that.template) : that.template == null;
-
-    }
-
-    @Override
-    public int hashCode() {
-        return hashCode;
-    }
-
-    /**
-     * generated hashCode on all fields except hashCode
-     */
-    private int computeHashCode() {
-        int result = annotation != null ? annotation.hashCode() : 0;
-        result = 31 * result + (groups != null ? groups.hashCode() : 0);
-        result = 31 * result + (payload != null ? payload.hashCode() : 0);
-        result = 31 * result + (constraintValidatorClasses != null ? constraintValidatorClasses.hashCode() : 0);
-        result = 31 * result + (attributes != null ? attributes.hashCode() : 0);
-        result = 31 * result + (composingConstraints != null ? composingConstraints.hashCode() : 0);
-        result = 31 * result + (reportAsSingleViolation ? 1 : 0);
-        result = 31 * result + (validationAppliesTo != null ? validationAppliesTo.hashCode() : 0);
-        result = 31 * result + (template != null ? template.hashCode() : 0);
-        return result;
-    }
-
-    @Override
-    public ValidateUnwrappedValue getValueUnwrapping() {
-        // TODO Auto-generated method stub
-        return null;
-    }
-
-    @Override
-    public <U> U unwrap(Class<U> arg0) {
-        // TODO Auto-generated method stub
-        return null;
-    }
-}

http://git-wip-us.apache.org/repos/asf/bval/blob/92c64b3c/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java
----------------------------------------------------------------------
diff --git a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java b/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java
deleted file mode 100644
index 57680d7..0000000
--- a/bval-jsr/src/main/java/org/apache/bval/jsr/ConstraintFinderImpl.java
+++ /dev/null
@@ -1,175 +0,0 @@
-/*
- * 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 org.apache.bval.jsr;
-
-import org.apache.bval.jsr.groups.Group;
-import org.apache.bval.jsr.groups.Groups;
-import org.apache.bval.jsr.groups.GroupsComputer;
-import org.apache.bval.model.MetaBean;
-
-import javax.validation.metadata.ConstraintDescriptor;
-import javax.validation.metadata.ElementDescriptor;
-import javax.validation.metadata.ElementDescriptor.ConstraintFinder;
-import javax.validation.metadata.Scope;
-import java.lang.annotation.ElementType;
-import java.util.Arrays;
-import java.util.Collections;
-import java.util.HashSet;
-import java.util.Iterator;
-import java.util.List;
-import java.util.Set;
-
-/**
- * Description: Implementation of the fluent {@link ConstraintFinder} interface.<br/>
- */
-final class ConstraintFinderImpl implements ElementDescriptor.ConstraintFinder {
-    private final MetaBean metaBean;
-    private final Set<Scope> findInScopes;
-    private Set<ConstraintValidation<?>> constraintDescriptors;
-
-    /**
-     * Create a new ConstraintFinderImpl instance.
-     * 
-     * @param metaBean
-     * @param constraintDescriptors
-     */
-    ConstraintFinderImpl(MetaBean metaBean, Set<ConstraintValidation<?>> constraintDescriptors) {
-        this.metaBean = metaBean;
-        this.constraintDescriptors = constraintDescriptors;
-        this.findInScopes = new HashSet<Scope>(Arrays.asList(Scope.values()));
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ElementDescriptor.ConstraintFinder unorderedAndMatchingGroups(Class<?>... groups) {
-        final Set<ConstraintValidation<?>> matchingDescriptors =
-            new HashSet<ConstraintValidation<?>>(constraintDescriptors.size());
-        final Groups groupChain = new GroupsComputer().computeGroups(groups);
-        for (Group group : groupChain.getGroups()) {
-            if (group.isDefault()) {
-                // If group is default, check if it gets redefined
-                for (Group defaultGroupMember : metaBean.<List<Group>> getFeature(JsrFeatures.Bean.GROUP_SEQUENCE)) {
-                    for (ConstraintValidation<?> descriptor : constraintDescriptors) {
-                        if (isInScope(descriptor) && isInGroup(descriptor, defaultGroupMember)) {
-                            matchingDescriptors.add(descriptor);
-                        }
-                    }
-                }
-            } else {
-                for (ConstraintValidation<?> descriptor : constraintDescriptors) {
-                    if (isInScope(descriptor) && isInGroup(descriptor, group)) {
-                        matchingDescriptors.add(descriptor);
-                    }
-                }
-            }
-        }
-        return thisWith(matchingDescriptors);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ElementDescriptor.ConstraintFinder lookingAt(Scope scope) {
-        if (scope == Scope.LOCAL_ELEMENT) {
-            findInScopes.remove(Scope.HIERARCHY);
-            for (Iterator<ConstraintValidation<?>> it = constraintDescriptors.iterator(); it.hasNext();) {
-                if (!it.next().getOwner().equals(metaBean.getBeanClass())) {
-                    it.remove();
-                }
-            }
-        }
-        return this;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public ElementDescriptor.ConstraintFinder declaredOn(ElementType... elementTypes) {
-        final Set<ConstraintValidation<?>> matchingDescriptors =
-            new HashSet<ConstraintValidation<?>>(constraintDescriptors.size());
-        for (ElementType each : elementTypes) {
-            for (ConstraintValidation<?> descriptor : constraintDescriptors) {
-                if (isInScope(descriptor) && isAtElement(descriptor, each)) {
-                    matchingDescriptors.add(descriptor);
-                }
-            }
-        }
-        return thisWith(matchingDescriptors);
-    }
-
-    private boolean isAtElement(ConstraintValidation<?> descriptor, ElementType each) {
-        return descriptor.getAccess().getElementType() == each;
-    }
-
-    private boolean isInScope(ConstraintValidation<?> descriptor) {
-        if (findInScopes.size() == Scope.values().length) {
-            return true; // all scopes
-        }
-        if (metaBean != null) {
-            final boolean isOwner = descriptor.getOwner().equals(metaBean.getBeanClass());
-            for (Scope scope : findInScopes) {
-                switch (scope) {
-                case LOCAL_ELEMENT:
-                    if (isOwner) {
-                        return true;
-                    }
-                    break;
-                case HIERARCHY:
-                    if (!isOwner) {
-                        return true;
-                    }
-                    break;
-                }
-            }
-        }
-        return false;
-    }
-
-    private boolean isInGroup(ConstraintValidation<?> descriptor, Group group) {
-        return descriptor.getGroups().contains(group.getGroup());
-    }
-
-    private ElementDescriptor.ConstraintFinder thisWith(Set<ConstraintValidation<?>> matchingDescriptors) {
-        constraintDescriptors = matchingDescriptors;
-        return this;
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public Set<ConstraintDescriptor<?>> getConstraintDescriptors() {
-        if (constraintDescriptors.isEmpty()) {
-            return Collections.emptySet();
-        }
-        return Collections.<ConstraintDescriptor<?>> unmodifiableSet(constraintDescriptors);
-    }
-
-    /**
-     * {@inheritDoc}
-     */
-    @Override
-    public boolean hasConstraints() {
-        return !constraintDescriptors.isEmpty();
-    }
-}