/*
 * Copyright 2010 Google Inc.
 *
 * Licensed 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.google.gwt.validation.rebind;

import com.google.gwt.core.client.GWT;
import com.google.gwt.core.client.UnsafeNativeLong;
import com.google.gwt.core.ext.Generator;
import com.google.gwt.core.ext.GeneratorContext;
import com.google.gwt.core.ext.TreeLogger;
import com.google.gwt.core.ext.UnableToCompleteException;
import com.google.gwt.core.ext.typeinfo.JClassType;
import com.google.gwt.core.ext.typeinfo.JField;
import com.google.gwt.core.ext.typeinfo.JMethod;
import com.google.gwt.core.ext.typeinfo.JPrimitiveType;
import com.google.gwt.core.ext.typeinfo.JType;
import com.google.gwt.dev.jjs.ast.JBooleanLiteral;
import com.google.gwt.dev.jjs.ast.JCharLiteral;
import com.google.gwt.dev.jjs.ast.JDoubleLiteral;
import com.google.gwt.dev.jjs.ast.JFloatLiteral;
import com.google.gwt.dev.jjs.ast.JIntLiteral;
import com.google.gwt.dev.jjs.ast.JLongLiteral;
import com.google.gwt.thirdparty.guava.common.base.Function;
import com.google.gwt.thirdparty.guava.common.base.Functions;
import com.google.gwt.thirdparty.guava.common.base.Joiner;
import com.google.gwt.thirdparty.guava.common.base.Predicate;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableList;
import com.google.gwt.thirdparty.guava.common.collect.ImmutableSet;
import com.google.gwt.thirdparty.guava.common.collect.Iterables;
import com.google.gwt.thirdparty.guava.common.collect.Maps;
import com.google.gwt.thirdparty.guava.common.collect.Ordering;
import com.google.gwt.thirdparty.guava.common.collect.Sets;
import com.google.gwt.thirdparty.guava.common.primitives.Primitives;
import com.google.gwt.user.rebind.ClassSourceFileComposerFactory;
import com.google.gwt.user.rebind.SourceWriter;
import com.google.gwt.validation.client.impl.AbstractGwtSpecificValidator;
import com.google.gwt.validation.client.impl.ConstraintDescriptorImpl;
import com.google.gwt.validation.client.impl.ConstraintOrigin;
import com.google.gwt.validation.client.impl.Group;
import com.google.gwt.validation.client.impl.GroupChain;
import com.google.gwt.validation.client.impl.GroupChainGenerator;
import com.google.gwt.validation.client.impl.GwtBeanDescriptor;
import com.google.gwt.validation.client.impl.GwtBeanDescriptorImpl;
import com.google.gwt.validation.client.impl.GwtValidationContext;
import com.google.gwt.validation.client.impl.PathImpl;
import com.google.gwt.validation.client.impl.PropertyDescriptorImpl;
import com.google.gwt.validation.client.impl.metadata.BeanMetadata;
import com.google.gwt.validation.client.impl.metadata.ValidationGroupsMetadata;

import java.beans.BeanInfo;
import java.beans.IntrospectionException;
import java.beans.Introspector;
import java.lang.annotation.Annotation;
import java.lang.annotation.ElementType;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
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.Iterator;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;

import javax.validation.Constraint;
import javax.validation.ConstraintValidator;
import javax.validation.ConstraintViolation;
import javax.validation.GroupSequence;
import javax.validation.Path.Node;
import javax.validation.Payload;
import javax.validation.UnexpectedTypeException;
import javax.validation.Valid;
import javax.validation.ValidationException;
import javax.validation.groups.Default;
import javax.validation.metadata.BeanDescriptor;
import javax.validation.metadata.ConstraintDescriptor;
import javax.validation.metadata.PropertyDescriptor;

/**
 * Creates a {@link com.google.gwt.validation.client.impl.GwtSpecificValidator}.
 * <p>
 * This class is not thread safe.
 */
public final class GwtSpecificValidatorCreator extends AbstractCreator {
  private static enum Stage {
    OBJECT, PROPERTY, VALUE
  }

  static final JType[] NO_ARGS = new JType[]{};

  private static final String DEFAULT_VIOLATION_VAR = "violations";

  private static final Annotation[] NO_ANNOTATIONS = new Annotation[]{};

  private static Function<java.beans.PropertyDescriptor, String>
      PROPERTY_DESCRIPTOR_TO_NAME =
          new Function<java.beans.PropertyDescriptor, String>() {
    @Override
    public String apply(java.beans.PropertyDescriptor pd) {
      return pd.getName();
    }
  };

  private static Function<Object, String> TO_LITERAL = new Function<Object, String>() {

    @Override
    public String apply(Object input) {
      return asLiteral(input);
    }
  };

  public static String asGetter(PropertyDescriptor p) {
    return "get" + capitalizeFirstLetter(p.getPropertyName());
  }

  /**
   * Returns the literal value of an object that is suitable for inclusion in
   * Java Source code.
   *
   * <p>
   * Supports all types that {@link Annotation} value can have.
   *
   *
   * @throws IllegalArgumentException if the type of the object does not have a java literal form.
   */
  public static String asLiteral(Object value) throws IllegalArgumentException {
    Class<?> clazz = value.getClass();

    if (clazz.isArray()) {
      StringBuilder sb = new StringBuilder();
      Object[] array = (Object[]) value;

      sb.append("new " + clazz.getComponentType().getCanonicalName() + "[] ");
      sb.append("{");
      boolean first = true;
      for (Object object : array) {
        if (first) {
          first = false;
        } else {
          sb.append(",");
        }
        sb.append(asLiteral(object));
      }
      sb.append("}");
      return sb.toString();
    }

    if (value instanceof Boolean) {
      return JBooleanLiteral.get(((Boolean) value).booleanValue())
          .toSource();
    } else if (value instanceof Byte) {
      return JIntLiteral.get(((Byte) value).byteValue()).toSource();
    } else if (value instanceof Character) {
      return JCharLiteral.get(((Character) value).charValue())
          .toSource();
    } else if (value instanceof Class<?>) {
      return ((Class<?>) ((Class<?>) value)).getCanonicalName() + ".class";
    } else if (value instanceof Double) {
      return JDoubleLiteral.get(((Double) value).doubleValue())
          .toSource();
    } else if (value instanceof Enum) {
      return value.getClass().getCanonicalName() + "."
          + ((Enum<?>) value).name();
    } else if (value instanceof Float) {
      return JFloatLiteral.get(((Float) value).floatValue()).toSource();
    } else if (value instanceof Integer) {
      return JIntLiteral.get(((Integer) value).intValue()).toSource();
    } else if (value instanceof Long) {
      return JLongLiteral.get(((Long) value).longValue()).toSource();
    } else if (value instanceof String) {
      return '"' + Generator.escape((String) value) + '"';
    } else {
      // TODO(nchalko) handle Annotation types
      throw new IllegalArgumentException(value.getClass()
          + " can not be represented as a Java Literal.");
    }
  }

  public static String capitalizeFirstLetter(String propertyName) {
    if (propertyName == null) {
      return null;
    }
    if (propertyName.length() == 0) {
      return "";
    }
    String cap = propertyName.substring(0, 1).toUpperCase(Locale.ROOT);
    if (propertyName.length() > 1) {
      cap += propertyName.substring(1);
    }
    return cap;
  }

  public static boolean isIterableOrMap(Class<?> elementClass) {
    // TODO(nchalko) handle iterables everywhere this is called.
    return elementClass.isArray()
        || Iterable.class.isAssignableFrom(elementClass)
        || Map.class.isAssignableFrom(elementClass);
  }

  /**
   * Finds the type that a constraint validator will check.
   *
   * <p>This type comes from the first parameter of the isValid() method on
   * the constraint validator. However, this is a bit tricky because ConstraintValidator
   * has a parameterized type. When using Java reflection, we will see multiple isValid()
   * methods, including one that checks java.lang.Object.</p>
   *
   * <p>Strategy: for now, assume there are at most two isValid() methods. If there are two,
   * assume one of them has a type that is assignable from the other. (Most likely,
   * one of them will be java.lang.Object.)</p>
   *
   * @throws IllegalStateException if there isn't any isValid() method or there are more than two.
   */
  static <T extends Annotation> Class<?> getTypeOfConstraintValidator(
      Class<? extends ConstraintValidator<T, ?>> constraintClass) {
    
    int candidateCount = 0;
    Class<?> result = null;
    for (Method method :  constraintClass.getMethods()) {
      if (method.getName().equals("isValid")
          && method.getParameterTypes().length == 2
          && method.getReturnType().isAssignableFrom(Boolean.TYPE)) {
        Class<?> firstArgType = method.getParameterTypes()[0];
        if (result == null || result.isAssignableFrom(firstArgType)) {
          result = firstArgType;
        }
        candidateCount++;
      }
    }

    if (candidateCount == 0) {
      throw new IllegalStateException("ConstraintValidators must have a isValid method");
    } else if (candidateCount > 2) {
      throw new IllegalStateException(
          "ConstraintValidators must have no more than two isValid methods");
    }

    return result;
  }

  // Visible for testing
  static <A extends Annotation> ImmutableSet<Class<? extends ConstraintValidator<A, ?>>> getValidatorForType(
      Class<?> type,
      List<Class<? extends ConstraintValidator<A, ?>>> constraintValidatorClasses) {
    type = Primitives.wrap(type);
    Map<Class<?>, Class<? extends ConstraintValidator<A, ?>>> map = Maps.newHashMap();
    for (Class<? extends ConstraintValidator<A, ?>> constraintClass : constraintValidatorClasses) {
      Class<?> aType = Primitives.wrap(getTypeOfConstraintValidator(constraintClass));
      if (aType.isAssignableFrom(type)) {
        map.put(aType, constraintClass);
      }
    }
    // TODO(nchalko) implement per spec
    // Handle Arrays and Generics

    final Set<Class<?>> best = Util.findBestMatches(type, map.keySet());

    Predicate<Class<?>> inBest = new Predicate<Class<?>>() {

      @Override
      public boolean apply(Class<?> key) {
        return best.contains(key);
      }
    };
    return ImmutableSet.copyOf(Maps.filterKeys(map, inBest).values());
  }

  private static ConstraintOrigin convertConstraintOriginEnum(
      org.hibernate.validator.metadata.ConstraintOrigin definedOn) {
    switch (definedOn) {
      case DEFINED_IN_HIERARCHY:
        return ConstraintOrigin.DEFINED_IN_HIERARCHY;
      case DEFINED_LOCALLY:
        return ConstraintOrigin.DEFINED_LOCALLY;
      default:
        throw new IllegalArgumentException("Unable to convert: unknown ConstraintOrigin value");
    }
  }

  /**
   * Gets the best {@link ConstraintValidator}.
   *
   * <p>
   * The ConstraintValidator chosen to validate a declared type
   * {@code targetType} is the one where the type supported by the
   * ConstraintValidator is a supertype of {@code targetType} and where there is
   * no other ConstraintValidator whose supported type is a supertype of
   * {@code type} and not a supertype of the chosen ConstraintValidator
   * supported type.
   *
   * @param constraint the constraint to find ConstraintValidators for.
   * @param targetType The type to find a ConstraintValidator for.
   * @return ConstraintValidator
   *
   * @throws UnexpectedTypeException if there is not exactly one maximally
   *           specific constraint validator for targetType.
   */
  private static <A extends Annotation> Class<? extends ConstraintValidator<A, ?>> getValidatorForType(
      ConstraintDescriptor<A> constraint, Class<?> targetType)
      throws UnexpectedTypeException {
    List<Class<? extends ConstraintValidator<A, ?>>> constraintValidatorClasses
        = constraint.getConstraintValidatorClasses();
    if (constraintValidatorClasses.isEmpty()) {
      throw new UnexpectedTypeException("No ConstraintValidator found for  "
          + constraint.getAnnotation());
    }
    ImmutableSet<Class<? extends ConstraintValidator<A, ?>>> best = getValidatorForType(
        targetType, constraintValidatorClasses);
    if (best.isEmpty()) {
      throw new UnexpectedTypeException("No " + constraint.getAnnotation()
          + " ConstraintValidator for type " + targetType);
    }
    if (best.size() > 1) {
      throw new UnexpectedTypeException("More than one maximally specific "
          + constraint.getAnnotation() + " ConstraintValidator for type "
          + targetType + ", found " + Ordering.usingToString().sortedCopy(best));
    }
    return Iterables.get(best, 0);
  }

  private final BeanHelper beanHelper;

  private final Set<BeanHelper> beansToValidate = Sets.newHashSet();

  private final JClassType beanType;

  private final Set<JField> fieldsToWrap = Sets.newHashSet();

  private Set<JMethod> gettersToWrap = Sets.newHashSet();

  private final Set<Class<?>> validGroups;

  private final Map<ConstraintDescriptor<?>, Boolean> validConstraintsMap = Maps.newHashMap();

  public GwtSpecificValidatorCreator(JClassType validatorType,
      JClassType beanType, BeanHelper beanHelper, TreeLogger logger,
      GeneratorContext context, BeanHelperCache cache, Class<?>[] validGroupsFromAnnotation) {
    super(context, logger, validatorType, cache);
    this.beanType = beanType;
    this.beanHelper = beanHelper;

    Set<Class<?>> tempValidGroups = Sets.newHashSet(validGroupsFromAnnotation);
    tempValidGroups.add(Default.class);
    this.validGroups = Collections.unmodifiableSet(tempValidGroups);
  }

  @Override
  protected void compose(ClassSourceFileComposerFactory composerFactory) {
    addImports(composerFactory, Annotation.class, ConstraintViolation.class,
        GWT.class, ValidationGroupsMetadata.class, Group.class, GroupChain.class, PathImpl.class,
        Node.class, GroupChainGenerator.class, GwtBeanDescriptor.class, BeanMetadata.class, 
        GwtValidationContext.class, ArrayList.class, HashSet.class, IllegalArgumentException.class,
        Set.class, Collection.class, Iterator.class, List.class, ValidationException.class);
    composerFactory.setSuperclass(AbstractGwtSpecificValidator.class.getCanonicalName()
        + "<" + beanType.getQualifiedSourceName() + ">");
    composerFactory.addImplementedInterface(validatorType.getName());
  }

  @Override
  protected void writeClassBody(SourceWriter sw)
      throws UnableToCompleteException {
    writeFields(sw);
    sw.println();
    writeValidateClassGroups(sw);
    sw.println();
    writeExpandDefaultAndValidateClassGroups(sw);
    sw.println();
    writeExpandDefaultAndValidatePropertyGroups(sw);
    sw.println();
    writeExpandDefaultAndValidateValueGroups(sw);
    sw.println();
    writeValidatePropertyGroups(sw);
    sw.println();
    writeValidateValueGroups(sw);
    sw.println();
    writeGetBeanMetadata(sw);
    sw.println();
    writeGetDescriptor(sw);
    sw.println();
    writePropertyValidators(sw);
    sw.println();
    writeValidateAllNonInheritedProperties(sw);
    sw.println();

    // Write the wrappers after we know which are needed
    writeWrappers(sw);
    sw.println();
  }

  protected void writeUnsafeNativeLongIfNeeded(SourceWriter sw, JType jType) {
    if (JPrimitiveType.LONG.equals(jType)) {
      // @com.google.gwt.core.client.UnsafeNativeLong
      sw.print("@");
      sw.println(UnsafeNativeLong.class.getCanonicalName());
    }
  }

  private boolean areConstraintDescriptorGroupsValid(ConstraintDescriptor<?> constraintDescriptor) {
    if (validConstraintsMap.containsKey(constraintDescriptor)) {
      return validConstraintsMap.get(constraintDescriptor);
    } else {
      boolean areValid = checkGroups(constraintDescriptor.getGroups());
      // cache result
      validConstraintsMap.put(constraintDescriptor, areValid);
      return areValid;
    }
  }

  private <T> T[] asArray(Collection<?> collection, T[] array) {
    if (collection == null) {
      return null;
    }
    return collection.toArray(array);
  }

  private boolean checkGroups(Set<Class<?>> groups) {
    for (Class<?> group : groups) {
      if (validGroups.contains(group)) {
        return true;
      }
    }
    return false;
  }

  private String constraintDescriptorVar(String name, int count) {
    String s = name + "_c" + count;
    return s;
  }

  private Annotation getAnnotation(PropertyDescriptor p, boolean useField,
      Class<? extends Annotation> expectedAnnotationClass) {
    Annotation annotation = null;
    if (useField) {
      JField field = beanType.findField(p.getPropertyName());
      if (field.getEnclosingType().equals(beanType)) {
        annotation = field.getAnnotation(expectedAnnotationClass);
      }
    } else {
      JMethod method = beanType.findMethod(asGetter(p), NO_ARGS);
      if (method.getEnclosingType().equals(beanType)) {
        annotation = method.getAnnotation(expectedAnnotationClass);
      }
    }
    return annotation;
  }

  private Annotation[] getAnnotations(PropertyDescriptor p,
      boolean useField) {
    Class<?> clazz = beanHelper.getClazz();
    if (useField) {
      try {
        Field field = clazz.getDeclaredField(p.getPropertyName());
        return field.getAnnotations();
      } catch (NoSuchFieldException ignore) {
        // Expected Case
      }
    } else {
      try {
        Method method = clazz.getMethod(asGetter(p));
        return method.getAnnotations();
      } catch (NoSuchMethodException ignore) {
        // Expected Case
      }
    }
    return NO_ANNOTATIONS;
  }

  private String getQualifiedSourceNonPrimitiveType(JType elementType) {
    JPrimitiveType primitive = elementType.isPrimitive();
    return primitive == null ? elementType.getQualifiedSourceName()
        : primitive.getQualifiedBoxedSourceName();
  }

  private boolean hasMatchingAnnotation(Annotation expectedAnnotation,
      Annotation[] annotations) throws UnableToCompleteException {
    // See spec section 2.2. Applying multiple constraints of the same type
    for (Annotation annotation : annotations) {
      // annotations not annotated by @Constraint
      if (annotation.annotationType().getAnnotation(Constraint.class) == null) {
        try {
          // value element has a return type of an array of constraint
          // annotations
          Method valueMethod = annotation.annotationType().getMethod("value");
          Class<?> valueType = valueMethod.getReturnType();
          if (valueType.isArray()
              && Annotation.class.isAssignableFrom(valueType.getComponentType())) {
            if (Modifier.isAbstract(valueMethod.getModifiers())) {
              // handle edge case where interface is marked "abstract"
              valueMethod.setAccessible(true);
            }
            Annotation[] valueAnnotions = (Annotation[]) valueMethod.invoke(annotation);
            for (Annotation annotation2 : valueAnnotions) {
              if (expectedAnnotation.equals(annotation2)) {
                return true;
              }
            }
          }
        } catch (NoSuchMethodException ignore) {
          // Expected Case.
        } catch (Exception e) {
          throw error(logger, e);
        }
      }
    }
    return false;
  }

  private boolean hasMatchingAnnotation(ConstraintDescriptor<?> constraint)
      throws UnableToCompleteException {
    Annotation expectedAnnotation = constraint.getAnnotation();
    Class<? extends Annotation> expectedAnnotationClass = expectedAnnotation.annotationType();
    if (expectedAnnotation.equals(beanHelper.getClazz().getAnnotation(
        expectedAnnotationClass))) {
      return true;
    }

    // See spec section 2.2. Applying multiple constraints of the same type
    Annotation[] annotations = beanHelper.getClazz().getAnnotations();
    return hasMatchingAnnotation(expectedAnnotation, annotations);
  }

  private boolean hasMatchingAnnotation(PropertyDescriptor p, boolean useField,
      ConstraintDescriptor<?> constraint) throws UnableToCompleteException {
    Annotation expectedAnnotation = constraint.getAnnotation();
    Class<? extends Annotation> expectedAnnotationClass =
        expectedAnnotation.annotationType();
    if (expectedAnnotation.equals(getAnnotation(p, useField,
        expectedAnnotationClass))) {
      return true;
    }
    return hasMatchingAnnotation(expectedAnnotation,
        getAnnotations(p, useField));
  }

  private boolean hasValid(PropertyDescriptor p, boolean useField) {
    return getAnnotation(p, useField, Valid.class) != null;
  }

  private boolean isPropertyConstrained(BeanHelper helper, PropertyDescriptor p) {
    Set<PropertyDescriptor> propertyDescriptors =
        helper.getBeanDescriptor().getConstrainedProperties();
    Predicate<PropertyDescriptor> nameMatches = newPropertyNameMatches(p);
    return Iterables.any(propertyDescriptors, nameMatches);
  }

  private boolean isPropertyConstrained(PropertyDescriptor p, boolean useField) {
    // cascaded counts as constrained
    // we must know if the @Valid annotation is on a field or a getter
    JClassType jClass = beanHelper.getJClass();
    if (useField &&
        jClass.findField(p.getPropertyName()).isAnnotationPresent(Valid.class)) {
      return true;
    } else if (!useField &&
        jClass.findMethod(asGetter(p),NO_ARGS).isAnnotationPresent(Valid.class)) {
      return true;
    }
    // for non-cascaded properties
    for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
      org.hibernate.validator.metadata.ConstraintDescriptorImpl<?> constraintHibernate = 
          (org.hibernate.validator.metadata.ConstraintDescriptorImpl<?>) constraint;
      if (constraintHibernate.getElementType() ==
          (useField ? ElementType.FIELD : ElementType.METHOD)) {
        return true;
      }
    }
    return false;
  }

  private Predicate<PropertyDescriptor> newPropertyNameMatches(
      final PropertyDescriptor p) {
    return new Predicate<PropertyDescriptor>() {
      @Override
      public boolean apply(PropertyDescriptor input) {
        return input.getPropertyName().equals(p.getPropertyName());
      }
    };
  }

  private String toWrapperName(JField field) {
    return "_" + field.getName();
  }

  private String toWrapperName(JMethod method) {
    return "_" + method.getName();
  }

  private String validateMethodFieldName(PropertyDescriptor p) {
    return "validateProperty_" + p.getPropertyName();
  }

  private String validateMethodGetterName(PropertyDescriptor p) {
    return "validateProperty_get" + p.getPropertyName();
  }

  private void writeBeanDescriptor(SourceWriter sw) {
    BeanDescriptor beanDescriptor = beanHelper.getBeanDescriptor();

    // private final GwtBeanDescriptor <MyBean> beanDescriptor =
    sw.print("private final ");
    sw.print(GwtBeanDescriptor.class.getCanonicalName());
    sw.print("<" + beanHelper.getTypeCanonicalName() + ">");
    sw.println(" beanDescriptor = ");
    sw.indent();
    sw.indent();

    // GwtBeanDescriptorImpl.builder(Order.class)
    sw.print(GwtBeanDescriptorImpl.class.getCanonicalName());
    sw.println(".builder(" + beanHelper.getTypeCanonicalName() + ".class)");
    sw.indent();
    sw.indent();

    // .setConstrained(true)
    sw.println(".setConstrained(" + beanDescriptor.isBeanConstrained() + ")");

    int count = 0;
    for (ConstraintDescriptor<?> constraint : beanDescriptor.getConstraintDescriptors()) {
      if (areConstraintDescriptorGroupsValid(constraint)) {
        // .add(c0)
        sw.println(".add(" + constraintDescriptorVar("this", count) + ")");
        count++;
      }
    }

    // .put("myProperty", myProperty_pd)
    for (PropertyDescriptor p : beanDescriptor.getConstrainedProperties()) {
      sw.print(".put(\"");
      sw.print(p.getPropertyName());
      sw.print("\", ");
      sw.print(p.getPropertyName());
      sw.println("_pd)");
    }

    // .setBeanMetadata(beanMetadata)
    sw.println(".setBeanMetadata(beanMetadata)");

    // .build();
    sw.println(".build();");
    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();
  }

  private void writeBeanMetadata(SourceWriter sw) throws UnableToCompleteException {
    // private final BeanMetadata beanMetadata =
    sw.println("private final BeanMetadata beanMetadata =");
    sw.indent();
    sw.indent();

    // new BeanMetadata(
    sw.println("new " + BeanMetadata.class.getSimpleName() + "(");
    sw.indent();
    sw.indent();

    // <<bean class>>, <<default group seq class 1>>, <<default group seq class 2>>, ...
    Class<?> beanClazz = beanHelper.getClazz();
    sw.print(asLiteral(beanClazz));
    GroupSequence groupSeqAnnotation = beanClazz.getAnnotation(GroupSequence.class);
    List<Class<?>> groupSequence = new ArrayList<Class<?>>();
    if (groupSeqAnnotation == null) {
      groupSequence.add(beanClazz);
    } else {
      groupSequence.addAll(Arrays.asList(groupSeqAnnotation.value()));
    }
    boolean groupSequenceContainsDefault = false;
    for (Class<?> group : groupSequence) {
      sw.println(",");
      if (group.getName().equals(beanClazz.getName())) {
        sw.print(asLiteral(Default.class));
        groupSequenceContainsDefault = true;
      }
      else if (group.getName().equals(Default.class.getName())) {
        throw error(logger, "'Default.class' cannot appear in default group sequence list.");
      }
      else {
        sw.print(asLiteral(group));
      }
    }
    if (!groupSequenceContainsDefault) {
      throw error(logger, beanClazz.getName() + " must be part of the redefined default group " +
          "sequence.");
    }

    sw.println(");");
    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();
  }

  private void writeClassLevelConstraintsValidation(SourceWriter sw, String groupsVarName)
      throws UnableToCompleteException {
    // all class level constraints
    int count = 0;
    Class<?> clazz = beanHelper.getClazz();
    for (ConstraintDescriptor<?> constraint : beanHelper.getBeanDescriptor().getConstraintDescriptors()) {
      if (areConstraintDescriptorGroupsValid(constraint)) {
        if (hasMatchingAnnotation(constraint)) {

          if (!constraint.getConstraintValidatorClasses().isEmpty()) {
            Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass =
                getValidatorForType(constraint, clazz);
  
            // validate(context, violations, null, object,
            sw.print("validate(context, violations, null, object, ");
  
            // new MyValidtor(),
            sw.print("new ");
            sw.print(validatorClass.getCanonicalName());
            sw.print("(), "); // TODO(nchalko) use ConstraintValidatorFactory
  
            // this.aConstraintDescriptor, groups);
            sw.print(constraintDescriptorVar("this", count));
            sw.print(", ");
            sw.print(groupsVarName);
            sw.println(");");
          } else if (constraint.getComposingConstraints().isEmpty()) {
            // TODO(nchalko) What does the spec say to do here.
            logger.log(TreeLogger.WARN, "No ConstraintValidator of " + constraint
                + " for type " + clazz);
          }
          // TODO(nchalko) handle constraint.isReportAsSingleViolation() and
          // hasComposingConstraints
        }
        count++;
      }
    }
  }

  private void writeConstraintDescriptor(SourceWriter sw,
      ConstraintDescriptor<? extends Annotation> constraint,
      ElementType elementType,
      ConstraintOrigin origin,
      String constraintDescripotorVar) throws UnableToCompleteException {
    Class<? extends Annotation> annotationType =
        constraint.getAnnotation().annotationType();

    // First list all composing constraints
    int count = 0;
    for (ConstraintDescriptor<?> composingConstraint :
        constraint.getComposingConstraints()) {
      writeConstraintDescriptor(sw, composingConstraint, elementType, origin,
          constraintDescripotorVar + "_" + count++);
    }

    // private final ConstraintDescriptorImpl<MyAnnotation> constraintDescriptor = ;
    sw.print("private final ");
    sw.print(ConstraintDescriptorImpl.class.getCanonicalName());
    sw.print("<");

    sw.print(annotationType.getCanonicalName());
    sw.print(">");

    sw.println(" " + constraintDescripotorVar + "  = ");
    sw.indent();
    sw.indent();

    // ConstraintDescriptorImpl.<MyConstraint> builder()
    sw.print(ConstraintDescriptorImpl.class.getCanonicalName());
    sw.print(".<");

    sw.print(annotationType.getCanonicalName());
    sw.println("> builder()");
    sw.indent();
    sw.indent();

    // .setAnnotation(new MyAnnotation )
    sw.println(".setAnnotation( ");
    sw.indent();
    sw.indent();
    writeNewAnnotation(sw, constraint);
    sw.println(")");
    sw.outdent();
    sw.outdent();

    // .setAttributes(builder()
    sw.println(".setAttributes(attributeBuilder()");
    sw.indent();

    for (Map.Entry<String, Object> entry :
        constraint.getAttributes().entrySet()) {
      // .put(key, value)
      sw.print(".put(");
      String key = entry.getKey();
      sw.print(asLiteral(key));
      sw.print(", ");
      Object value = entry.getValue();
      // Add the Default group if it is not already present
      if ("groups".equals(key) && value instanceof Class[] && ((Class[])value).length == 0) {
        value = new Class[] { Default.class };
      }
      sw.print(asLiteral(value));
      sw.println(")");
    }

    // .build())
    sw.println(".build())");
    sw.outdent();

    // .setConstraintValidatorClasses(classes )
    sw.print(".setConstraintValidatorClasses(");
    sw.print(asLiteral(asArray(constraint.getConstraintValidatorClasses(),
        new Class[0])));
    sw.println(")");

    int ccCount = constraint.getComposingConstraints().size();
    for (int i = 0; i < ccCount; i++) {
      // .addComposingConstraint(cX_X)
      sw.print(".addComposingConstraint(");
      sw.print(constraintDescripotorVar + "_" + i);
      sw.println(")");
    }

    // .getGroups(groups)
    sw.print(".setGroups(");
    Set<Class<?>> groups = constraint.getGroups();
    sw.print(asLiteral(asArray(groups, new Class<?>[0])));
    sw.println(")");

    // .setPayload(payload)
    sw.print(".setPayload(");
    Set<Class<? extends Payload>> payload = constraint.getPayload();
    sw.print(asLiteral(asArray(payload, new Class[0])));
    sw.println(")");

    // .setReportAsSingleViolation(boolean )
    sw.print(".setReportAsSingleViolation(");
    sw.print(Boolean.valueOf(constraint.isReportAsSingleViolation())
        .toString());
    sw.println(")");

    // .setElementType(elementType)
    sw.print(".setElementType(");
    sw.print(asLiteral(elementType));
    sw.println(")");

    // .setDefinedOn(origin)
    sw.print(".setDefinedOn(");
    sw.print(asLiteral(origin));
    sw.println(")");

    // .build();
    sw.println(".build();");
    sw.outdent();
    sw.outdent();

    sw.outdent();
    sw.outdent();
    sw.println();
  }

  private void writeExpandDefaultAndValidate(SourceWriter sw, Stage stage) throws UnableToCompleteException {
    Class<?> clazz = beanHelper.getClazz();

    // ArrayList<Class<?>> justGroups = new ArrayList<Class<?>>();
    sw.println("ArrayList<Class<?>> justGroups = new ArrayList<Class<?>>();");

    // for (Group g : groups) {
    sw.println("for (Group g : groups) {");
    sw.indent();
    //  if (!g.isDefaultGroup() || !getBeanMetadata().defaultGroupSequenceIsRedefined()) {
    sw.println("if (!g.isDefaultGroup() || !getBeanMetadata().defaultGroupSequenceIsRedefined()) {");
    sw.indent();
    // justGroups.add(g.getGroup());
    sw.println("justGroups.add(g.getGroup());");
    sw.outdent();
    // }
    sw.println("}");
    sw.outdent();
    // }
    sw.println("}");

    // Class<?>[] justGroupsArray = justGroups.toArray(new Class<?>[justGroups.size()]);
    sw.println("Class<?>[] justGroupsArray = justGroups.toArray(new Class<?>[justGroups.size()]);");

    switch (stage) {
      case OBJECT:
        // validateAllNonInheritedProperties(context, object, violations, justGroupsArray);
        sw.println("validateAllNonInheritedProperties(context, object, violations, " +
            "justGroupsArray);");
        writeClassLevelConstraintsValidation(sw, "justGroupsArray");
        break;
      case PROPERTY:
        // validatePropertyGroups(context, object, propertyName, violations, justGroupsArray);
        sw.println("validatePropertyGroups(context, object, propertyName, violations, " +
            "justGroupsArray);");
        break;
      case VALUE:
        // validateValueGroups(context, beanType, propertyName, value, violations,
        //     justGroupsArray);
        sw.println("validateValueGroups(context, beanType, propertyName, value, violations, " +
            "justGroupsArray);");
        break;
      default:
        throw new IllegalStateException();
    }

    // if (getBeanMetadata().defaultGroupSequenceIsRedefined()) {
    sw.println("if (getBeanMetadata().defaultGroupSequenceIsRedefined()) {");
    sw.indent();
    // for (Class<?> g : beanMetadata.getDefaultGroupSequence()) {
    sw.println("for (Class<?> g : beanMetadata.getDefaultGroupSequence()) {");
    sw.indent();
    // int numberOfViolations = violations.size();
    sw.println("int numberOfViolations = violations.size();");

    switch (stage) {
      case OBJECT:
        // validateAllNonInheritedProperties(context, object, violations, g);
        sw.println("validateAllNonInheritedProperties(context, object, violations, g);");
        writeClassLevelConstraintsValidation(sw, "g");
        // validate super classes and super interfaces
        writeValidateInheritance(sw, clazz, Stage.OBJECT, null, false, "g");
        break;
      case PROPERTY:
        // validatePropertyGroups(context, object, propertyName, violations, g);
        sw.println("validatePropertyGroups(context, object, propertyName, violations, g);");
        break;
      case VALUE:
        // validateValueGroups(context, beanType, propertyName, value, violations, g);
        sw.println("validateValueGroups(context, beanType, propertyName, value, violations, g);");
        break;
      default:
        throw new IllegalStateException();
    }

    // if (violations.size() > numberOfViolations) {
    sw.println("if (violations.size() > numberOfViolations) {");
    sw.indent();
    // break;
    sw.println("break;");
    sw.outdent();
    // }
    sw.println("}");
    sw.outdent();
    // }
    sw.println("}");
    sw.outdent();
    // }
    sw.println("}");
    if (stage == Stage.OBJECT) {
      // else {
      sw.println("else {");
      sw.indent();

      // validate super classes and super interfaces
      writeValidateInheritance(sw, clazz, Stage.OBJECT, null, true, "groups");

      // }
      sw.outdent();
      sw.println("}");
    }
  }

  private void writeExpandDefaultAndValidateClassGroups(SourceWriter sw) throws UnableToCompleteException {
    // public <T> void expandDefaultAndValidateClassGroups(
    sw.println("public <T> void expandDefaultAndValidateClassGroups(");

    // GwtValidationContext<T> context, BeanType object,
    // Set<ConstraintViolation<T>> violations, Group... groups) {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Group... groups) {");
    sw.outdent();

    writeExpandDefaultAndValidate(sw, Stage.OBJECT);

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeExpandDefaultAndValidatePropertyGroups(SourceWriter sw) throws UnableToCompleteException {
    // public <T> void expandDefaultAndValidatePropertyGroups(
    sw.println("public <T> void expandDefaultAndValidatePropertyGroups(");

    // GwtValidationContext<T> context, BeanType object, String propertyName,
    // Set<ConstraintViolation<T>> violations, Group... groups) {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    sw.println("String propertyName,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Group... groups) {");
    sw.outdent();

    writeExpandDefaultAndValidate(sw, Stage.PROPERTY);

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeExpandDefaultAndValidateValueGroups(SourceWriter sw) throws UnableToCompleteException {
    // public <T> void expandDefaultAndValidateValueGroups(
    sw.println("public <T> void expandDefaultAndValidateValueGroups(");

    // GwtValidationContext<T> context, Class<Author> beanType, String propertyName,
    // Object value, Set<ConstraintViolation<T>> violations, Group... groups) {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println("Class<" + beanHelper.getTypeCanonicalName() + "> beanType,");
    sw.println("String propertyName,");
    sw.println("Object value,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Group... groups) {");
    sw.outdent();

    writeExpandDefaultAndValidate(sw, Stage.VALUE);

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeFields(SourceWriter sw) throws UnableToCompleteException {

    // Create a static array of all valid property names.
    BeanInfo beanInfo;
    try {
      beanInfo = Introspector.getBeanInfo(beanHelper.getClazz());
    } catch (IntrospectionException e) {
      throw error(logger, e);
    }

    // private static final java.util.List<String> ALL_PROPERTY_NAMES =
    sw.println("private static final java.util.List<String> ALL_PROPERTY_NAMES = ");
    sw.indent();
    sw.indent();

    // Collections.<String>unmodifiableList(
    sw.println("java.util.Collections.<String>unmodifiableList(");
    sw.indent();
    sw.indent();

    // java.util.Arrays.<String>asList(
    sw.print("java.util.Arrays.<String>asList(");

    // "foo","bar" );
    sw.print(Joiner.on(",").join(
        Iterables.transform(
            ImmutableList.copyOf(beanInfo.getPropertyDescriptors()),
            Functions.compose(TO_LITERAL, PROPERTY_DESCRIPTOR_TO_NAME))));
    sw.println("));");
    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();

    // Write the metadata for the bean
    writeBeanMetadata(sw);
    sw.println();

    // Create a variable for each constraint of each property
    for (PropertyDescriptor p :
         beanHelper.getBeanDescriptor().getConstrainedProperties()) {
      int count = 0;
      for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
        org.hibernate.validator.metadata.ConstraintDescriptorImpl<?> constraintHibernate = 
            (org.hibernate.validator.metadata.ConstraintDescriptorImpl<?>) constraint;
        if (areConstraintDescriptorGroupsValid(constraint)) {
          writeConstraintDescriptor(sw, constraint, constraintHibernate.getElementType(),
              convertConstraintOriginEnum(constraintHibernate.getDefinedOn()),
              constraintDescriptorVar(p.getPropertyName(), count++));
        }
      }
      writePropertyDescriptor(sw, p);
      if (p.isCascaded()) {
        beansToValidate.add(isIterableOrMap(p.getElementClass())
            ? createBeanHelper(beanHelper.getAssociationType(p, true))
            : createBeanHelper(p.getElementClass()));
      }
    }

    // Create a variable for each constraint of this class.
    int count = 0;
    for (ConstraintDescriptor<?> constraint :
        beanHelper.getBeanDescriptor().getConstraintDescriptors()) {
      org.hibernate.validator.metadata.ConstraintDescriptorImpl<?> constraintHibernate =
          (org.hibernate.validator.metadata.ConstraintDescriptorImpl<?>) constraint;
      if (areConstraintDescriptorGroupsValid(constraint)) {
        writeConstraintDescriptor(sw, constraint, ElementType.TYPE,
            convertConstraintOriginEnum(constraintHibernate.getDefinedOn()),
            constraintDescriptorVar("this", count++));
      }
    }

    // Now write the BeanDescriptor after we already have the
    // PropertyDescriptors and class constraints
    writeBeanDescriptor(sw);
    sw.println();
  }

  private void writeFieldWrapperMethod(SourceWriter sw, JField field) {
    writeUnsafeNativeLongIfNeeded(sw, field.getType());

    // private native fieldType _fieldName(com.example.Bean object) /*-{
    sw.print("private native ");

    sw.print(field.getType().getQualifiedSourceName());
    sw.print(" ");
    sw.print(toWrapperName(field));
    sw.print("(");
    sw.print(field.getEnclosingType().getQualifiedSourceName());
    sw.println(" object) /*-{");
    sw.indent();

    // return object.@com.examples.Bean::myMethod();
    sw.print("return object.@");
    sw.print(field.getEnclosingType().getQualifiedSourceName());
    sw.print("::" + field.getName());
    sw.println(";");

    // }-*/;
    sw.outdent();
    sw.println("}-*/;");
  }

  private void writeGetBeanMetadata(SourceWriter sw) {
    // public BeanMetadata getBeanMetadata() {
    sw.println("public BeanMetadata getBeanMetadata() {");
    sw.indent();

    // return beanMetadata;
    sw.println("return beanMetadata;");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeGetDescriptor(SourceWriter sw) {
    // public GwtBeanDescriptor<beanType>
    //     getConstraints(ValidationGroupsMetadata validationGroupsMetadata) {
    sw.print("public ");
    sw.print("GwtBeanDescriptor<" + beanHelper.getTypeCanonicalName() + "> ");
    sw.println("getConstraints(ValidationGroupsMetadata validationGroupsMetadata) {");
    sw.indent();

    // beanDescriptor.setValidationGroupsMetadata(validationGroupsMetadata);
    sw.println("beanDescriptor.setValidationGroupsMetadata(validationGroupsMetadata);");

    // return beanDescriptor;
    sw.println("return beanDescriptor;");

    sw.outdent();
    sw.println("}");
  }

  private void writeGetterWrapperMethod(SourceWriter sw, JMethod method) {
    writeUnsafeNativeLongIfNeeded(sw, method.getReturnType());

    // private native fieldType _getter(Bean object) /*={
    sw.print("private native ");
    sw.print(method.getReturnType().getQualifiedSourceName());
    sw.print(" ");
    sw.print(toWrapperName(method));
    sw.print("(");
    sw.print(beanType.getName());
    sw.println(" object) /*-{");
    sw.indent();

    // return object.@com.examples.Bean::myMethod()();
    sw.print("return object.");
    sw.print(method.getJsniSignature());
    sw.println("();");

    // }-*/;
    sw.outdent();
    sw.println("}-*/;");
  }

  private void writeIfPropertyNameNotFound(SourceWriter sw) {
    // if (!ALL_PROPERTY_NAMES.contains(propertyName)) {
    sw.println(" if (!ALL_PROPERTY_NAMES.contains(propertyName)) {");
    sw.indent();

    // throw new IllegalArgumentException(propertyName
    // +"is not a valid property of myClass");
    sw.print("throw new ");
    sw.print(IllegalArgumentException.class.getCanonicalName());
    sw.print("( propertyName +\" is not a valid property of ");
    sw.print(beanType.getQualifiedSourceName());
    sw.println("\");");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeNewAnnotation(SourceWriter sw,
      ConstraintDescriptor<? extends Annotation> constraint)
      throws UnableToCompleteException {
    Annotation annotation = constraint.getAnnotation();
    Class<? extends Annotation> annotationType = annotation.annotationType();

    // new MyAnnotation () {
    sw.print("new ");
    sw.print(annotationType.getCanonicalName());
    sw.println("(){");
    sw.indent();
    sw.indent();

    // public Class<? extends Annotation> annotationType() { return
    // MyAnnotation.class; }
    sw.print("public Class<? extends Annotation> annotationType() {  return ");
    sw.print(annotationType.getCanonicalName());
    sw.println(".class; }");

    for (Method method : annotationType.getMethods()) {
      // method.isAbstract would be better
      if (method.getDeclaringClass().equals(annotation.annotationType())) {
        // public returnType method() { return value ;}
        sw.print("public ");
        sw.print(method.getReturnType().getCanonicalName()); // TODO handle
                                                             // generics
        sw.print(" ");
        sw.print(method.getName());
        sw.print("() { return ");

        try {
          Object value = method.invoke(annotation);
          sw.print(asLiteral(value));
        } catch (IllegalArgumentException e) {
          throw error(logger, e);
        } catch (IllegalAccessException e) {
          throw error(logger, e);
        } catch (InvocationTargetException e) {
          throw error(logger, e);
        }
        sw.println(";}");
      }
    }

    sw.outdent();
    sw.outdent();
    sw.println("}");
  }

  private void writeNewViolations(SourceWriter sw, String violationName) {
    // Set<ConstraintViolation<T>> violations =
    sw.print("Set<ConstraintViolation<T>> ");
    sw.print(violationName);
    sw.println(" = ");
    sw.indent();
    sw.indent();

    // new HashSet<ConstraintViolation<T>>();
    sw.println("new HashSet<ConstraintViolation<T>>();");
    sw.outdent();
    sw.outdent();
  }

  /**
   * @param sw
   * @param p
   */
  private void writePropertyDescriptor(SourceWriter sw, PropertyDescriptor p) {
    // private final PropertyDescriptor myProperty_pd =
    sw.print("private final ");
    sw.print(PropertyDescriptorImpl.class.getCanonicalName());
    sw.print(" ");
    sw.print(p.getPropertyName());
    sw.println("_pd =");
    sw.indent();
    sw.indent();

    // new PropertyDescriptorImpl(
    sw.println("new " + PropertyDescriptorImpl.class.getCanonicalName() + "(");
    sw.indent();
    sw.indent();

    // "myProperty",
    sw.println("\"" + p.getPropertyName() + "\",");

    // MyType.class,
    sw.println(p.getElementClass().getCanonicalName() + ".class,");

    // isCascaded,
    sw.print(Boolean.toString(p.isCascaded()) + ",");

    // beanMetadata,
    sw.print("beanMetadata");

    // myProperty_c0,
    // myProperty_c1 );
    int count = 0;
    for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
      if (areConstraintDescriptorGroupsValid(constraint)) {
        sw.println(","); // Print the , for the previous line
        sw.print(constraintDescriptorVar(p.getPropertyName(), count));
        count++;
      }
    }
    sw.println(");");

    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();
  }

  private void writePropertyValidators(SourceWriter sw)
      throws UnableToCompleteException {
    for (PropertyDescriptor p :
        beanHelper.getBeanDescriptor().getConstrainedProperties()) {
      if (beanHelper.hasField(p)) {
        writeValidatePropertyMethod(sw, p, true);
        sw.println();
      }
      if (beanHelper.hasGetter(p)) {
        writeValidatePropertyMethod(sw, p, false);
        sw.println();
      }
    }
  }

  private void writeValidateAllNonInheritedProperties(SourceWriter sw) {
    // private <T> void validateAllNonInheritedProperties(
    sw.println("private <T> void validateAllNonInheritedProperties(");
    sw.indent();
    sw.indent();

    // GwtValidationContext<T> context, BeanType object,
    // Set<ConstraintViolation<T>> violations, Class<?>... groups) {
    sw.println("GwtValidationContext<T> context,");
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Class<?>... groups) {");
    sw.outdent();

    for (PropertyDescriptor p : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
      writeValidatePropertyCall(sw, p, false, true);
    }

    sw.outdent();
    sw.println("}");
  }

  private void writeValidateClassGroups(SourceWriter sw) throws UnableToCompleteException {
    // public <T> void validateClassGroups(
    sw.println("public <T> void validateClassGroups(");

    // GwtValidationContext<T> context, BeanType object,
    // Set<ConstraintViolation<T>> violations, Group... groups) {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Class<?>... groups) {");
    sw.outdent();

    // /// For each group

    // TODO(nchalko) handle the sequence in the AbstractValidator

    // See JSR 303 section 3.5
    // all reachable fields
    // all reachable getters (both) at once
    // including all reachable and cascadable associations

    sw.println("validateAllNonInheritedProperties(context, object, violations, groups);");

    // validate super classes and super interfaces
    writeValidateInheritance(sw, beanHelper.getClazz(), Stage.OBJECT, null, false, "groups");

    writeClassLevelConstraintsValidation(sw, "groups");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidateConstraint(SourceWriter sw, PropertyDescriptor p,
      Class<?> elementClass, ConstraintDescriptor<?> constraint,
      String constraintDescriptorVar) throws UnableToCompleteException {
    writeValidateConstraint(sw, p, elementClass, constraint,
        constraintDescriptorVar, DEFAULT_VIOLATION_VAR);
  }

  /**
   * Writes the call to actually validate a constraint, including its composite
   * constraints.
   * <p>
   * If the constraint is annotated as
   * {@link javax.validation.ReportAsSingleViolation ReportAsSingleViolation},
   * then is called recursively and the {@code violationsVar} is changed to
   * match the {@code constraintDescriptorVar}.
   *
   * @param sw the Source Writer
   * @param p the property
   * @param elementClass The class of the Element
   * @param constraint the constraint to validate.
   * @param constraintDescriptorVar the name of the constraintDescriptor
   *          variable.
   * @param violationsVar the name of the variable to hold violations
   * @throws UnableToCompleteException
   */
  private void writeValidateConstraint(SourceWriter sw, PropertyDescriptor p,
      Class<?> elementClass, ConstraintDescriptor<?> constraint,
      String constraintDescriptorVar, String violationsVar)
      throws UnableToCompleteException {
    boolean isComposite = !constraint.getComposingConstraints().isEmpty();
    boolean firstReportAsSingleViolation =
        constraint.isReportAsSingleViolation()
        && violationsVar.equals(DEFAULT_VIOLATION_VAR) && isComposite;
    boolean reportAsSingleViolation = firstReportAsSingleViolation
        || !violationsVar.equals(DEFAULT_VIOLATION_VAR);
    boolean hasValidator = !constraint.getConstraintValidatorClasses()
        .isEmpty();
    String compositeViolationsVar = constraintDescriptorVar + "_violations";

    // Only do this the first time in a constraint composition.
    if (firstReportAsSingleViolation) {
      // Report myConstraint as Single Violation
      sw.print("// Report ");
      sw.print(constraint.getAnnotation().annotationType().getCanonicalName());
      sw.println(" as Single Violation");
      writeNewViolations(sw, compositeViolationsVar);
    }

    if (hasValidator) {
      Class<? extends ConstraintValidator<? extends Annotation, ?>> validatorClass;
      try {
        validatorClass = getValidatorForType(constraint, elementClass);
      } catch (UnexpectedTypeException e) {
        throw error(logger, e);
      }

      if (firstReportAsSingleViolation) {
        // if (!
        sw.println("if (!");
        sw.indent();
        sw.indent();
      }

      // validate(myContext, violations object, value, new MyValidator(),
      // constraintDescriptor, groups));
      sw.print("validate(myContext, ");
      sw.print(violationsVar);
      sw.print(", object, value, ");
      sw.print("new ");
      sw.print(validatorClass.getCanonicalName());
      sw.print("(), ");
      sw.print(constraintDescriptorVar);
      sw.print(", groups)");
      if (firstReportAsSingleViolation) {
        // ) {
        sw.println(") {");
        sw.outdent();

      } else if (!reportAsSingleViolation) {
        // ;
        sw.println(";");
      } else if (isComposite) {
        // ||
        sw.println(" ||");
      }
    } else if (!isComposite) {
      // TODO(nchalko) What does the spec say to do here.
      logger.log(TreeLogger.WARN, "No ConstraintValidator of " + constraint + " for "
          + p.getPropertyName() + " of type " + elementClass);
    }

    if (firstReportAsSingleViolation) {
      // if (
      sw.print("if (");
      sw.indent();
      sw.indent();
    }
    int count = 0;

    for (ConstraintDescriptor<?> compositeConstraint : constraint
        .getComposingConstraints()) {
      String compositeVar = constraintDescriptorVar + "_" + count++;
      writeValidateConstraint(sw, p, elementClass, compositeConstraint,
          compositeVar, firstReportAsSingleViolation ? compositeViolationsVar
              : violationsVar);
      if (!reportAsSingleViolation) {
        // ;
        sw.println(";");
      } else {
        // ||
        sw.println(" ||");
      }
    }
    if (isComposite && reportAsSingleViolation) {
      // false
      sw.print("false");
    }
    if (firstReportAsSingleViolation) {
      // ) {
      sw.println(" ) {");
      sw.outdent();

      // addSingleViolation(myContext, violations, object, value,
      // constraintDescriptor);
      sw.print("addSingleViolation(myContext, violations, object, value, ");
      sw.print(constraintDescriptorVar);
      sw.println(");");

      // }
      sw.outdent();
      sw.println("}");

      if (hasValidator) {
        // }
        sw.outdent();
        sw.println("}");
      }
    }
  }

  private void writeValidateFieldCall(SourceWriter sw, PropertyDescriptor p,
      boolean useValue, boolean honorValid) {
    String propertyName = p.getPropertyName();

    // validateProperty_<<field>>(context,
    sw.print(validateMethodFieldName(p));
    sw.print("(context, ");
    sw.print("violations, ");

    // null, (MyType) value,
    // or
    // object, object.getLastName(),
    if (useValue) {
      sw.print("null, ");
      sw.print("(");
      sw.print(getQualifiedSourceNonPrimitiveType(beanHelper.getElementType(p,
          true)));
      sw.print(") value");
    } else {
      sw.print("object, ");
      JField field = beanType.getField(propertyName);
      if (field.isPublic()) {
        sw.print("object.");
        sw.print(propertyName);
      } else {
        fieldsToWrap.add(field);
        sw.print(toWrapperName(field) + "(object)");
      }
    }
    sw.print(", ");

    // honorValid, groups);
    sw.print(Boolean.toString(honorValid));
    sw.println(", groups);");
  }

  private void writeValidateGetterCall(SourceWriter sw, PropertyDescriptor p,
      boolean useValue, boolean honorValid) {
    // validateProperty_get<<field>>(context, violations,
    sw.print(validateMethodGetterName(p));
    sw.print("(context, ");
    sw.print("violations, ");

    // object, object.getMyProp(),
    // or
    // null, (MyType) value,
    if (useValue) {
      sw.print("null, ");
      sw.print("(");
      sw.print(getQualifiedSourceNonPrimitiveType(beanHelper.getElementType(p,
          false)));
      sw.print(") value");
    } else {
      sw.print("object, ");
      JMethod method = beanType.findMethod(asGetter(p), NO_ARGS);
      if (method.isPublic()) {
        sw.print("object.");
        sw.print(asGetter(p));
        sw.print("()");
      } else {
        gettersToWrap.add(method);
        sw.print(toWrapperName(method) + "(object)");
      }
    }
    sw.print(", ");

    // honorValid, groups);
    sw.print(Boolean.toString(honorValid));
    sw.println(", groups);");
  }

  private void writeValidateInheritance(SourceWriter sw, Class<?> clazz, Stage stage,
      PropertyDescriptor property) throws UnableToCompleteException {
    writeValidateInheritance(sw, clazz, stage, property, false, "groups");
  }

  private void writeValidateInheritance(SourceWriter sw, Class<?> clazz, Stage stage,
      PropertyDescriptor property, boolean expandDefaultGroupSequence, String groupsVarName)
      throws UnableToCompleteException {
    writeValidateInterfaces(sw, clazz, stage, property, expandDefaultGroupSequence, groupsVarName);
    Class<?> superClass = clazz.getSuperclass();
    if (superClass != null) {
      writeValidatorCall(sw, superClass, stage, property, expandDefaultGroupSequence, groupsVarName);
    }
  }

  private void writeValidateInterfaces(SourceWriter sw, Class<?> clazz,
      Stage stage, PropertyDescriptor p, boolean expandDefaultGroupSequence, String groupsVarName)
      throws UnableToCompleteException {
    for (Class<?> type : clazz.getInterfaces()) {
      writeValidatorCall(sw, type, stage, p, expandDefaultGroupSequence, groupsVarName);
      writeValidateInterfaces(sw, type, stage, p, expandDefaultGroupSequence, groupsVarName);
    }
  }

  private void writeValidateIterable(SourceWriter sw, PropertyDescriptor p) {
    // int i = 0;
    sw.println("int i = 0;");

    // for (Object instance : value) {
    sw.println("for(Object instance : value) {");
    sw.indent();

    // if(instance != null && !context.alreadyValidated(instance)) {
    sw.println(" if(instance != null  && !context.alreadyValidated(instance)) {");
    sw.indent();

    // violations.addAll(
    sw.println("violations.addAll(");
    sw.indent();
    sw.indent();

    // context.getValidator().validate(
    sw.println("context.getValidator().validate(");
    sw.indent();
    sw.indent();

    Class<?> elementClass = p.getElementClass();
    if (elementClass.isArray() || List.class.isAssignableFrom(elementClass)) {
      // context.appendIndex("myProperty",i++),
      sw.print("context.appendIndex(\"");
      sw.print(p.getPropertyName());
      sw.println("\",i),");
    } else {
      // context.appendIterable("myProperty"),
      sw.print("context.appendIterable(\"");
      sw.print(p.getPropertyName());
      sw.println("\"),");
    }

    // instance, groups));
    sw.println("instance, groups));");
    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");

    // i++;
    sw.println("i++;");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidateMap(SourceWriter sw, PropertyDescriptor p) {
    // for (Entry<?, Type> entry : value.entrySet()) {
    sw.print("for(");
    sw.print(Entry.class.getCanonicalName());
    sw.println("<?, ?> entry : value.entrySet()) {");
    sw.indent();

    // if(entry.getValue() != null &&
    // !context.alreadyValidated(entry.getValue())) {
    sw.println(" if(entry.getValue() != null && !context.alreadyValidated(entry.getValue())) {");
    sw.indent();

    // violations.addAll(
    sw.println("violations.addAll(");
    sw.indent();
    sw.indent();

    // context.getValidator().validate(
    sw.println("context.getValidator().validate(");
    sw.indent();
    sw.indent();

    // context.appendKey("myProperty",entry.getKey()),
    sw.print("context.appendKey(\"");
    sw.print(p.getPropertyName());
    sw.println("\",entry.getKey()),");

    // entry.getValue(), groups));
    sw.println("entry.getValue(), groups));");
    sw.outdent();
    sw.outdent();
    sw.outdent();
    sw.outdent();

    // }
    sw.outdent();
    sw.println("}");

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidatePropertyCall(SourceWriter sw,
      PropertyDescriptor property, boolean useValue, boolean honorValid) {
    if (useValue) {
      // boolean valueTypeMatches = false;
      sw.println("boolean valueTypeMatches = false;");
    }
    if (beanHelper.hasGetter(property)) {
      if (useValue) {
        // if ( value == null || value instanceof propertyType) {
        sw.print("if ( value == null || value instanceof ");
        sw.print(getQualifiedSourceNonPrimitiveType(beanHelper.getElementType(
            property, false)));
        sw.println(") {");
        sw.indent();

        // valueTypeMatches = true;
        sw.println("valueTypeMatches = true;");
      }
      // validate_getMyProperty
      writeValidateGetterCall(sw, property, useValue, honorValid);
      if (useValue) {
        // }
        sw.outdent();
        sw.println("}");
      }
    }

    if (beanHelper.hasField(property)) {
      if (useValue) {
        // if ( value == null || value instanceof propertyType) {
        sw.print("if ( value == null || value instanceof ");
        sw.print(getQualifiedSourceNonPrimitiveType(beanHelper.getElementType(
            property, true)));
        sw.println(") {");
        sw.indent();

        // valueTypeMatches = true;
        sw.println("valueTypeMatches = true;");
      }
      // validate_myProperty
      writeValidateFieldCall(sw, property, useValue, honorValid);
      if (useValue) {
        // } else
        sw.outdent();
        sw.println("}");
      }
    }

    if (useValue & (beanHelper.hasGetter(property) || beanHelper.hasField(property))) {
      // if(!valueTypeMatches) {
      sw.println("if(!valueTypeMatches)  {");
      sw.indent();

      // throw new ValidationException(value.getClass +
      // " is not a valid type for " + propertyName);
      sw.print("throw new ValidationException");
      sw.println("(value.getClass() +\" is not a valid type for \"+ propertyName);");

      // }
      sw.outdent();
      sw.println("}");
    }
  }

  private void writeValidatePropertyGroups(SourceWriter sw)
      throws UnableToCompleteException {
    // public <T> void validatePropertyGroups(
    sw.println("public <T> void validatePropertyGroups(");

    // GwtValidationContext<T> context, BeanType object, String propertyName,
    // Set<ConstraintViolation<T>> violations, Class<?>... groups) throws ValidationException {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    sw.println("String propertyName,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Class<?>... groups) throws ValidationException {");
    sw.outdent();

    for (PropertyDescriptor property : beanHelper.getBeanDescriptor().getConstrainedProperties()) {
      // if (propertyName.equals(myPropety)) {
      sw.print("if (propertyName.equals(\"");
      sw.print(property.getPropertyName());
      sw.println("\")) {");
      sw.indent();

      writeValidatePropertyCall(sw, property, false, false);

      // validate all super classes and interfaces
      writeValidateInheritance(sw, beanHelper.getClazz(), Stage.PROPERTY,
          property);

      // }
      sw.outdent();
      sw.print("} else ");
    }

    writeIfPropertyNameNotFound(sw);

    // }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidatePropertyMethod(SourceWriter sw,
      PropertyDescriptor p, boolean useField) throws UnableToCompleteException {
    Class<?> elementClass = p.getElementClass();
    JType elementType = beanHelper.getElementType(p, useField);

    // private final <T> void validateProperty_{get}<p>(
    sw.print("private final <T> void ");
    if (useField) {
      sw.print(validateMethodFieldName(p));
    } else {
      sw.print(validateMethodGetterName(p));
    }
    sw.println("(");
    sw.indent();
    sw.indent();

    // final GwtValidationContext<T> context,
    sw.println("final GwtValidationContext<T> context,");

    // final Set<ConstraintViolation<T>> violations,
    sw.println("final Set<ConstraintViolation<T>> violations,");

    // BeanType object,
    sw.println(beanHelper.getTypeCanonicalName() + " object,");
    
    // final <Type> value,
    sw.print("final ");
    sw.print(elementType.getParameterizedQualifiedSourceName());
    sw.println(" value,");
    
    // boolean honorValid,
    sw.println("boolean honorValid,");
    
    // Class<?>... groups) {
    sw.println("Class<?>... groups) {");
    sw.outdent();

    // only write the checks if the property is constrained in some way
    if (isPropertyConstrained(p, useField)) {
      // context = context.append("myProperty");
      sw.print("final GwtValidationContext<T> myContext = context.append(\"");
      sw.print(p.getPropertyName());
      sw.println("\");");
  
      // only check this property if the TraversableResolver says we can

      // Node leafNode = myContext.getPath().getLeafNode();
      sw.println("Node leafNode = myContext.getPath().getLeafNode();");
      // PathImpl path = myContext.getPath().getPathWithoutLeafNode();
      sw.println("PathImpl path = myContext.getPath().getPathWithoutLeafNode();");
      // boolean isReachable;
      sw.println("boolean isReachable;");
      // try {
      sw.println("try {");
      sw.indent();
      // isReachable = myContext.getTraversableResolver().isReachable(object, leafNode,
      //       myContext.getRootBeanClass(), path, ElementType);
      sw.println("isReachable = myContext.getTraversableResolver().isReachable(object, " +
          "leafNode, myContext.getRootBeanClass(), path, " + 
          (useField ? asLiteral(ElementType.FIELD) : asLiteral(ElementType.METHOD)) + ");");
      // } catch (Exception e) {
      sw.outdent();
      sw.println("} catch (Exception e) {");
      sw.indent();
      // throw new ValidationException("TraversableResolver isReachable caused an exception", e);
      sw.println("throw new ValidationException(\"TraversableResolver isReachable caused an " +
          "exception\", e);");
      // }
      sw.outdent();
      sw.println("}");
      // if (isReachable) {
      sw.println("if (isReachable) {");
      sw.indent();
  
      // TODO(nchalko) move this out of here to the Validate method
      if (p.isCascaded() && hasValid(p, useField)) {
  
        // if (honorValid && value != null) {
        sw.println("if (honorValid && value != null) {");
        sw.indent();
        // boolean isCascadable;
        sw.println("boolean isCascadable;");
        // try {
        sw.println("try {");
        sw.indent();
        // isCascadable = myContext.getTraversableResolver().isCascadable(object, leafNode,
        //       myContext.getRootBeanClass(), path, ElementType)
        sw.println("isCascadable = myContext.getTraversableResolver().isCascadable(object, " +
            "leafNode, myContext.getRootBeanClass(), path, " + 
          (useField ? asLiteral(ElementType.FIELD) : asLiteral(ElementType.METHOD)) + ");");
        // } catch (Exception e) {
        sw.outdent();
        sw.println("} catch (Exception e) {");
        sw.indent();
        // throw new ValidationException("TraversableResolver isReachable caused an exception", e);
        sw.println("throw new ValidationException(\"TraversableResolver isCascadable caused an " +
            "exception\", e);");
        // }
        sw.outdent();
        sw.println("}");
        // if (isCascadable) {
        sw.println("if (isCascadable) {");
        sw.indent();
  
        if (isIterableOrMap(elementClass)) {
          JClassType associationType = beanHelper.getAssociationType(p,
              useField);
          createBeanHelper(associationType);
          if (Map.class.isAssignableFrom(elementClass)) {
            writeValidateMap(sw, p);
          } else {
            writeValidateIterable(sw, p);
          }
        } else {
          createBeanHelper(elementClass);
  
          // if (!context.alreadyValidated(value)) {
          sw.println(" if (!context.alreadyValidated(value)) {");
          sw.indent();
  
          // violations.addAll(myContext.getValidator().validate(context, value,
          // groups));
          sw.print("violations.addAll(");
          sw.println("myContext.getValidator().validate(myContext, value, groups));");
  
          // }
          sw.outdent();
          sw.println("}");
        }

        // }
        sw.outdent();
        sw.println("}");
        // }
        sw.outdent();
        sw.println("}");
      }
  
      // It is possible for an annotation with the exact same values to be set on
      // both the field and the getter.
      // Keep track of the ones we have used to make sure we don't duplicate.
      Set<Object> includedAnnotations = Sets.newHashSet();
      int count = 0;
      for (ConstraintDescriptor<?> constraint : p.getConstraintDescriptors()) {
        if (areConstraintDescriptorGroupsValid(constraint)) {
          Object annotation = constraint.getAnnotation();
          if (hasMatchingAnnotation(p, useField, constraint)) {
            String constraintDescriptorVar = constraintDescriptorVar(p.getPropertyName(), count);
            if (!includedAnnotations.contains(annotation)) {
              if (useField) {
                writeValidateConstraint(sw, p, elementClass, constraint, constraintDescriptorVar);
              } else {
                // The annotation hasn't been looked at twice (yet) and we are validating a getter
                // Write the call if only the getter has this constraint applied to it
                boolean hasField = beanHelper.hasField(p);
                if (!hasField ||
                    (hasField && !hasMatchingAnnotation(p, true, constraint))) {
                  writeValidateConstraint(sw, p, elementClass, constraint, constraintDescriptorVar);
                }
              }
            } else {
              // The annotation has been looked at once already during this validate property call
              // so we know the field and the getter are both annotated with the same constraint.
              if (!useField) {
                writeValidateConstraint(sw, p, elementClass, constraint, constraintDescriptorVar);
              }
            }
            includedAnnotations.add(annotation);
          }
          count++;
        }
      }
      // }
      sw.outdent();
      sw.println("}");
    }
    sw.outdent();
    sw.println("}");
  }

  private void writeValidateValueGroups(SourceWriter sw)
      throws UnableToCompleteException {
    // public <T> void validateValueGroups(
    sw.println("public <T> void validateValueGroups(");

    // GwtValidationContext<T> context, Class<Author> beanType, String propertyName,
    // Object value, Set<ConstraintViolation<T>> violations, Class<?>... groups) {
    sw.indent();
    sw.indent();
    sw.println("GwtValidationContext<T> context,");
    sw.println("Class<" + beanHelper.getTypeCanonicalName() + "> beanType,");
    sw.println("String propertyName,");
    sw.println("Object value,");
    sw.println("Set<ConstraintViolation<T>> violations,");
    sw.println("Class<?>... groups) {");
    sw.outdent();

    for (PropertyDescriptor property :
        beanHelper.getBeanDescriptor().getConstrainedProperties()) {
      // if (propertyName.equals(myPropety)) {
      sw.print("if (propertyName.equals(\"");
      sw.print(property.getPropertyName());
      sw.println("\")) {");
      sw.indent();

      if (!isIterableOrMap(property.getElementClass())) {
        writeValidatePropertyCall(sw, property, true, false);
      }

      // validate all super classes and interfaces
      writeValidateInheritance(sw, beanHelper.getClazz(),
          Stage.VALUE, property);

      // }
      sw.outdent();
      sw.print("} else ");
    }

    writeIfPropertyNameNotFound(sw);

    sw.outdent();
    sw.println("}");
  }

  /**
   * @param p Only used if writing a call to validate a property - otherwise can be null.
   * @param expandDefaultGroupSequence Only used if writing a call to validate a bean.
   * @param groupsVarName The name of the variable containing the groups.
   */
  private void writeValidatorCall(SourceWriter sw, Class<?> type, Stage stage,
      PropertyDescriptor p, boolean expandDefaultGroupSequence, String groupsVarName)
      throws UnableToCompleteException {
    if (cache.isClassConstrained(type) && !isIterableOrMap(type)) {
      BeanHelper helper = createBeanHelper(type);
      beansToValidate.add(helper);
      switch (stage) {
        case OBJECT:
          // myValidator
          sw.print(helper.getValidatorInstanceName());
          if (expandDefaultGroupSequence) {
            // .expandDefaultAndValidateClassGroups(context,object,violations,groups);
            sw.println(".expandDefaultAndValidateClassGroups(context, object, violations, " +
                groupsVarName + ");");
          } else {
            // .validateClassGroups(context,object,violations,groups);
            sw.println(".validateClassGroups(context, object, violations, " + groupsVarName + ");");
          }
          break;
        case PROPERTY:
          if (isPropertyConstrained(helper, p)) {
            // myValidator.validatePropertyGroups(context,object
            // ,propertyName, violations, groups);
            sw.print(helper.getValidatorInstanceName());
            sw.print(".validatePropertyGroups(context, object,");
            sw.println(" propertyName, violations, " + groupsVarName + ");");
          }
          break;
        case VALUE:
          if (isPropertyConstrained(helper, p)) {
            // myValidator.validateValueGroups(context,beanType
            // ,propertyName, value, violations, groups);
            sw.print(helper.getValidatorInstanceName());
            sw.print(".validateValueGroups(context, ");
            sw.print(helper.getTypeCanonicalName());
            sw.println(".class, propertyName, value, violations, " + groupsVarName + ");");
          }
          break;
        default:
          throw new IllegalStateException();
      }
    }
  }

  private void writeWrappers(SourceWriter sw) {
    sw.println("// Write the wrappers after we know which are needed");
    for (JField field : fieldsToWrap) {
      writeFieldWrapperMethod(sw, field);
      sw.println();
    }

    for (JMethod method : gettersToWrap) {
      writeGetterWrapperMethod(sw, method);
      sw.println();
    }
  }
}
