private int findMissingDIElements(
      DiagramElementTreeNode missing, LaneSet laneSet, List<FlowElement> laneElements) {
    int added = 0;
    if (laneSet != null) {
      for (Lane lane : laneSet.getLanes()) {
        // create the missing tree node for this Lane's container
        // this is either a FlowElementsContainer or another Lane
        BaseElement container = (BaseElement) lane.eContainer().eContainer();
        DiagramElementTreeNode containerNode = missing.getChild(container);
        if (containerNode == null) containerNode = missing.addChild(container);
        DiagramElementTreeNode parentNode = containerNode.addChild(lane);

        for (FlowNode fn : lane.getFlowNodeRefs()) {
          if (isMissingDIElement(fn)) {
            parentNode.addChild(fn);
            laneElements.add(fn);
            ++added;
          }
        }
        added += findMissingDIElements(parentNode, lane.getChildLaneSet(), laneElements);

        if (added == 0) {
          containerNode.removeChild(lane);
          missing.removeChild(container);
        }
      }
    }
    return added;
  }
  private void findMissingDIElements(DiagramElementTreeNode missing, BaseElement be) {
    if (be instanceof FlowElementsContainer) {
      // handles Process/SubProcess and Choreography/SubChoreography
      FlowElementsContainer container = (FlowElementsContainer) be;
      DiagramElementTreeNode parentNode = null;

      List<FlowElement> laneElements = new ArrayList<FlowElement>();
      for (LaneSet laneSet : container.getLaneSets()) {
        findMissingDIElements(missing, laneSet, laneElements);
      }

      for (FlowElement fe : container.getFlowElements()) {
        if (isMissingDIElement(fe) && !laneElements.contains(fe)) {
          if (fe instanceof SequenceFlow || fe instanceof DataObject || fe instanceof DataStore)
            continue;
          if (parentNode == null) parentNode = missing.addChild(container);
          parentNode.addChild(fe);
          if (fe instanceof FlowElementsContainer || fe instanceof ChoreographyActivity) {
            findMissingDIElements(parentNode, fe);
          }
        }
      }
      List<Artifact> artifacts = getArtifacts(container);
      if (artifacts != null) {
        for (Artifact a : artifacts) {
          if (isMissingDIElement(a) && !(a instanceof Association)) {
            if (parentNode == null) parentNode = missing.addChild(container);
            parentNode.addChild(a);
          }
        }
      }
    }

    // Choreography inherits both Collaboration and FlowElementsContainer
    if (be instanceof Collaboration) {
      // also handle Choreography
      Collaboration container = (Collaboration) be;
      DiagramElementTreeNode parentNode = null;
      for (Artifact a : container.getArtifacts()) {
        if (isMissingDIElement(a) && !(a instanceof Association)) {
          if (parentNode == null) parentNode = missing.addChild(container);
          parentNode.addChild(a);
        }
      }
      for (Participant p : container.getParticipants()) {
        boolean isParticipantBand = false;
        if (p.eContainer() instanceof Choreography) {
          // this may be a Choreography Activity Participant band
          Choreography choreography = (Choreography) p.eContainer();
          for (FlowElement fe : choreography.getFlowElements()) {
            if (fe instanceof ChoreographyActivity) {
              if (((ChoreographyActivity) fe).getParticipantRefs().contains(p)) {
                isParticipantBand = true;
                break;
              }
            }
          }
        }
        if (isMissingDIElement(p)
            && p.getProcessRef() != null
            && isMissingDIElement(p.getProcessRef())
            && !isParticipantBand) {
          if (parentNode == null) parentNode = missing.addChild(container);
          parentNode.addChild(p);
        }
      }
      for (ConversationNode c : container.getConversations()) {
        if (isMissingDIElement(c)) {
          if (parentNode == null) parentNode = missing.addChild(container);
          parentNode.addChild(c);
        }
      }
    } else if (be instanceof Participant) {
      Participant container = (Participant) be;
      if (container.getProcessRef() != null) {
        DiagramElementTreeNode parentNode = missing.addChild(container);
        parentNode.addChild(container.getProcessRef());
      }
    } else if (be instanceof ChoreographyActivity) {
      ChoreographyActivity container = (ChoreographyActivity) be;
      DiagramElementTreeNode parentNode = null;
      for (Participant p : container.getParticipantRefs()) {
        if (isMissingDIElement(p)) {
          if (parentNode == null) parentNode = missing.addChild(container);
          DiagramElementTreeNode child = parentNode.addChild(p);
          if (p.getProcessRef() != null) findMissingDIElements(child, p.getProcessRef());
        }
      }
    } else if (isDataElement(be)) {
      if (isMissingDIElement(be)) {
        missing.addChild(be);
      }
    }
  }