public void removeEvaObjects(
     String evaName, String targetClass, SimpleNode expression, ParserAdapter scda)
     throws Exception {
   ClassDef targetClassDef = scda.getClass(targetClass);
   WDBObject[] matchingObjs = targetClassDef.search(expression, scda);
   removeEvaObjects(evaName, targetClass, matchingObjs, scda);
 }
  public void removeEvaObjects(
      String evaName, String targetClass, WDBObject[] targetObjects, ParserAdapter scda)
      throws Exception {
    // Don't do anything if the target objects to remove is null
    if (targetObjects != null) {
      ClassDef myClass = this.getClassDef(scda);
      Attribute myAttribute = myClass.getAttribute(evaName);
      if (myAttribute != null && myAttribute.getClass() == EVA.class) {
        ClassDef targetClassDef = scda.getClass(targetClass);
        if (targetClassDef.name.equals(((EVA) myAttribute).baseClassName)
            || targetClassDef.isSubclassOf((((EVA) myAttribute).baseClassName), scda)) {
          ClassDef baseClassDef = scda.getClass(((EVA) myAttribute).baseClassName);
          WDBObject baseObject;
          for (int i = 0; i < targetObjects.length; i++) {
            // See if we can remove it from our end first
            if (this.removeEvaObject((EVA) myAttribute, targetObjects[i], scda)) {
              // Get the object that belongs to the base class of the EVA
              if ((((EVA) myAttribute).baseClassName).equals(targetClassDef.name)) {
                baseObject = targetObjects[i];
              } else {
                baseObject =
                    targetObjects[i].getParentObject((((EVA) myAttribute).baseClassName), scda);
              }
              // Get the inverse EVA, if there is one
              Attribute inverseAttribute =
                  baseClassDef.getAttribute(((EVA) myAttribute).inverseEVA);
              // Put myself as a reference in the target's EVA
              if (inverseAttribute != null && inverseAttribute.getClass() == EVA.class) {
                baseObject.removeEvaObject((EVA) inverseAttribute, this, scda);
              } else {
                throw new Exception("Implication of target class inverse EVAs is not implemented");
              }
              // Update the object
              baseObject.commit(scda);
            }
          }
        }
      }
      // Not immediate, go check parents if I'm an object of a subclass
      else if (myClass.getClass() == SubclassDef.class) {
        Enumeration e = parents.keys();
        while (true) {
          try {
            String parentClass = (String) e.nextElement();
            Integer parentUid = (Integer) parents.get(parentClass);
            WDBObject parent = scda.getObject(parentClass, parentUid);

            parent.removeEvaObjects(evaName, targetClass, targetObjects, scda);
            // If we reached here, we set our value. Get out of here
            break;
          } catch (NoSuchFieldException nsfe) {
            // Can't find DVA going up that parent's heirarchy. Continue on to another parent
            if (!e.hasMoreElements()) {
              // No more parents to try. We are here if we exausted our parent's list and
              // still can't find the DVA. Throw exception
              throw nsfe;
            }
          }
        }
      }
      // value can't be found and I'm not a subclass. It doesn't exist in this heirarchy
      else {
        throw new NoSuchFieldException("Attribute \"" + evaName + "\" is not a valid EVA");
      }

      this.commit(scda);
    }
  }
 public ClassDef getClassDef(ParserAdapter scda) throws Exception {
   return scda.getClass(this.classDefName);
 }