/**
   * Called when an IJavaElement changes. Used to reflect changes in the editor, which has a view
   * that is based on the <code>JavaModel</code>.
   *
   * @param event - The change that occurred to the <code>JavaModel</code>.
   */
  @SuppressWarnings("unchecked")
  public void elementChanged(ElementChangedEvent event) {
    try {
      /* Goes through these classes looking for any that are added, moved
       * or removed. Calls methods that updates the editor to reflect any
       * changes found.
       */
      for (Class type : map.keySet()) {
        List<IJavaElementDelta> added = findAddedElements(event.getDelta(), type);
        List<IJavaElementDelta> removed = findRemovedElements(event.getDelta(), type);
        List<IJavaElementDelta> changed = findChangedElements(event.getDelta(), type);
        HashMap<IJavaElement, IJavaElement> moved = extractMovedElements(added, removed);

        // ignore updating the editors if no changes occurred
        if (added.size() == 0 && removed.size() == 0 && moved.size() == 0 && changed.size() == 0) {
          continue;
        }

        List<DiagramEditor> editors = new ArrayList<DiagramEditor>(DiagramEditor.getEditors());

        // handle changes
        for (DiagramEditor editor : editors) {
          RootModel root = editor.getRootModel();

          // handle moves
          for (IJavaElement sourceElement : moved.keySet()) {
            IJavaElement targetElement = moved.get(sourceElement);
            map.get(sourceElement.getClass()).handleMove(root, sourceElement, targetElement);
          }

          // handle removes
          for (IJavaElementDelta removedElement : removed) {
            map.get(removedElement.getElement().getClass())
                .handleRemove(root, removedElement.getElement());
          }

          // handle adds
          for (IJavaElementDelta addedElement : added) {
            map.get(addedElement.getElement().getClass())
                .handleAdd(root, addedElement.getElement());
          }

          // handle changes (to modifiers, etc.)
          for (IJavaElementDelta changedElement : changed) {
            handleElementChange(changedElement);
          }

          editor.forceRefreshRelationships();
        }
      }
    } catch (Throwable t) {
      // TODO Incremental exploration throws Null Pointer.  Virtually unreproduceable.
      GreenException.critical(t);
    } finally {
      TypeRefactorHandler.REMOVED_TYPE = null;
    }
  }
  /** @see edu.buffalo.cse.green.editor.model.commands.DeleteCommand#doDelete() */
  public void doDelete() {
    RootModel root = _typeModel.getRootModel();

    // Remove relationships first
    List<RelationshipModel> rels = root.getRelationships();

    // No iterators here due to CME's (ConcurrentModificationException)
    // Removal of relationships causes modifications to the rels list.
    for (int i = 0; i < rels.size(); i++) {
      IType t = _typeModel.getType();
      RelationshipModel r = rels.get(i);
      if (r.getSourceType() == t || r.getTargetType() == t) {
        DeleteCommand drc = r.getDeleteCommand(DiagramEditor.findProjectEditor(root.getProject()));
        drc.suppressMessage(true);
        drc.execute();
      }
    }

    _typeModel.removeChildren(); // remove fields/methods
    _typeModel.removeFromParent();
    try {
      IType type = _typeModel.getType();
      ICompilationUnit cu = (ICompilationUnit) type.getAncestor(IJavaElement.COMPILATION_UNIT);

      if (type.equals(cu.findPrimaryType())) {
        cu.delete(true, PlugIn.getEmptyProgressMonitor());
      } else {
        type.delete(true, PlugIn.getEmptyProgressMonitor());
      }
    } catch (JavaModelException e) {
      e.printStackTrace();
    }
    root.updateRelationships();
  }
  /**
   * Updates the display when some change occurs to a Java element that doesn't involve removal,
   * addition, or movement.
   *
   * @param elementDelta - The delta of the element that changed.
   */
  private void handleElementChange(IJavaElementDelta elementDelta) {
    IJavaElement element = elementDelta.getElement();

    // update the modifiers of the element (if they changed)
    if ((elementDelta.getFlags() & IJavaElementDelta.F_MODIFIERS) != 0) {
      for (DiagramEditor editor : DiagramEditor.getEditors()) {
        RootPart rootEditPart = editor.getRootPart();
        RootModel root = (RootModel) rootEditPart.getModel();
        AbstractModel abstractModel = root.getModelFromElement(element);

        if (abstractModel != null) {
          if (abstractModel instanceof FieldModel) {
            FieldModel fModel = (FieldModel) abstractModel;
            FieldPart fEditPart = (FieldPart) rootEditPart.getPartFromModel(fModel);
            fEditPart.updateIcon();
          } else if (abstractModel instanceof MethodModel) {
            MethodModel mModel = (MethodModel) abstractModel;
            MethodPart mEditPart = (MethodPart) rootEditPart.getPartFromModel(mModel);
            mEditPart.updateIcon();
          }
        }
      }
    }
  }