public static List<ContainerShape> findGroupedShapes(ContainerShape groupShape) {
    Diagram diagram = null;
    EObject parent = groupShape.eContainer();
    while (parent != null) {
      if (parent instanceof Diagram) {
        diagram = (Diagram) parent;
        break;
      }
      parent = parent.eContainer();
    }

    // find all shapes that are inside this Group
    // these will be moved along with the Group
    List<ContainerShape> list = new ArrayList<ContainerShape>();
    if (diagram != null && isGroupShape(groupShape)) {
      TreeIterator<EObject> iter = diagram.eAllContents();
      while (iter.hasNext()) {
        EObject child = iter.next();
        if (child instanceof ContainerShape
            && child != groupShape
            && !list.contains(child)
            && !isLabelShape((ContainerShape) child)) {
          ContainerShape shape = (ContainerShape) child;
          if (isGroupShape(shape)) {
            if (GraphicsUtil.contains(groupShape, shape)) {
              if (!list.contains(shape)) {
                list.add(shape);
              }
            }
          } else if (GraphicsUtil.contains(groupShape, shape)) {
            if (!list.contains(shape)) {
              list.add(shape);
            }
            // find this shape's parent ContainerShape if it has one
            while (!(shape.getContainer() instanceof Diagram)) {
              shape = shape.getContainer();
            }
            if (!list.contains(shape) && shape != groupShape) {
              list.add(shape);
            }
          }
        }
      }
    }
    return list;
  }
 public static ContainerShape getRootContainer(ContainerShape container) {
   ContainerShape parent = container.getContainer();
   EObject bo = BusinessObjectUtil.getFirstElementOfType(parent, BaseElement.class);
   if (bo != null && (bo instanceof Lane || bo instanceof Participant)) {
     return getRootContainer(parent);
   }
   return container;
 }
  private Point getLocation(ContainerShape containerShape) {
    if (containerShape instanceof Diagram == true) {
      return new Point(
          containerShape.getGraphicsAlgorithm().getX(),
          containerShape.getGraphicsAlgorithm().getY());
    }

    Point location = getLocation(containerShape.getContainer());
    return new Point(
        location.x + containerShape.getGraphicsAlgorithm().getX(),
        location.y + containerShape.getGraphicsAlgorithm().getY());
  }
  @Override
  public void delete(IDeleteContext context) {
    ContainerShape laneContainerShape = (ContainerShape) context.getPictogramElement();
    ContainerShape parentContainerShape = laneContainerShape.getContainer();

    if (parentContainerShape != null) {
      boolean before = false;
      ContainerShape neighborContainerShape = FeatureSupport.getLaneAfter(laneContainerShape);
      if (neighborContainerShape == null) {
        neighborContainerShape = FeatureSupport.getLaneBefore(laneContainerShape);
        if (neighborContainerShape == null) {
          super.delete(context);
          return;
        } else {
          before = true;
        }
      }
      boolean isHorizontal = FeatureSupport.isHorizontal(laneContainerShape);
      GraphicsAlgorithm ga = laneContainerShape.getGraphicsAlgorithm();
      GraphicsAlgorithm neighborGA = neighborContainerShape.getGraphicsAlgorithm();
      ResizeShapeContext newContext = new ResizeShapeContext(neighborContainerShape);
      if (!before) {
        Graphiti.getGaService().setLocation(neighborGA, ga.getX(), ga.getY());
      }
      newContext.setLocation(neighborGA.getX(), neighborGA.getY());
      if (isHorizontal) {
        newContext.setHeight(neighborGA.getHeight() + ga.getHeight());
        newContext.setWidth(neighborGA.getWidth());
      } else {
        newContext.setHeight(neighborGA.getHeight());
        newContext.setWidth(neighborGA.getWidth() + ga.getWidth());
      }

      IResizeShapeFeature resizeFeature = getFeatureProvider().getResizeShapeFeature(newContext);
      if (resizeFeature.canResizeShape(newContext)) {
        super.delete(context);
        resizeFeature.resizeShape(newContext);
        return;
      }
    }
    super.delete(context);
  }
  // Creates the business object for the relationship
  @Override
  public Connection create(ICreateConnectionContext context) {
    Connection newConnection = null;
    // get TNodeTemplates which should be connected
    TNodeTemplate source = getTNodeTemplate(context.getSourceAnchor());
    TNodeTemplate target = getTNodeTemplate(context.getTargetAnchor());
    if (source != null && target != null) {
      // create new business object
      TRelationshipTemplate newClass = ToscaFactory.eINSTANCE.createTRelationshipTemplate();
      newClass.setName("Relation");
      newClass.setId(("R" + (Integer) newClass.hashCode()).toString());
      newClass.setType(new QName("Bidirected"));
      //      newClass.setType( new QName("Peer - Peer") );
      SourceElementType se = ToscaFactory.eINSTANCE.createSourceElementType();
      se.setRef(source.getId());
      newClass.setSourceElement(se);
      TargetElementType te = ToscaFactory.eINSTANCE.createTargetElementType();
      te.setRef(target.getId());
      newClass.setTargetElement(te);

      ContainerShape sourceContainer = (ContainerShape) context.getSourcePictogramElement();
      Object parentObject =
          getFeatureProvider().getBusinessObjectForPictogramElement(sourceContainer.getContainer());
      TServiceTemplate serviceTemplate = null;
      if (parentObject == null) return null;
      if (parentObject instanceof TServiceTemplate) {
        serviceTemplate = (TServiceTemplate) parentObject;
      }
      TTopologyTemplate topology = null;
      topology = serviceTemplate.getTopologyTemplate();
      topology.getRelationshipTemplate().add(newClass);
      // add connection for business object
      AddConnectionContext addContext =
          new AddConnectionContext(context.getSourceAnchor(), context.getTargetAnchor());
      addContext.setNewObject(newClass);
      newConnection = (Connection) getFeatureProvider().addIfPossible(addContext);
    }
    return newConnection;
  }
  protected ContainerShape createNewShape(
      ModelHandler mh, ContainerShape oldShape, EClass newType) {
    ILayoutService layoutService = Graphiti.getLayoutService();
    boolean horz = Bpmn2Preferences.getInstance().isHorizontalDefault();

    ILocation loc = layoutService.getLocationRelativeToDiagram(oldShape);
    int x = loc.getX();
    int y = loc.getY();
    int xOffset = 0;
    int yOffset = 0;
    GraphicsAlgorithm ga = oldShape.getGraphicsAlgorithm();
    int width = ga.getWidth();
    int height = ga.getHeight();

    BPMN2FeatureProvider fp = (BPMN2FeatureProvider) getFeatureProvider();
    AbstractCreateFeature createFeature =
        (AbstractCreateFeature) fp.getCreateFeatureForBusinessObject(newType.getInstanceClass());

    CreateContext createContext = new CreateContext();
    createContext.putProperty(AbstractCreateFlowElementFeature.SKIP_ADD_GRAPHICS, true);
    createContext.setTargetContainer(oldShape.getContainer());

    FlowElement newObject = null;
    if (createFeature != null) {
      newObject = (FlowElement) createFeature.create(createContext)[0];
    } else {
      newObject = (FlowElement) mh.create(newType);
    }

    ContainerShape containerShape = oldShape.getContainer();
    if (containerShape != getDiagram()) {
      // we are adding a new shape to a control (e.g a SubProcess)
      // so we need to adjust the location to be relative to the
      // control instead of the diagram
      loc = layoutService.getLocationRelativeToDiagram(containerShape);
      xOffset = loc.getX();
      yOffset = loc.getY();
    }
    BaseElement oldObject = BusinessObjectUtil.getFirstElementOfType(oldShape, BaseElement.class);

    if (oldObject instanceof Lane) {
      ((Lane) oldObject).getFlowNodeRefs().add((FlowNode) newObject);
    }
    AddContext ac = new AddContext(new AreaContext(), newObject);
    AbstractAddBpmnShapeFeature af =
        (AbstractAddBpmnShapeFeature) getFeatureProvider().getAddFeature(ac);
    int w = af.getDefaultWidth();
    int h = af.getDefaultHeight();
    if (horz) {
      x += width + 50 + w / 2;
      y += height / 2;
      boolean done = false;
      while (!done) {
        done = true;
        List<Shape> shapes = getFlowElementChildren(containerShape);
        for (Shape s : shapes) {
          if (GraphicsUtil.intersects(s, x - w / 2, y - h / 2, w, h)) {
            y += 100;
            done = false;
            break;
          }
        }
      }
    } else {
      x += width / 2;
      y += height + 50 + h / 2;
      boolean done = false;
      while (!done) {
        done = true;
        List<Shape> shapes = getFlowElementChildren(containerShape);
        for (Shape s : shapes) {
          if (GraphicsUtil.intersects(s, x - w / 2, y - h / 2, w, h)) {
            x += 100;
            done = false;
            break;
          }
        }
      }
    }
    ac.setX(x - xOffset);
    ac.setY(y - yOffset);
    ac.setTargetContainer(oldShape.getContainer());

    return (ContainerShape) getFeatureProvider().addIfPossible(ac);
  }