/**
   * Locate the AttributeGroup where the leaf attribute in the path should be applied to.
   *
   * @param create indicates if intermediate AttributeGroup required within the specified path
   *     should be created as needed. When checking the state of the map callers should set this to
   *     false to avoid changing the state unexpectedly
   */
  protected ATTRIBUTE_ITEM getItem(String[] attributePath, boolean create) {
    ATTRIBUTE_ITEM item = null;
    CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> currentGroup = this;

    for (int index = 0; index < attributePath.length; index++) {
      String attrName = attributePath[index];

      item = currentGroup.getItems().get(attrName);

      // Add missing AttributeGroup
      if (item == null) {
        // If not creating missing AttributeGroups then return null
        if (!create) {
          if (this.superClassGroup != null) {
            return (ATTRIBUTE_ITEM) this.superClassGroup.getItem(attributePath, create);
          }
          return null;
        }

        item = (ATTRIBUTE_ITEM) newItem(currentGroup, attrName);
        currentGroup.getItems().put(attrName, item);
      }

      // Add a AttributeGroup if not at the end of the attributes path
      if (item.getGroup() == null && index < (attributePath.length - 1)) {
        if (!create) {
          return null;
        }
        // XXX-dclarke: Converting the attribute[] into a string and then re-parsing it seems odd
        CoreAttributeGroup newGroup = newGroup(attrName, currentGroup);
        item.setRootGroup(newGroup);
      }

      currentGroup = item.getGroup();
    }

    return item;
  }
 @Override
 public boolean equals(Object obj) {
   if (this != obj) {
     if (obj == null) {
       return false;
     }
     CoreAttributeGroup anotherGroup = null;
     try {
       anotherGroup = (CoreAttributeGroup) obj;
     } catch (ClassCastException cce) {
       return false;
     }
     if (hasItems()) {
       if (anotherGroup.hasItems()) {
         if (!getItems().equals(anotherGroup.getItems())) {
           return false;
         }
       } else {
         return false;
       }
     } else {
       if (anotherGroup.hasItems()) {
         return false;
       }
     }
     if (this.superClassGroup != null) {
       if (anotherGroup.superClassGroup != null) {
         return this.superClassGroup.equals(anotherGroup.superClassGroup);
       } else {
         return false;
       }
     } else {
       if (anotherGroup.superClassGroup != null) {
         return false;
       }
       return true;
     }
   } else {
     return true;
   }
 }
 /** Return true if this AttributeGroup is a super-set of the passed in AttributeGroup. */
 public boolean isSupersetOf(CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> anotherGroup) {
   // TODO: should handle the case when the current group has all
   // attributes - then its equivalent to null
   if (anotherGroup == null) {
     return false;
   }
   if (anotherGroup != this) {
     if (hasItems()) {
       if (anotherGroup.hasItems()) {
         Iterator<Map.Entry<String, ATTRIBUTE_ITEM>> otherItemEntries =
             anotherGroup.getItems().entrySet().iterator();
         while (otherItemEntries.hasNext()) {
           Map.Entry<String, ATTRIBUTE_ITEM> otherItemEntry = otherItemEntries.next();
           String otherAttributeName = otherItemEntry.getKey();
           CoreAttributeItem item = this.items.get(otherAttributeName);
           if (item == null) {
             return false;
           }
           CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> group = item.getGroup();
           CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> otherGroup =
               otherItemEntry.getValue().getGroup();
           if (group != null) {
             if (!group.isSupersetOf(otherGroup)) {
               return false;
             }
           } else {
             if (otherGroup != null) {
               return true;
             }
           }
           group = item.getKeyGroup();
           otherGroup = otherItemEntry.getValue().getKeyGroup();
           if (group != null) {
             if (!group.isSupersetOf(otherGroup)) {
               return false;
             }
           } else {
             if (otherGroup != null) {
               return true;
             }
           }
           if (item.getGroups() != null) {
             if (otherItemEntry.getValue().getGroups() == null) {
               return true;
             }
             for (Object next : item.getGroups().values()) {
               CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> element =
                   (CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>) next;
               CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR> otherElement =
                   (CoreAttributeGroup<ATTRIBUTE_ITEM, DESCRIPTOR>)
                       otherItemEntry.getValue().getGroups().get(element.getType());
               if (!element.isSupersetOf(otherElement)) {
                 return false;
               }
             }
           }
           if (item.getKeyGroups() != null) {
             if (otherItemEntry.getValue().getKeyGroups() == null) {
               return true;
             }
             for (Object next : item.getKeyGroups().values()) {
               CoreAttributeGroup element = (CoreAttributeGroup) next;
               CoreAttributeGroup otherElement =
                   (CoreAttributeGroup)
                       otherItemEntry.getValue().getKeyGroups().get(element.getType());
               if (!element.isSupersetOf(otherElement)) {
                 return false;
               }
             }
           }
         }
         return true;
       } else {
         return true;
       }
     } else {
       if (anotherGroup.hasItems()) {
         return false;
       } else {
         return true;
       }
     }
   } else {
     return true;
   }
 }