@Override
  public IReason updateNeeded(IUpdateContext context) {
    if (!canUpdate(context)) {
      return Reason.createFalseReason();
    }

    ContainerShape cs = (ContainerShape) context.getPictogramElement();
    Reference reference = (Reference) getBusinessObjectForPictogramElement(cs);

    // make sure the component still exists in the model
    if (!GraphitiInternal.getEmfService().isObjectAlive(reference)) {
      return Reason.createTrueReason(
          String.format("Reference {0} has been removed.", reference.getName()));
    }

    // retrieve name from pictogram model
    String pictogramName = null;
    Text foundText = GraphitiUtil.findChildGA(cs.getGraphicsAlgorithm(), Text.class);
    if (foundText != null) {
      pictogramName = foundText.getValue();
    }

    // update needed, if names are different
    String businessName = reference.getName();
    boolean updateNameNeeded =
        ((pictogramName == null && businessName != null)
            || (pictogramName != null && !pictogramName.contentEquals(businessName)));
    if (updateNameNeeded) {
      return Reason.createTrueReason("Reference name is out of date");
    }

    // check the wiring
    final Set<Contract> existingConnections = getExistingConnections(cs);
    for (ComponentReference promotedReference : reference.getPromote()) {
      if (promotedReference != null && !existingConnections.remove(promotedReference)) {
        return Reason.createTrueReason("Update connections.");
      }
    }

    if (existingConnections.size() > 0) {
      return Reason.createTrueReason("Update connections.");
    }

    return Reason.createFalseReason();
  }
  @Override
  public Object[] create(ICreateContext context) {
    Reference newReference = null;
    Composite composite =
        (Composite) getBusinessObjectForPictogramElement(context.getTargetContainer());
    BaseNewContractWizard wizard =
        new BaseNewContractWizard(
            Messages.title_newCompositeReference,
            Messages.description_newCompositeReference,
            ScaPackage.eINSTANCE.getReference());
    Shell shell = PlatformUI.getWorkbench().getActiveWorkbenchWindow().getShell();
    WizardDialog wizDialog = new WizardDialog(shell, wizard);
    wizard.init(composite);
    int rtn_code = wizDialog.open();
    if (rtn_code == Window.OK) {
      newReference = (Reference) wizard.getContract();
      newReference.setMultiplicity(Multiplicity._01);
    } else {
      _hasDoneChanges = false;
      return EMPTY;
    }

    composite.getReference().add(newReference);

    // do the add
    PictogramElement pe = addGraphicalRepresentation(context, newReference);
    if (pe instanceof Shape) {
      // make sure the new reference is positioned correctly.
      layoutPictogramElement(((Shape) pe).getContainer());
    }

    // make sure we look like we actually did something.
    _hasDoneChanges = true;

    // return newly created business object(s)
    return new Object[] {newReference};
  }
  @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;
  }