/**
   * Returns whether a classNode has the specified property or not
   *
   * @param classNode The ClassNode
   * @param propertyName The name of the property
   * @return True if the property exists in the ClassNode
   */
  public static boolean hasProperty(ClassNode classNode, String propertyName) {
    if (classNode == null || propertyName == null || "".equals(propertyName.trim())) return false;

    List properties = classNode.getProperties();
    for (Iterator i = properties.iterator(); i.hasNext(); ) {
      PropertyNode pn = (PropertyNode) i.next();
      if (pn.getName().equals(propertyName)) return true;
    }
    return false;
  }
 /**
  * Tests whether the ClassNode implements the specified method name
  *
  * @param classNode The ClassNode
  * @param methodName The method name
  * @param argTypes
  * @return True if it implements the method
  */
 private static boolean implementsMethod(
     ClassNode classNode, String methodName, Class[] argTypes) {
   List methods = classNode.getMethods();
   for (Iterator i = methods.iterator(); i.hasNext(); ) {
     MethodNode mn = (MethodNode) i.next();
     final boolean isZeroArg = (argTypes == null || argTypes.length == 0);
     boolean methodMatch = mn.getName().equals(methodName) && isZeroArg;
     if (methodMatch) return true;
     // TODO Implement further parameter analysis
   }
   return false;
 }
 private void injectAssociationProperties(ClassNode classNode, List propertiesToAdd) {
   for (Iterator i = propertiesToAdd.iterator(); i.hasNext(); ) {
     PropertyNode pn = (PropertyNode) i.next();
     if (! /*GrailsASTUtils.*/hasProperty(classNode, pn.getName())) {
       // if(LOG.isDebugEnabled()) {
       //    LOG.debug("[GrailsDomainInjector] Adding property [" + pn.getName() + "] to class [" +
       // classNode.getName() + "]");
       // }
       classNode.addProperty(pn);
     }
   }
 }
 private List createPropertiesForHasManyExpression(Expression e, ClassNode classNode) {
   List properties = new ArrayList();
   if (e instanceof MapExpression) {
     MapExpression me = (MapExpression) e;
     List mapEntries = me.getMapEntryExpressions();
     for (Iterator j = mapEntries.iterator(); j.hasNext(); ) {
       MapEntryExpression mee = (MapEntryExpression) j.next();
       Expression keyExpression = mee.getKeyExpression();
       String key = keyExpression.getText();
       addAssociationForKey(key, properties, classNode);
     }
   }
   return properties;
 }
  private Collection createPropertiesForBelongsToExpression(Expression e, ClassNode classNode) {
    List properties = new ArrayList();
    if (e instanceof MapExpression) {
      MapExpression me = (MapExpression) e;
      List mapEntries = me.getMapEntryExpressions();
      for (Iterator i = mapEntries.iterator(); i.hasNext(); ) {
        MapEntryExpression mme = (MapEntryExpression) i.next();
        String key = mme.getKeyExpression().getText();

        String type = mme.getValueExpression().getText();

        properties.add(
            new PropertyNode(
                key, Modifier.PUBLIC, ClassHelper.make(type), classNode, null, null, null));
      }
    }

    return properties;
  }
  private void injectAssociations(ClassNode classNode) {

    List properties = classNode.getProperties();
    List propertiesToAdd = new ArrayList();
    for (Iterator p = properties.iterator(); p.hasNext(); ) {
      PropertyNode pn = (PropertyNode) p.next();
      final boolean isHasManyProperty =
          pn.getName().equals(/*GrailsDomainClassProperty.*/ RELATES_TO_MANY)
              || pn.getName().equals(/*GrailsDomainClassProperty.*/ HAS_MANY);
      if (isHasManyProperty) {
        Expression e = pn.getInitialExpression();
        propertiesToAdd.addAll(createPropertiesForHasManyExpression(e, classNode));
      }
      final boolean isBelongsTo = pn.getName().equals(/*GrailsDomainClassProperty.*/ BELONGS_TO);
      if (isBelongsTo) {
        Expression e = pn.getInitialExpression();
        propertiesToAdd.addAll(createPropertiesForBelongsToExpression(e, classNode));
      }
    }
    injectAssociationProperties(classNode, propertiesToAdd);
  }