protected static void createSPPFigure(
        SPPRef spp,
        boolean refspp,
        ContainerShape containerShape,
        GraphicsAlgorithm invisibleRectangle,
        Color darkColor,
        Color brightDolor) {

      boolean relay = ValidationUtil.isRelay(spp);

      int size = refspp ? ITEM_SIZE_SMALL : ITEM_SIZE;
      int line = refspp ? LINE_WIDTH / 2 : LINE_WIDTH;

      Color bg = brightDolor;
      if (refspp) {
        bg = darkColor;
      } else {
        if (relay) bg = brightDolor;
        else bg = darkColor;
      }

      IGaService gaService = Graphiti.getGaService();

      // TODOHRR: depicting SPPs as diamond using polygon didn't work
      //			int s2 = size/2;
      //			int xy[] = new int[] { s2, 0, size, s2, s2, size, 0, s2};
      //			Polygon rect = gaService.createPolygon(invisibleRectangle, xy);
      //			rect.setForeground(darkColor);
      //			rect.setBackground(bg);
      //			rect.setLineWidth(line);
      //			gaService.setLocation(rect, s2, s2);
      // Rectangle rect = gaService.createRectangle(invisibleRectangle);

      Ellipse rect = gaService.createEllipse(invisibleRectangle);
      rect.setForeground(darkColor);
      rect.setBackground(bg);
      rect.setLineWidth(line);
      gaService.setLocationAndSize(rect, size / 2, size / 2, size, size);

      if (containerShape.getAnchors().isEmpty()) {
        // here we place our anchor
        IPeCreateService peCreateService = Graphiti.getPeCreateService();
        //				FixPointAnchor anchor = peCreateService.createFixPointAnchor(containerShape);
        //				anchor.setLocation(gaService.createPoint(xy[0], xy[1]));
        //				anchor = peCreateService.createFixPointAnchor(containerShape);
        //				anchor.setLocation(gaService.createPoint(xy[2], xy[3]));
        //				anchor = peCreateService.createFixPointAnchor(containerShape);
        //				anchor.setLocation(gaService.createPoint(xy[4], xy[5]));
        //				anchor = peCreateService.createFixPointAnchor(containerShape);
        //				anchor.setLocation(gaService.createPoint(xy[6], xy[7]));
        // TODOHRR:  EllipseAnchor would be nice
        ChopboxAnchor anchor = peCreateService.createChopboxAnchor(containerShape);
        anchor.setReferencedGraphicsAlgorithm(rect);
      } else {
        // we just set the referenced GA
        // containerShape.getAnchors().get(0).setReferencedGraphicsAlgorithm(rect);
      }
    }
  public static void updateCategoryValues(IFeatureProvider fp, List<ContainerShape> shapes) {
    // Update CategoryValues for SequenceFlows also
    List<Connection> connections = new ArrayList<Connection>();
    for (ContainerShape cs : shapes) {
      updateCategoryValues(fp, cs);

      for (Anchor a : cs.getAnchors()) {
        for (Connection c : a.getIncomingConnections()) {
          if (!connections.contains(c)) connections.add(c);
        }
        for (Connection c : a.getOutgoingConnections()) {
          if (!connections.contains(c)) connections.add(c);
        }
      }
    }
    for (Connection c : connections) {
      updateCategoryValues(fp, c);
    }
  }
  private void drawAssociation(Association association, BpmnMemoryModel model) {

    Anchor sourceAnchor = null;
    Anchor targetAnchor = null;
    BaseElement sourceElement = model.getFlowElement(association.getSourceRef());
    if (sourceElement == null) {
      sourceElement = model.getArtifact(association.getSourceRef());
    }
    if (sourceElement == null) {
      return;
    }
    ContainerShape sourceShape =
        (ContainerShape)
            getDiagramTypeProvider()
                .getFeatureProvider()
                .getPictogramElementForBusinessObject(sourceElement);

    if (sourceShape == null) {
      return;
    }

    EList<Anchor> anchorList = sourceShape.getAnchors();
    for (Anchor anchor : anchorList) {
      if (anchor instanceof ChopboxAnchor) {
        sourceAnchor = anchor;
        break;
      }
    }

    BaseElement targetElement = model.getFlowElement(association.getTargetRef());
    if (targetElement == null) {
      targetElement = model.getArtifact(association.getTargetRef());
    }
    if (targetElement == null) {
      return;
    }
    ContainerShape targetShape =
        (ContainerShape)
            getDiagramTypeProvider()
                .getFeatureProvider()
                .getPictogramElementForBusinessObject(targetElement);

    if (targetShape == null) {
      return;
    }

    anchorList = targetShape.getAnchors();
    for (Anchor anchor : anchorList) {
      if (anchor instanceof ChopboxAnchor) {
        targetAnchor = anchor;
        break;
      }
    }

    AddConnectionContext addContext = new AddConnectionContext(sourceAnchor, targetAnchor);

    List<GraphicInfo> bendpointList = new ArrayList<GraphicInfo>();
    if (model.getBpmnModel().getFlowLocationMap().containsKey(association.getId())) {
      List<GraphicInfo> pointList =
          model.getBpmnModel().getFlowLocationGraphicInfo(association.getId());
      if (pointList.size() > 2) {
        for (int i = 1; i < pointList.size() - 1; i++) {
          bendpointList.add(pointList.get(i));
        }
      }
    }

    addContext.putProperty("org.activiti.designer.bendpoints", bendpointList);

    addContext.setNewObject(association);
    getDiagramTypeProvider().getFeatureProvider().addIfPossible(addContext);
  }
  protected void drawMessageFlows(
      final Collection<MessageFlow> messageFlows, final BpmnMemoryModel model) {

    for (final MessageFlow messageFlow : messageFlows) {

      Anchor sourceAnchor = null;
      Anchor targetAnchor = null;
      ContainerShape sourceShape =
          (ContainerShape)
              getDiagramTypeProvider()
                  .getFeatureProvider()
                  .getPictogramElementForBusinessObject(
                      model.getFlowElement(messageFlow.getSourceRef()));

      if (sourceShape == null) {
        continue;
      }

      EList<Anchor> anchorList = sourceShape.getAnchors();
      for (Anchor anchor : anchorList) {
        if (anchor instanceof ChopboxAnchor) {
          sourceAnchor = anchor;
          break;
        }
      }

      ContainerShape targetShape =
          (ContainerShape)
              getDiagramTypeProvider()
                  .getFeatureProvider()
                  .getPictogramElementForBusinessObject(
                      model.getFlowElement(messageFlow.getTargetRef()));

      if (targetShape == null) {
        continue;
      }

      anchorList = targetShape.getAnchors();
      for (Anchor anchor : anchorList) {
        if (anchor instanceof ChopboxAnchor) {
          targetAnchor = anchor;
          break;
        }
      }

      AddConnectionContext addContext = new AddConnectionContext(sourceAnchor, targetAnchor);

      List<GraphicInfo> bendpointList = new ArrayList<GraphicInfo>();
      if (model.getBpmnModel().getFlowLocationMap().containsKey(messageFlow.getId())) {
        List<GraphicInfo> pointList =
            model.getBpmnModel().getFlowLocationGraphicInfo(messageFlow.getId());
        if (pointList.size() > 2) {
          for (int i = 1; i < pointList.size() - 1; i++) {
            bendpointList.add(pointList.get(i));
          }
        }
      }
      addContext.putProperty("org.activiti.designer.bendpoints", bendpointList);
      addContext.putProperty(
          "org.activiti.designer.connectionlabel",
          model.getBpmnModel().getLabelGraphicInfo(messageFlow.getId()));

      addContext.setNewObject(messageFlow);
      getDiagramTypeProvider().getFeatureProvider().addIfPossible(addContext);
    }
  }
  @Override
  public boolean update(IUpdateContext context) {
    _hasDoneChanges = false;

    // retrieve name from business model
    ContainerShape cs = (ContainerShape) context.getPictogramElement();
    Reference reference = (Reference) getBusinessObjectForPictogramElement(cs);

    // remove it if it's gone
    if (!GraphitiInternal.getEmfService().isObjectAlive(reference)) {
      IRemoveContext removeContext = new RemoveContext(context.getPictogramElement());
      final IRemoveFeature removeFeature = getFeatureProvider().getRemoveFeature(removeContext);
      if (removeFeature != null && removeFeature.canRemove(removeContext)) {
        removeFeature.remove(removeContext);
        _hasDoneChanges = removeFeature.hasDoneChanges();
        return true;
      }
    }

    // Set name in pictogram model
    String pictogramName = null;
    Text foundText = GraphitiUtil.findChildGA(cs.getGraphicsAlgorithm(), Text.class);
    if (foundText != null) {
      pictogramName = foundText.getValue();
    }
    String businessName = reference.getName();
    boolean updateNameNeeded =
        ((pictogramName == null && businessName != null)
            || (pictogramName != null && !pictogramName.contentEquals(businessName)));
    if (updateNameNeeded) {
      foundText.setValue(businessName);
      _hasDoneChanges = true;
    }

    // update the wires
    final Set<Contract> existingConnections = getExistingConnections(cs);
    final Anchor anchor = cs.getAnchors().get(0);
    for (ComponentReference promotedReference : reference.getPromote()) {
      if (promotedReference != null && !existingConnections.remove(promotedReference)) {
        for (PictogramElement pe :
            getFeatureProvider().getAllPictogramElementsForBusinessObject(promotedReference)) {
          if (pe instanceof Anchor) {
            AddConnectionContext addContext = new AddConnectionContext((Anchor) pe, anchor);
            addContext.setNewObject(reference);
            updatePictogramElement(getFeatureProvider().addIfPossible(addContext));
            _hasDoneChanges = true;
            break;
          }
        }
      }
    }

    for (Connection connection : new ArrayList<Connection>(anchor.getIncomingConnections())) {
      Object bo = getBusinessObjectForPictogramElement(connection.getStart());
      if (bo == null || existingConnections.remove(bo)) {
        RemoveContext removeContext = new RemoveContext(connection);
        IRemoveFeature removeFeature = getFeatureProvider().getRemoveFeature(removeContext);
        if (removeFeature.canExecute(removeContext)) {
          removeFeature.execute(removeContext);
          _hasDoneChanges = _hasDoneChanges || removeFeature.hasDoneChanges();
        }
      }
    }

    return _hasDoneChanges;
  }