@Override
 public boolean canDelete(IDeleteContext context) {
   // Participant bands in a ChoreographyTask only be "deleted" (from the model)
   // if there are no other references to the participant; but they can be "removed"
   // (from the ChoreographyTask's participantRef list) at any time.
   // @see RemoveChoreographyParticipantFeature
   PictogramElement pe = context.getPictogramElement();
   if (ChoreographyUtil.isChoreographyParticipantBand(pe)) {
     int referenceCount = 0;
     Participant participant = BusinessObjectUtil.getFirstElementOfType(pe, Participant.class);
     Definitions definitions = ModelUtil.getDefinitions(participant);
     TreeIterator<EObject> iter = definitions.eAllContents();
     while (iter.hasNext()) {
       EObject o = iter.next();
       for (EReference reference : o.eClass().getEAllReferences()) {
         if (!reference.isContainment() && !(o instanceof DiagramElement)) {
           if (reference.isMany()) {
             List list = (List) o.eGet(reference);
             for (Object referencedObject : list) {
               if (referencedObject == participant) ++referenceCount;
             }
           } else {
             Object referencedObject = o.eGet(reference);
             if (referencedObject == participant) ++referenceCount;
           }
         }
       }
     }
     return referenceCount <= 1;
   }
   return true;
 }
  public static List<EObject> findMessageReferences(Diagram diagram, Message message) {
    List<EObject> result = new ArrayList<EObject>();
    Definitions definitions = ModelUtil.getDefinitions(message);
    TreeIterator<EObject> iter = definitions.eAllContents();
    while (iter.hasNext()) {
      EObject o = iter.next();
      if (o instanceof MessageFlow) {
        if (((MessageFlow) o).getMessageRef() == message) {
          result.add(o);
        }
      }
      if (o instanceof MessageEventDefinition) {
        if (((MessageEventDefinition) o).getMessageRef() == message) {
          result.add(o);
        }
      }
      if (o instanceof Operation) {
        if (((Operation) o).getInMessageRef() == message
            || ((Operation) o).getOutMessageRef() == message) {
          result.add(o);
        }
      }
      if (o instanceof ReceiveTask) {
        if (((ReceiveTask) o).getMessageRef() == message) {
          result.add(o);
        }
      }
      if (o instanceof SendTask) {
        if (((SendTask) o).getMessageRef() == message) {
          result.add(o);
        }
      }
      if (o instanceof CorrelationPropertyRetrievalExpression) {
        if (((CorrelationPropertyRetrievalExpression) o).getMessageRef() == message) {
          result.add(o);
        }
      }
    }

    if (diagram != null) {
      iter = diagram.eResource().getAllContents();
      while (iter.hasNext()) {
        EObject o = iter.next();
        if (o instanceof ContainerShape && !isLabelShape((ContainerShape) o)) {
          if (BusinessObjectUtil.getFirstBaseElement((ContainerShape) o) == message) result.add(o);
        }
      }
    }
    return result;
  }
  @Override
  protected List<Object> getModelChildren() {
    List<Object> retList = new ArrayList<Object>();
    FlowElement elem = getFlowElement();

    if (elem instanceof FlowElementsContainer) {
      FlowElementsContainer container = (FlowElementsContainer) elem;
      return getFlowElementsContainerChildren(container);
    } else if (elem instanceof ChoreographyActivity) {
      ChoreographyActivity ca = (ChoreographyActivity) elem;
      retList.addAll(ca.getParticipantRefs());
    } else if (elem instanceof CallActivity) {
      // render a Call Activity with its called element target
      // (a Process or Global Task) as the child node.
      CallableElement target = ((CallActivity) elem).getCalledElementRef();
      if (target != null) {
        retList.add(target);
      }
    } else if (elem instanceof CatchEvent) {
      retList.addAll(((CatchEvent) elem).getEventDefinitions());
      retList.addAll(((CatchEvent) elem).getDataOutputAssociation());
    } else if (elem instanceof ThrowEvent) {
      retList.addAll(((ThrowEvent) elem).getEventDefinitions());
      retList.addAll(((ThrowEvent) elem).getDataInputAssociation());
    }

    if (elem instanceof Activity) {
      // Boundary Events are children nodes of Activities
      Definitions definitions = ModelUtil.getDefinitions(elem);
      if (definitions != null) {
        TreeIterator<EObject> iter = definitions.eAllContents();
        while (iter.hasNext()) {
          EObject o = iter.next();
          if (o instanceof BoundaryEvent && ((BoundaryEvent) o).getAttachedToRef() == elem) {
            retList.add(o);
          }
        }
        retList.addAll(((Activity) elem).getDataInputAssociations());
        retList.addAll(((Activity) elem).getDataOutputAssociations());
      }
    }
    return retList;
  }
  private void createMissingDIElements(DiagramElementTree missing) {

    // look for any BPMN2 elements that do not have corresponding DI elements
    // and create DI elements for them. First, handle the BPMNShape objects:
    int x = 102400;
    int y = 0;
    List<BaseElement> shapes = new ArrayList<BaseElement>();
    for (DiagramElementTreeNode node : missing.getChildren()) {
      if (node.getChecked()) {
        BPMNShape bpmnShape = createMissingDIElement(node, x, y, shapes);
        if (bpmnShape != null) {
          y += bpmnShape.getBounds().getHeight() + 10;
        }
      }
    }

    // Next create the BPMNEdge objects. At this point, all of the source
    // and target elements for the connections should already exist, so
    // we don't have to worry about that.
    List<BaseElement> connections = new ArrayList<BaseElement>();
    for (BaseElement be : shapes) {
      if (be instanceof FlowNode) {
        FlowNode flowNode = (FlowNode) be;
        // find the BPMNDiagram that contains this flow node
        BPMNDiagram bpmnDiagram = createDIDiagram(flowNode);

        for (SequenceFlow sf : flowNode.getIncoming()) {
          if (!connections.contains(sf)) {
            BPMNEdge bpmnEdge = createDIEdge(bpmnDiagram, sf);
            if (bpmnEdge != null) connections.add(sf);
          }
        }

        for (SequenceFlow sf : flowNode.getOutgoing()) {
          if (!connections.contains(sf)) {
            BPMNEdge bpmnEdge = createDIEdge(bpmnDiagram, sf);
            if (bpmnEdge != null) connections.add(sf);
          }
        }
      } else if (be instanceof ConversationNode) {
        ConversationNode convNode = (ConversationNode) be;
        BPMNDiagram bpmnDiagram = createDIDiagram(convNode);
        for (MessageFlow mf : convNode.getMessageFlowRefs()) {
          if (!connections.contains(mf)) {
            BPMNEdge bpmnEdge = createDIEdge(bpmnDiagram, mf);
            if (bpmnEdge != null) connections.add(mf);
          }
        }
      }
    }
    // Finally, Associations are RootElements and since we only include shapes
    // in the missing elements tree, we'll have to revisit all of the RootElements
    TreeIterator<EObject> iter = definitions.eAllContents();
    while (iter.hasNext()) {
      EObject o = iter.next();
      if (o instanceof Association) {
        Association assoc = (Association) o;
        BPMNDiagram bpmnDiagram = createDIDiagram(assoc);
        BPMNEdge bpmnEdge = createDIEdge(bpmnDiagram, assoc);
        if (bpmnEdge != null) connections.add(assoc);
      }
    }
  }