public static boolean isInLane(FlowElement fe, LaneSet ls) {
    if (ls == null || ls.getLanes().size() == 0) return false;

    for (Lane ln : ls.getLanes()) {
      if (ln.getFlowNodeRefs().contains(fe)) return true;
      if (isInLane(fe, ln.getChildLaneSet())) return true;
    }
    return false;
  }
  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;
  }
 public void laneToTop(Lane lane) {
   LaneSet laneSet = FACTORY.createLaneSet();
   //		laneSet.setId(EcoreUtil.generateUUID());
   ModelUtil.setID(laneSet, resource);
   laneSet.getLanes().add(lane);
   Process process = getOrCreateProcess(getInternalParticipant());
   process.getLaneSets().add(laneSet);
 }
  private void modifyModelStructure(IMoveShapeContext context) {
    Lane movedLane = getMovedLane(context);
    Process sourceProcess = getProcess(context.getSourceContainer());
    Process targetProcess = getProcess(context.getTargetContainer());
    moveLane(movedLane, sourceProcess, targetProcess);

    for (LaneSet laneSet : sourceProcess.getLaneSets()) {
      if (laneSet.getLanes().contains(movedLane)) {
        laneSet.getLanes().remove(movedLane);
        if (laneSet.getLanes().isEmpty()) {
          sourceProcess.getLaneSets().remove(laneSet);
        }

        if (targetProcess.getLaneSets().isEmpty()) {
          LaneSet newLaneSet = createLaneSet();
          targetProcess.getLaneSets().add(newLaneSet);
        }
        targetProcess.getLaneSets().get(0).getLanes().add(movedLane);
        break;
      }
    }
  }
  private void modifyModelStructure(IMoveShapeContext context) {
    Lane movedLane = getMovedLane(context);
    Participant sourceParticipant =
        (Participant) getBusinessObjectForPictogramElement(context.getSourceContainer());
    Participant internalParticipant = null;

    try {
      ModelHandler handler = ModelHandler.getInstance(getDiagram());
      internalParticipant = handler.getInternalParticipant();
      handler.moveLane(movedLane, internalParticipant);
    } catch (IOException e) {
      Activator.logError(e);
    }

    LaneSet laneSet = null;
    for (LaneSet set : sourceParticipant.getProcessRef().getLaneSets()) {
      if (set.getLanes().contains(movedLane)) {
        laneSet = set;
        break;
      }
    }

    if (laneSet != null) {
      laneSet.getLanes().remove(movedLane);
      if (laneSet.getLanes().isEmpty()) {
        sourceParticipant.getProcessRef().getLaneSets().remove(laneSet);
      }

      Process process = internalParticipant.getProcessRef();
      if (process.getLaneSets().isEmpty()) {
        LaneSet createLaneSet = ModelHandler.FACTORY.createLaneSet();
        //				createLaneSet.setId(EcoreUtil.generateUUID());
        process.getLaneSets().add(createLaneSet);
        ModelUtil.setID(createLaneSet);
      }
      process.getLaneSets().get(0).getLanes().add(movedLane);
    }
  }
  public Lane createLane(Lane targetLane) {
    Lane lane = FACTORY.createLane();
    //		lane.setId(EcoreUtil.generateUUID());
    ModelUtil.setID(lane, resource);

    if (targetLane.getChildLaneSet() == null) {
      targetLane.setChildLaneSet(ModelHandler.FACTORY.createLaneSet());
    }

    LaneSet targetLaneSet = targetLane.getChildLaneSet();
    targetLaneSet.getLanes().add(lane);

    lane.getFlowNodeRefs().addAll(targetLane.getFlowNodeRefs());
    targetLane.getFlowNodeRefs().clear();

    return lane;
  }
  public static List<Object> getFlowElementsContainerChildren(FlowElementsContainer container) {
    List<Object> retList = new ArrayList<Object>();
    List<FlowElement> flowElements = new ArrayList<FlowElement>();
    for (FlowElement fe : container.getFlowElements()) {
      if (!(fe instanceof BoundaryEvent)) flowElements.add(fe);
    }

    if (container.getLaneSets().size() == 0) retList.addAll(flowElements);
    else {
      for (LaneSet ls : container.getLaneSets()) {
        retList.addAll(ls.getLanes());
      }
      // only add the flow element if it's not contained in a Lane
      List<Object> laneElements = new ArrayList<Object>();
      for (FlowElement fe : flowElements) {
        boolean inLane = false;
        for (LaneSet ls : container.getLaneSets()) {
          if (isInLane(fe, ls)) {
            inLane = true;
            break;
          }
        }
        if (inLane) laneElements.add(fe);
        else retList.add(fe);
      }

      // don't include any sequence flows that connect flow
      // nodes that are contained in Lanes
      List<SequenceFlow> flows = new ArrayList<SequenceFlow>();
      for (Object fn : laneElements) {
        if (fn instanceof FlowNode) {
          for (SequenceFlow sf : ((FlowNode) fn).getIncoming()) {
            if (laneElements.contains(sf.getSourceRef())
                && laneElements.contains(sf.getTargetRef())
                && !flows.contains(sf)) {
              flows.add(sf);
            }
          }
          for (SequenceFlow sf : ((FlowNode) fn).getOutgoing()) {
            if (laneElements.contains(sf.getSourceRef())
                && laneElements.contains(sf.getTargetRef())
                && !flows.contains(sf)) {
              flows.add(sf);
            }
          }
        }
      }
      retList.removeAll(flows);
    }

    // add the list of Artifacts
    if (container instanceof Process) {
      retList.addAll(((Process) container).getArtifacts());
    } else if (container instanceof SubProcess) {
      retList.addAll(((SubProcess) container).getArtifacts());
    }
    if (container instanceof SubChoreography) {
      retList.addAll(((SubChoreography) container).getArtifacts());
    }
    if (container instanceof Choreography) {
      // Add Pools as children if the Pool has a Process associated with it,
      // or if the Participant is NOT referenced by a Choreography Activity.
      for (Participant p : ((Choreography) container).getParticipants()) {
        if (p.getProcessRef() != null) retList.add(p);
        else {
          for (FlowElement fe : flowElements) {
            if (fe instanceof ChoreographyActivity) {
              if (!((ChoreographyActivity) fe).getParticipantRefs().contains(p)) {
                retList.add(p);
              }
            }
          }
        }
      }
    }
    return retList;
  }