private boolean canDelete(Object theLangObj) {
    boolean result = true;
    LanguageObject parent = (LanguageObject) contentProvider.getParent(theLangObj);

    if (parent == null) {
      // object is root. can only delete if not undefined
      result = !isUndefined(theLangObj);
    } else if (parent instanceof Function) {
      // all function arguments except converstion type constants can be deleted
      if (theLangObj instanceof Constant) {
        result = !BuilderUtils.isConversionType((Constant) theLangObj);
      }
    } else if (parent instanceof NotCriteria) {
      // get compound criteria and ask again
      NotCriteria notCrit = (NotCriteria) parent;
      Criteria criteria = notCrit.getCriteria();

      // NotCriteria must contain either another NotCriteria or a CompoundCriteria
      while (!(criteria instanceof CompoundCriteria)) {
        // must be a NotCriteria
        criteria = ((NotCriteria) criteria).getCriteria();
        result = canDelete(criteria);
      }
    }

    return result;
  }
 @Override
 public void visit(NotCriteria obj) {
   preVisitVisitor(obj);
   visitNode(obj.getCriteria());
   postVisitVisitor(obj);
 }
  private void delete(Object theLangObj) {
    if (canDelete(theLangObj)) {
      boolean doSelect = true;

      //
      // set the parent object to reflect the change in it's child. parent can't be undefined.
      //

      Object newSelection = StructuredSelection.EMPTY;
      LanguageObject parent = (LanguageObject) contentProvider.getParent(theLangObj);

      if (parent == null) {
        // object being delete is root language object
        setLanguageObject(null); // resets undefined count
        refresh(true);
        newSelection = contentProvider.getRoot();
        expandToLevel(newSelection, ALL_LEVELS);
      } else if (parent instanceof Function) {
        // set the arg to null in parent
        int index = contentProvider.getChildIndex(theLangObj);

        Expression[] args = ((Function) parent).getArgs();
        args[index] = null;

        refresh(true);
        newSelection = contentProvider.getChildAt(index, parent);
      } else if (parent instanceof Criteria) {
        if (contentProvider.getChildCount(parent) > 1) {
          CompoundCriteria compoundCriteria = null;

          // parent is either a compound criteria or not criteria
          if (parent instanceof CompoundCriteria) {
            compoundCriteria = (CompoundCriteria) parent;
          } else { // NotCriteria
            NotCriteria notCrit = (NotCriteria) parent;
            Criteria criteria = notCrit.getCriteria();

            // NotCriteria must contain either another NotCriteria or a CompoundCriteria
            while (!(criteria instanceof CompoundCriteria)) {
              // must be a NotCriteria
              criteria = ((NotCriteria) criteria).getCriteria();
            }

            compoundCriteria = (CompoundCriteria) criteria;
          }

          List crits = compoundCriteria.getCriteria();
          int index = contentProvider.getChildIndex(theLangObj);

          // CompoundCriteria has to have at least 2 criteria to be compound. if it has more than 2
          // just delete the selected obj. if there are exactly 2 criteria than this special
          // processing block occurs.
          if (contentProvider.getChildCount(parent) == 2) {
            int siblingIndex = (index == 0) ? 1 : 0;

            // if deleting this node would leave just an undefined node under the parent, delete
            // parent
            if (isUndefined(contentProvider.getChildAt(siblingIndex, parent))) {
              delete(parent);
            } else {
              // sibling is not undefined

              // if deleting an undefined node, delete from parent. this will leave one node
              // under the parent.
              if (isUndefined(theLangObj)) {
                crits.remove(index);
                // selection taken care of below in block checking for size of 1
              } else {
                // replace deleted node with undefined node
                crits.set(index, (Criteria) null);
                refresh(true);
                newSelection = contentProvider.getChildAt(index, parent);
              }
            }
          } else {
            // just remove from parent
            crits.remove(index);
            refresh(true);
            newSelection = parent;
          }

          if (crits.size() == 1) {
            // need to modify parent node with the child (refresh done there)
            modifyLanguageObject(
                parent, (LanguageObject) contentProvider.getChildAt(0, parent), false);
            doSelect = false; // modify does select
          }
        }
      }

      if (doSelect) {
        final Object selection = newSelection;

        Display.getDefault()
            .asyncExec(
                new Runnable() {
                  public void run() {
                    setSelection(new StructuredSelection(selection));
                  }
                });
      }
    }
  }