static {
   // Planner managed annotations
   domainAnnotations.add(DriverUtils.buildAnnotationDefinition(PlanningEntity.class));
   domainAnnotations.add(DriverUtils.buildAnnotationDefinition(PlanningSolution.class));
   domainAnnotations.add(DriverUtils.buildAnnotationDefinition(PlanningVariable.class));
   domainAnnotations.add(DriverUtils.buildAnnotationDefinition(ValueRangeProvider.class));
   domainAnnotations.add(
       DriverUtils.buildAnnotationDefinition(PlanningEntityCollectionProperty.class));
 }
  public static AnnotationDefinition buildAnnotationDefinition(Class cls) {

    if (!cls.isAnnotation()) return null;

    AnnotationDefinitionImpl annotationDefinition =
        new AnnotationDefinitionImpl(NamingUtils.normalizeClassName(cls.getName()));

    // set retention and target.
    DriverUtils.copyAnnotationRetention(cls, annotationDefinition);
    DriverUtils.copyAnnotationTarget(cls, annotationDefinition);

    Method[] methods = cls.getMethods();
    Method method;
    AnnotationValuePairDefinitionImpl valuePairDefinition;
    Class returnType;
    boolean isArray = false;

    for (int i = 0; methods != null && i < methods.length; i++) {
      method = methods[i];
      if (DriverUtils.isAnnotationMember(cls, method)) {
        returnType = method.getReturnType();
        if ((isArray = returnType.isArray())) returnType = returnType.getComponentType();
        valuePairDefinition =
            new AnnotationValuePairDefinitionImpl(
                method.getName(),
                NamingUtils.normalizeClassName(returnType.getName()),
                DriverUtils.buildValuePairType(returnType),
                isArray,
                // TODO, review this default value assignment, when we have annotations the default
                // value should be an AnnotationInstance
                method.getDefaultValue() != null ? method.getDefaultValue().toString() : null);
        if (valuePairDefinition.isAnnotation()) {
          valuePairDefinition.setAnnotationDefinition(buildAnnotationDefinition(returnType));
        }
        if (valuePairDefinition.isEnum()) {
          Object[] enumConstants = returnType.getEnumConstants();
          if (enumConstants != null) {
            String[] strEnumConstants = new String[enumConstants.length];
            for (int j = 0; j < enumConstants.length; j++) {
              strEnumConstants[j] = enumConstants[j].toString();
            }
            valuePairDefinition.setEnumValues(strEnumConstants);
          }
        }
        annotationDefinition.addValuePair(valuePairDefinition);
      }
    }

    return annotationDefinition;
  }
 public static void copyAnnotationRetention(
     Class annotationClass, AnnotationDefinition annotationDefinition) {
   if (annotationClass.isAnnotationPresent(Retention.class)) {
     Retention retentionAnnotation = (Retention) annotationClass.getAnnotation(Retention.class);
     annotationDefinition.setRetention(DriverUtils.buildRetention(retentionAnnotation.value()));
   }
 }