public static DialogFieldConfig getDialogFieldFromSuperClasses(CtMethod method)
     throws NotFoundException, ClassNotFoundException, InvalidComponentClassException {
   DialogFieldConfig dialogFieldConfig = null;
   List<CtClass> classes = new ArrayList<CtClass>();
   CtClass clazz = method.getDeclaringClass();
   classes.add(clazz);
   while (clazz.getSuperclass() != null) {
     classes.add(clazz.getSuperclass());
     clazz = clazz.getSuperclass();
   }
   Collections.reverse(classes);
   CtMember interfaceMember = getMemberForAnnotatedInterfaceMethod(method);
   if (interfaceMember != null) {
     dialogFieldConfig =
         new DialogFieldConfig(
             (DialogField) interfaceMember.getAnnotation(DialogField.class), interfaceMember);
   }
   for (CtClass ctclass : classes) {
     try {
       CtMethod superClassMethod =
           ctclass.getDeclaredMethod(method.getName(), method.getParameterTypes());
       if (superClassMethod.hasAnnotation(DialogField.class)) {
         dialogFieldConfig =
             new DialogFieldConfig(
                 (DialogField) superClassMethod.getAnnotation(DialogField.class),
                 superClassMethod);
       } else if (superClassMethod.hasAnnotation(DialogFieldOverride.class)) {
         mergeDialogFields(dialogFieldConfig, superClassMethod);
       }
     } catch (NotFoundException e) {
     }
   }
   return dialogFieldConfig;
 }
  private void enhanceJPACallback(CtClass ctClass, CtMethod method, Class anno) throws Exception {
    if (method.hasAnnotation(anno)) {
      CtMethod ctMethod =
          CtMethod.make(
              format(
                  "public void {}() {\n"
                      + "        net.csdn.jpa.context.JPAContext jpaContext = getJPAConfig().reInitJPAContext();\n"
                      + "        try {\n"
                      + "            {}();\n"
                      + "            getJPAConfig().getJPAContext().closeTx(false);\n"
                      + "        } catch (Exception e) {\n"
                      + "            getJPAConfig().getJPAContext().closeTx(true);\n"
                      + "        } finally {\n"
                      + "            getJPAConfig().setJPAContext(jpaContext);\n"
                      + "        }\n"
                      + "    }",
                  "$_" + method.getName(),
                  method.getName()),
              ctClass);

      ctClass.addMethod(ctMethod);
      AnnotationsAttribute annotationsAttribute = EnhancerHelper.getAnnotations(ctMethod);
      EnhancerHelper.createAnnotation(annotationsAttribute, callback_classes.get(anno));
    }
  }
  private static void mergeDialogFields(DialogFieldConfig dialogFieldConfig, CtMethod method)
      throws ClassNotFoundException {
    if (dialogFieldConfig != null && method.hasAnnotation(DialogFieldOverride.class)) {
      DialogFieldOverride dialogField =
          (DialogFieldOverride) method.getAnnotation(DialogFieldOverride.class);
      if (StringUtils.isNotEmpty(dialogField.fieldLabel())) {
        dialogFieldConfig.setFieldLabel(dialogField.fieldLabel());
      }

      if (StringUtils.isNotEmpty(dialogField.fieldDescription())) {
        dialogFieldConfig.setFieldDescription(dialogField.fieldDescription());
      }

      dialogFieldConfig.setRequired(dialogField.required());

      dialogFieldConfig.setHideLabel(dialogField.hideLabel());

      if (StringUtils.isNotEmpty(dialogField.defaultValue())) {
        dialogFieldConfig.setDefaultValue(dialogField.defaultValue());
      }

      if (StringUtils.isNotEmpty(dialogField.name())) {
        dialogFieldConfig.setName(dialogField.name());
      }

      dialogFieldConfig.setTab(dialogField.tab());

      dialogFieldConfig.setRanking(dialogField.ranking());

      if (dialogField.additionalProperties().length > 0) {
        List<FieldProperty> properties = new ArrayList<FieldProperty>();
        properties.addAll(Arrays.asList(dialogField.additionalProperties()));
        if (dialogField.mergeAdditionalProperties()) {
          properties.addAll(Arrays.asList(dialogFieldConfig.getAdditionalProperties()));
        }
        dialogFieldConfig.setAdditionalProperties(
            properties.toArray(new FieldProperty[properties.size()]));
      }

      if (dialogField.listeners().length > 0) {
        List<Listener> listeners = new ArrayList<Listener>();
        listeners.addAll(Arrays.asList(dialogField.listeners()));
        if (dialogField.mergeAdditionalProperties()) {
          listeners.addAll(Arrays.asList(dialogFieldConfig.getListeners()));
        }
        dialogFieldConfig.setListeners(listeners.toArray(new Listener[listeners.size()]));
      }
    }
  }
  private Set<CtMethod> getPatchMethods(Set<CtClass> patchClasses) {
    Set<CtMethod> result = new HashSet<CtMethod>();

    // add all @PatchMethod found in a temporary map
    Map<String, List<CtMethod>> temp = new HashMap<String, List<CtMethod>>();
    for (CtClass patchClass : patchClasses) {
      for (CtMethod ctMethod : patchClass.getDeclaredMethods()) {
        if (ctMethod.hasAnnotation(PatchMethod.class)) {
          if (!Modifier.isStatic(ctMethod.getModifiers())) {
            throw new GwtTestPatchException(
                "@"
                    + PatchMethod.class.getName()
                    + " has to be static : '"
                    + ctMethod.getLongName()
                    + "'");
          }
          String nameAndSignature =
              ctMethod.getName() + Descriptor.toString(ctMethod.getSignature());
          List<CtMethod> correspondingMethods = temp.get(nameAndSignature);

          if (correspondingMethods == null) {
            correspondingMethods = new ArrayList<CtMethod>();
            temp.put(nameAndSignature, correspondingMethods);
          }

          correspondingMethods.add(ctMethod);
        }
      }
    }

    // for each @PatchMethod with the same signature, filter to get one with
    // override=true
    for (Map.Entry<String, List<CtMethod>> entry : temp.entrySet()) {
      CtMethod methodToUse = getMethodToUse(entry.getValue(), PatchMethod.class);
      methodToUse.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
      result.add(methodToUse);
    }

    return result;
  }
  private CtMethod getInitMethod(Set<CtClass> patchClasses) {
    List<CtMethod> initMethods = new ArrayList<CtMethod>();

    for (CtClass patchClass : patchClasses) {
      for (CtMethod ctMethod : patchClass.getDeclaredMethods()) {
        if (ctMethod.hasAnnotation(InitMethod.class)) {
          if (!Modifier.isStatic(ctMethod.getModifiers())) {
            throw new GwtTestPatchException(
                "@"
                    + InitMethod.class.getName()
                    + " has to be static : '"
                    + ctMethod.getLongName()
                    + "'");
          }
          try {
            if (ctMethod.getParameterTypes().length != 1
                || ctMethod.getParameterTypes()[0] != GwtClassPool.getCtClass(CtClass.class)) {
              throw new GwtTestPatchException(
                  "@"
                      + InitMethod.class.getName()
                      + " method must have one and only one parameter of type '"
                      + CtClass.class.getName()
                      + "'");
            }
          } catch (NotFoundException e) {
            // should never happen
            throw new GwtTestPatchException(e);
          }
          initMethods.add(ctMethod);
        }
      }
    }

    CtMethod initMethod = getMethodToUse(initMethods, InitMethod.class);
    if (initMethod != null) {
      initMethod.setModifiers(Modifier.PUBLIC + Modifier.STATIC);
    }
    return initMethod;
  }
  @Override
  public byte[] transform(
      ClassLoader loader,
      String className,
      Class<?> classBeingRedefined,
      ProtectionDomain protectionDomain,
      byte[] classfileBuffer)
      throws IllegalClassFormatException {
    byte[] bytes = null;
    try {
      final ClassPool pool = ClassPool.getDefault();
      pool.appendClassPath(new LoaderClassPath(getClass().getClassLoader()));
      final CtClass ctClass = pool.getCtClass(className.replaceAll("/", "."));
      if (ctClass != null) {
        try {
          for (CtMethod ctMethod : ctClass.getMethods()) {
            if (ctMethod.hasAnnotation(Retryable.class)) {
              try {
                changeMethod(ctClass, ctMethod);
                bytes = ctClass.toBytecode();
                writeClassFile(bytes);

              } catch (CannotCompileException | IOException e) {
                e.printStackTrace();
              }
              System.out.println("found it!");
            }
          }
        } finally {
          ctClass.detach();
        }
      }
    } catch (NotFoundException e) {
      e.printStackTrace();
    }
    return bytes;
  }
 private void enhanceJPACallback(CtClass ctClass) throws Exception {
   CtMethod[] methods = ctClass.getDeclaredMethods();
   for (CtMethod ctMethod : methods) {
     if (ctMethod.hasAnnotation(AfterSave.class)) {
       enhanceJPACallback(ctClass, ctMethod, AfterSave.class);
     }
     if (ctMethod.hasAnnotation(BeforeSave.class)) {
       enhanceJPACallback(ctClass, ctMethod, BeforeSave.class);
     }
     if (ctMethod.hasAnnotation(AfterUpdate.class)) {
       enhanceJPACallback(ctClass, ctMethod, AfterUpdate.class);
     }
     if (ctMethod.hasAnnotation(BeforeUpdate.class)) {
       enhanceJPACallback(ctClass, ctMethod, BeforeUpdate.class);
     }
     if (ctMethod.hasAnnotation(BeforeDestroy.class)) {
       enhanceJPACallback(ctClass, ctMethod, BeforeDestroy.class);
     }
     if (ctMethod.hasAnnotation(AfterLoad.class)) {
       enhanceJPACallback(ctClass, ctMethod, AfterLoad.class);
     }
   }
 }
  @Override
  public byte[] transform(
      ClassLoader loader,
      String className,
      Class<?> classBeingRedefined,
      ProtectionDomain protectionDomain,
      byte[] classfileBuffer)
      throws IllegalClassFormatException {
    // Be careful with Apache library usage in this class (e.g. ArrayUtils). Usage will likely cause
    // a ClassCircularityError
    // under JRebel. Favor not including outside libraries and unnecessary classes.
    CtClass clazz = null;
    try {
      boolean mySkipOverlaps = skipOverlaps;
      boolean myRenameMethodOverlaps = renameMethodOverlaps;
      String convertedClassName = className.replace('/', '.');
      ClassPool classPool = null;
      String xformKey = convertedClassName;
      String[] xformVals = null;
      Boolean[] xformSkipOverlaps = null;
      Boolean[] xformRenameMethodOverlaps = null;
      if (!xformTemplates.isEmpty()) {
        if (xformTemplates.containsKey(xformKey)) {
          xformVals = xformTemplates.get(xformKey).split(",");
          classPool = ClassPool.getDefault();
          clazz = classPool.makeClass(new ByteArrayInputStream(classfileBuffer), false);
        }
      } else {
        if (annotationTransformedClasses.contains(convertedClassName)) {
          logger.warn(
              convertedClassName
                  + " has already been transformed by a previous instance of DirectCopyTransfomer. "
                  + "Skipping this annotation based transformation. Generally, annotation-based transformation is handled "
                  + "by bean id blAnnotationDirectCopyClassTransformer with template tokens being added to "
                  + "blDirectCopyTransformTokenMap via EarlyStageMergeBeanPostProcessor.");
        }
        boolean isValidPattern = true;
        List<DirectCopyIgnorePattern> matchedPatterns = new ArrayList<DirectCopyIgnorePattern>();
        for (DirectCopyIgnorePattern pattern : ignorePatterns) {
          boolean isPatternMatch = false;
          for (String patternString : pattern.getPatterns()) {
            isPatternMatch = convertedClassName.matches(patternString);
            if (isPatternMatch) {
              break;
            }
          }
          if (isPatternMatch) {
            matchedPatterns.add(pattern);
          }
          isValidPattern = !(isPatternMatch && pattern.getTemplateTokenPatterns() == null);
          if (!isValidPattern) {
            return null;
          }
        }
        if (isValidPattern) {
          classPool = ClassPool.getDefault();
          clazz = classPool.makeClass(new ByteArrayInputStream(classfileBuffer), false);
          List<?> attributes = clazz.getClassFile().getAttributes();
          Iterator<?> itr = attributes.iterator();
          List<String> templates = new ArrayList<String>();
          List<Boolean> skips = new ArrayList<Boolean>();
          List<Boolean> renames = new ArrayList<Boolean>();
          check:
          {
            while (itr.hasNext()) {
              Object object = itr.next();
              if (AnnotationsAttribute.class.isAssignableFrom(object.getClass())) {
                AnnotationsAttribute attr = (AnnotationsAttribute) object;
                Annotation[] items = attr.getAnnotations();
                for (Annotation annotation : items) {
                  String typeName = annotation.getTypeName();
                  if (typeName.equals(DirectCopyTransform.class.getName())) {
                    ArrayMemberValue arrayMember =
                        (ArrayMemberValue) annotation.getMemberValue("value");
                    for (MemberValue arrayMemberValue : arrayMember.getValue()) {
                      AnnotationMemberValue member = (AnnotationMemberValue) arrayMemberValue;
                      Annotation memberAnnot = member.getValue();
                      ArrayMemberValue annot =
                          (ArrayMemberValue) memberAnnot.getMemberValue("templateTokens");
                      for (MemberValue memberValue : annot.getValue()) {
                        String val = ((StringMemberValue) memberValue).getValue();
                        if (val != null && templateTokens.containsKey(val)) {
                          templateCheck:
                          {
                            for (DirectCopyIgnorePattern matchedPattern : matchedPatterns) {
                              for (String ignoreToken : matchedPattern.getTemplateTokenPatterns()) {
                                if (val.matches(ignoreToken)) {
                                  break templateCheck;
                                }
                              }
                            }
                            templates.add(templateTokens.get(val));
                          }
                        }
                      }
                      BooleanMemberValue skipAnnot =
                          (BooleanMemberValue) memberAnnot.getMemberValue("skipOverlaps");
                      if (skipAnnot != null) {
                        skips.add(skipAnnot.getValue());
                      } else {
                        skips.add(mySkipOverlaps);
                      }
                      BooleanMemberValue renameAnnot =
                          (BooleanMemberValue) memberAnnot.getMemberValue("renameMethodOverlaps");
                      if (renameAnnot != null) {
                        renames.add(renameAnnot.getValue());
                      } else {
                        renames.add(myRenameMethodOverlaps);
                      }
                    }
                    xformVals = templates.toArray(new String[templates.size()]);
                    xformSkipOverlaps = skips.toArray(new Boolean[skips.size()]);
                    xformRenameMethodOverlaps = renames.toArray(new Boolean[renames.size()]);
                    break check;
                  }
                }
              }
            }
          }
        }
      }
      if (xformVals != null && xformVals.length > 0) {
        logger.lifecycle(
            LifeCycleEvent.START,
            String.format(
                "Transform - Copying into [%s] from [%s]",
                xformKey, StringUtils.join(xformVals, ",")));
        // Load the destination class and defrost it so it is eligible for modifications
        clazz.defrost();

        int index = 0;
        for (String xformVal : xformVals) {
          // Load the source class
          String trimmed = xformVal.trim();
          classPool.appendClassPath(new LoaderClassPath(Class.forName(trimmed).getClassLoader()));
          CtClass template = classPool.get(trimmed);

          // Add in extra interfaces
          CtClass[] interfacesToCopy = template.getInterfaces();
          for (CtClass i : interfacesToCopy) {
            checkInterfaces:
            {
              CtClass[] myInterfaces = clazz.getInterfaces();
              for (CtClass myInterface : myInterfaces) {
                if (myInterface.getName().equals(i.getName())) {
                  if (xformSkipOverlaps[index]) {
                    break checkInterfaces;
                  } else {
                    throw new RuntimeException(
                        "Duplicate interface detected " + myInterface.getName());
                  }
                }
              }
              logger.debug(String.format("Adding interface [%s]", i.getName()));
              clazz.addInterface(i);
            }
          }

          // copy over any EntityListeners
          ClassFile classFile = clazz.getClassFile();
          ClassFile templateFile = template.getClassFile();
          ConstPool constantPool = classFile.getConstPool();
          buildClassLevelAnnotations(classFile, templateFile, constantPool);

          // Copy over all declared fields from the template class
          // Note that we do not copy over fields with the @NonCopiedField annotation
          CtField[] fieldsToCopy = template.getDeclaredFields();
          for (CtField field : fieldsToCopy) {
            if (field.hasAnnotation(NonCopied.class)) {
              logger.debug(String.format("Not adding field [%s]", field.getName()));
            } else {
              try {
                CtField ctField = clazz.getDeclaredField(field.getName());
                String originalSignature = ctField.getSignature();
                String mySignature = field.getSignature();
                if (!originalSignature.equals(mySignature)) {
                  throw new IllegalArgumentException(
                      "Field with name ("
                          + field.getName()
                          + ") and signature "
                          + "("
                          + field.getSignature()
                          + ") is targeted for weaving into ("
                          + clazz.getName()
                          + "). "
                          + "An incompatible field of the same name and signature of ("
                          + ctField.getSignature()
                          + ") "
                          + "already exists. The field in the target class should be updated to a different name, "
                          + "or made to have a matching type.");
                }
                if (xformSkipOverlaps[index]) {
                  logger.debug(String.format("Skipping overlapped field [%s]", field.getName()));
                  continue;
                }
              } catch (NotFoundException e) {
                // do nothing -- field does not exist
              }
              logger.debug(String.format("Adding field [%s]", field.getName()));
              CtField copiedField = new CtField(field, clazz);

              boolean defaultConstructorFound = false;

              String implClass = getImplementationType(field.getType().getName());

              // Look through all of the constructors in the implClass to see
              // if there is one that takes zero parameters
              try {
                CtConstructor[] implConstructors = classPool.get(implClass).getConstructors();
                if (implConstructors != null) {
                  for (CtConstructor cons : implConstructors) {
                    if (cons.getParameterTypes().length == 0) {
                      defaultConstructorFound = true;
                      break;
                    }
                  }
                }
              } catch (NotFoundException e) {
                // Do nothing -- if we don't find this implementation, it's probably because it's
                // an array. In this case, we will not initialize the field.
              }

              if (defaultConstructorFound) {
                clazz.addField(copiedField, "new " + implClass + "()");
              } else {
                clazz.addField(copiedField);
              }
            }
          }

          // Copy over all declared methods from the template class
          CtMethod[] methodsToCopy = template.getDeclaredMethods();
          for (CtMethod method : methodsToCopy) {
            if (method.hasAnnotation(NonCopied.class)) {
              logger.debug(String.format("Not adding method [%s]", method.getName()));
            } else {
              try {
                CtClass[] paramTypes = method.getParameterTypes();
                CtMethod originalMethod = clazz.getDeclaredMethod(method.getName(), paramTypes);

                if (xformSkipOverlaps[index]) {
                  logger.debug(
                      String.format(
                          "Skipping overlapped method [%s]", methodDescription(originalMethod)));
                  continue;
                }

                if (transformedMethods.contains(methodDescription(originalMethod))) {
                  throw new RuntimeException(
                      "Method already replaced " + methodDescription(originalMethod));
                } else {
                  logger.debug(
                      String.format("Marking as replaced [%s]", methodDescription(originalMethod)));
                  transformedMethods.add(methodDescription(originalMethod));
                }

                logger.debug(String.format("Removing method [%s]", method.getName()));
                if (xformRenameMethodOverlaps[index]) {
                  originalMethod.setName(renameMethodPrefix + method.getName());
                } else {
                  clazz.removeMethod(originalMethod);
                }
              } catch (NotFoundException e) {
                // Do nothing -- we don't need to remove a method because it doesn't exist
              }

              logger.debug(String.format("Adding method [%s]", method.getName()));
              CtMethod copiedMethod = new CtMethod(method, clazz, null);
              clazz.addMethod(copiedMethod);
            }
          }
          index++;
        }

        if (xformTemplates.isEmpty()) {
          annotationTransformedClasses.add(convertedClassName);
        }
        logger.lifecycle(
            LifeCycleEvent.END,
            String.format(
                "Transform - Copying into [%s] from [%s]",
                xformKey, StringUtils.join(xformVals, ",")));
        return clazz.toBytecode();
      }
    } catch (ClassCircularityError error) {
      error.printStackTrace();
      throw error;
    } catch (Exception e) {
      throw new RuntimeException("Unable to transform class", e);
    } finally {
      if (clazz != null) {
        clazz.detach();
      }
    }

    return null;
  }
  @Override
  public byte[] transform(
      ClassLoader loader,
      String className,
      Class<?> classBeingRedefined,
      ProtectionDomain protectionDomain,
      byte[] classfileBuffer)
      throws IllegalClassFormatException {
    String convertedClassName = className.replace('/', '.');

    if (xformTemplates.containsKey(convertedClassName)) {
      String xformKey = convertedClassName;
      String[] xformVals = xformTemplates.get(xformKey).split(",");
      logger.lifecycle(
          LifeCycleEvent.START,
          String.format(
              "Transform - Copying into [%s] from [%s]",
              xformKey, StringUtils.join(xformVals, ",")));

      try {
        // Load the destination class and defrost it so it is eligible for modifications
        ClassPool classPool = ClassPool.getDefault();
        CtClass clazz = classPool.makeClass(new ByteArrayInputStream(classfileBuffer), false);
        clazz.defrost();

        for (String xformVal : xformVals) {
          // Load the source class
          String trimmed = xformVal.trim();
          classPool.appendClassPath(new LoaderClassPath(Class.forName(trimmed).getClassLoader()));
          CtClass template = classPool.get(trimmed);

          // Add in extra interfaces
          CtClass[] interfacesToCopy = template.getInterfaces();
          for (CtClass i : interfacesToCopy) {
            logger.debug(String.format("Adding interface [%s]", i.getName()));
            clazz.addInterface(i);
          }

          // Copy over all declared fields from the template class
          // Note that we do not copy over fields with the @NonCopiedField annotation
          CtField[] fieldsToCopy = template.getDeclaredFields();
          for (CtField field : fieldsToCopy) {
            if (field.hasAnnotation(NonCopied.class)) {
              logger.debug(String.format("Not adding field [%s]", field.getName()));
            } else {
              logger.debug(String.format("Adding field [%s]", field.getName()));
              CtField copiedField = new CtField(field, clazz);

              boolean defaultConstructorFound = false;

              String implClass = getImplementationType(field.getType().getName());

              // Look through all of the constructors in the implClass to see
              // if there is one that takes zero parameters
              try {
                CtConstructor[] implConstructors = classPool.get(implClass).getConstructors();
                if (implConstructors != null) {
                  for (CtConstructor cons : implConstructors) {
                    if (cons.getParameterTypes().length == 0) {
                      defaultConstructorFound = true;
                      break;
                    }
                  }
                }
              } catch (NotFoundException e) {
                // Do nothing -- if we don't find this implementation, it's probably because it's
                // an array. In this case, we will not initialize the field.
              }

              if (defaultConstructorFound) {
                clazz.addField(copiedField, "new " + implClass + "()");
              } else {
                clazz.addField(copiedField);
              }
            }
          }

          // Copy over all declared methods from the template class
          CtMethod[] methodsToCopy = template.getDeclaredMethods();
          for (CtMethod method : methodsToCopy) {
            if (method.hasAnnotation(NonCopied.class)) {
              logger.debug(String.format("Not adding method [%s]", method.getName()));
            } else {
              try {
                CtClass[] paramTypes = method.getParameterTypes();
                CtMethod originalMethod = clazz.getDeclaredMethod(method.getName(), paramTypes);

                if (transformedMethods.contains(methodDescription(originalMethod))) {
                  throw new RuntimeException(
                      "Method already replaced " + methodDescription(originalMethod));
                } else {
                  logger.debug(
                      String.format("Marking as replaced [%s]", methodDescription(originalMethod)));
                  transformedMethods.add(methodDescription(originalMethod));
                }

                logger.debug(String.format("Removing method [%s]", method.getName()));
                clazz.removeMethod(originalMethod);
              } catch (NotFoundException e) {
                // Do nothing -- we don't need to remove a method because it doesn't exist
              }

              logger.debug(String.format("Adding method [%s]", method.getName()));
              CtMethod copiedMethod = new CtMethod(method, clazz, null);
              clazz.addMethod(copiedMethod);
            }
          }
        }

        logger.lifecycle(
            LifeCycleEvent.END,
            String.format(
                "Transform - Copying into [%s] from [%s]",
                xformKey, StringUtils.join(xformVals, ",")));
        return clazz.toBytecode();
      } catch (Exception e) {
        throw new RuntimeException("Unable to transform class", e);
      }
    }

    return null;
  }
  /**
   * Constructs a list of Dialog objects based on Classes annotated by Component annotations. Scans
   * the provided list of classes constructing a Dialog object for each one annotated with the
   * Component annotation. Any classes provided in the class list which are not thusly annotated are
   * ignored.
   *
   * @param classList
   * @param zipOutputStream
   * @param reservedNames
   * @param xtypeMap
   * @param classLoader
   * @param classPool
   * @return A list of constructed Dialog objects
   * @throws InvalidComponentClassException
   * @throws InvalidComponentFieldException
   * @throws OutputFailureException
   * @throws IOException
   * @throws ParserConfigurationException
   * @throws TransformerException
   * @throws ClassNotFoundException
   * @throws CannotCompileException
   * @throws NotFoundException
   * @throws SecurityException
   * @throws NoSuchFieldException
   * @throws IllegalArgumentException
   * @throws IllegalAccessException
   * @throws InvocationTargetException
   * @throws NoSuchMethodException
   * @throws InstantiationException
   */
  public static List<Dialog> buildDialogsFromClassList(
      ComponentNameTransformer transformer,
      List<CtClass> classList,
      ZipArchiveOutputStream zipOutputStream,
      Set<String> reservedNames,
      WidgetRegistry widgetRegistry,
      ClassLoader classLoader,
      ClassPool classPool,
      File buildDirectory,
      String componentPathBase,
      String defaultComponentPathSuffix)
      throws InvalidComponentClassException, InvalidComponentFieldException, OutputFailureException,
          IOException, ParserConfigurationException, TransformerException, ClassNotFoundException,
          CannotCompileException, NotFoundException, SecurityException, NoSuchFieldException,
          IllegalArgumentException, IllegalAccessException, InvocationTargetException,
          NoSuchMethodException, InstantiationException {

    final List<Dialog> dialogList = new ArrayList<Dialog>();

    for (CtClass curClass : classList) {
      ComponentMojoUtil.getLog().debug("Checking class for Component annotation " + curClass);

      boolean hasDialogFieldOrCQIncludeTab = false;
      for (CtField curField : ComponentMojoUtil.collectFields(curClass)) {
        if (curField.hasAnnotation(DialogField.class)) {
          hasDialogFieldOrCQIncludeTab = true;
          break;
        }
      }
      if (!hasDialogFieldOrCQIncludeTab) {
        for (CtMethod curMethod : ComponentMojoUtil.collectMethods(curClass)) {
          if (curMethod.hasAnnotation(DialogField.class)) {
            hasDialogFieldOrCQIncludeTab = true;
            break;
          }
        }
      }
      if (!hasDialogFieldOrCQIncludeTab) {
        Component componentAnnotation = (Component) curClass.getAnnotation(Component.class);
        for (Tab tab : componentAnnotation.tabs()) {
          if (StringUtils.isNotEmpty(tab.path())) {
            hasDialogFieldOrCQIncludeTab = true;
            break;
          }
        }
      }
      if (hasDialogFieldOrCQIncludeTab) {
        ComponentMojoUtil.getLog().debug("Processing Component Class " + curClass);
        Dialog builtDialog = DialogFactory.make(curClass, widgetRegistry, classLoader, classPool);
        dialogList.add(builtDialog);
        File dialogFile =
            writeDialogToFile(
                transformer,
                builtDialog,
                curClass,
                buildDirectory,
                componentPathBase,
                defaultComponentPathSuffix);
        writeDialogToArchiveFile(
            transformer,
            dialogFile,
            curClass,
            zipOutputStream,
            reservedNames,
            componentPathBase,
            defaultComponentPathSuffix);
      }
    }

    return dialogList;
  }