@Override
    public Void visitNewArray(NewArrayTree tree, AnnotatedTypeMirror type) {

      List<? extends ExpressionTree> dimensions = tree.getDimensions();
      List<? extends ExpressionTree> initializers = tree.getInitializers();

      // Dimensions provided
      if (!dimensions.isEmpty()) {
        handleDimensions(dimensions, (AnnotatedArrayType) type);
      } else {
        // Initializer used
        handleInitalizers(initializers, (AnnotatedArrayType) type);

        AnnotationMirror newQual;
        Class<?> clazz = ValueCheckerUtils.getClassFromType(type.getUnderlyingType());
        String stringVal = null;
        if (clazz.equals(byte[].class)) {
          stringVal = getByteArrayStringVal(initializers);
        } else if (clazz.equals(char[].class)) {
          stringVal = getCharArrayStringVal(initializers);
        }

        if (stringVal != null) {
          newQual = createStringAnnotation(Collections.singletonList(stringVal));
          type.replaceAnnotation(newQual);
        }
      }

      return null;
    }
 public AnnotationMirror createBooleanAnnotation(List<Boolean> values) {
   values = ValueCheckerUtils.removeDuplicates(values);
   if (values.isEmpty() || values.size() > MAX_VALUES) {
     return UNKNOWNVAL;
   }
   AnnotationBuilder builder = new AnnotationBuilder(processingEnv, BoolVal.class);
   builder.setValue("value", values);
   return builder.build();
 }
 public AnnotationMirror createDoubleValAnnotation(List<Double> doubleValues) {
   doubleValues = ValueCheckerUtils.removeDuplicates(doubleValues);
   if (doubleValues.isEmpty() || doubleValues.size() > MAX_VALUES) {
     return UNKNOWNVAL;
   }
   AnnotationBuilder builder = new AnnotationBuilder(processingEnv, DoubleVal.class);
   builder.setValue("value", doubleValues);
   return builder.build();
 }
 private List<?> getValues(AnnotatedTypeMirror type, TypeMirror castTo) {
   AnnotationMirror anno = type.getAnnotationInHierarchy(UNKNOWNVAL);
   if (anno == null) {
     // if type is an AnnotatedTypeVariable (or other type without a primary annotation)
     // then anno will be null. It would be safe to use the annotation on the upper bound;
     //  however, unless the upper bound was explicitly annotated, it will be unknown.
     // AnnotatedTypes.findEffectiveAnnotationInHierarchy(, toSearch, top)
     return new ArrayList<>();
   }
   return ValueCheckerUtils.getValuesCastedToType(anno, castTo);
 }
 public AnnotationMirror createCharAnnotation(List<Character> values) {
   values = ValueCheckerUtils.removeDuplicates(values);
   if (values.isEmpty() || values.size() > MAX_VALUES) {
     return UNKNOWNVAL;
   }
   List<Long> longValues = new ArrayList<>();
   for (char value : values) {
     longValues.add((long) value);
   }
   AnnotationBuilder builder = new AnnotationBuilder(processingEnv, IntVal.class);
   builder.setValue("value", longValues);
   return builder.build();
 }
    /**
     * Overloaded version to accept an AnnotatedTypeMirror
     *
     * @param resultType is evaluated using getClass to derived a Class object for passing to the
     *     other resultAnnotationHandler function
     * @param tree location for error reporting
     */
    private AnnotationMirror resultAnnotationHandler(
        TypeMirror resultType, List<?> results, Tree tree) {

      Class<?> resultClass = ValueCheckerUtils.getClassFromType(resultType);

      // For some reason null is included in the list of values,
      // so remove it so that it does not cause a NPE else where.
      results.remove(null);
      if (results.size() == 0) {
        return UNKNOWNVAL;
      } else if (resultClass == Boolean.class || resultClass == boolean.class) {
        HashSet<Boolean> boolVals = new HashSet<Boolean>(results.size());
        for (Object o : results) {
          boolVals.add((Boolean) o);
        }
        return createBooleanAnnotation(new ArrayList<Boolean>(boolVals));

      } else if (resultClass == Double.class
          || resultClass == double.class
          || resultClass == Float.class
          || resultClass == float.class
          || resultClass == Integer.class
          || resultClass == int.class
          || resultClass == Long.class
          || resultClass == long.class
          || resultClass == Short.class
          || resultClass == short.class
          || resultClass == Byte.class
          || resultClass == byte.class) {
        HashSet<Number> numberVals = new HashSet<>(results.size());
        List<Character> charVals = new ArrayList<>();
        for (Object o : results) {
          if (o instanceof Character) {
            charVals.add((Character) o);
          } else {
            numberVals.add((Number) o);
          }
        }
        if (numberVals.isEmpty()) {
          return createCharAnnotation(charVals);
        }
        return createNumberAnnotationMirror(new ArrayList<Number>(numberVals));
      } else if (resultClass == char.class || resultClass == Character.class) {
        HashSet<Character> intVals = new HashSet<>(results.size());
        for (Object o : results) {
          if (o instanceof Number) {
            intVals.add((char) ((Number) o).intValue());
          } else {
            intVals.add((char) o);
          }
        }
        return createCharAnnotation(new ArrayList<Character>(intVals));
      } else if (resultClass == String.class) {
        HashSet<String> stringVals = new HashSet<String>(results.size());
        for (Object o : results) {
          stringVals.add((String) o);
        }
        return createStringAnnotation(new ArrayList<String>(stringVals));
      } else if (resultClass == byte[].class) {
        HashSet<String> stringVals = new HashSet<String>(results.size());
        for (Object o : results) {
          if (o instanceof byte[]) {
            stringVals.add(new String((byte[]) o));
          } else {
            stringVals.add(o.toString());
          }
        }
        return createStringAnnotation(new ArrayList<String>(stringVals));
      }

      return UNKNOWNVAL;
    }