/** Create a named container in this figure. */
  protected void createContainer(String name, Point position, Size size) {

    // Default colors.
    if (backgroundColor == null) backgroundColor = new Color(240, 240, 240);
    if (lineColor == null) lineColor = new Color(0, 0, 0);
    if (fontColor == null) fontColor = new Color(0, 0, 0);

    // Draw the rounded rectangle.
    RoundedRectangleShape shape =
        new RoundedRectangleShape(size.getWidth(), size.getHeight(), cornerRadius);
    shape.defineLineStyle(lineWidth, lineColor);
    shape.defineFillStyle(backgroundColor);
    shape.setRightFillStyle(1);
    shape.setLineStyle(1);
    shape.draw();

    addSymbol(shape, position);

    int gap = 2;

    // Draw the name label.
    if (name != null) {

      // Customize the label.
      if (useCustomizer && nameCustomizer != null) {
        String newName = nameCustomizer.getCustomizedName(getView(), name);
        if (newName != null) name = newName;
      }

      Point offset = new Point(-name.length() * 3 - 4, -size.getHeight() / 2 + fontSize + gap);
      addText(name, position.translate(offset), AnimationConstants.FONT_SIZE, fontColor);
    }

    // Draw an extra line.
    Shape line = new Shape();
    line.defineLineStyle(lineWidth, lineColor);
    line.setLineStyle(1);
    line.move(-size.getWidth() / 2, 0);
    line.line(size.getWidth() / 2, 0);
    Point offset = new Point(0, -size.getHeight() / 2 + fontSize + 4 * gap);
    addSymbol(line, position.translate(offset));
  }
  private Command getLayoutConstraintsCommand(boolean collapsed, Command initialCommand) {
    if (getHost() instanceof IResizableCompartmentEditPart
        && getHost().getParent() instanceof AbstractDiagramElementContainerEditPart) {
      AbstractDiagramElementContainerEditPart regionPart =
          (AbstractDiagramElementContainerEditPart) getHost().getParent();
      View notationView = regionPart.getNotationView();
      if (notationView instanceof Node
          && ((Node) notationView).getLayoutConstraint() instanceof Size
          && notationView.getElement() instanceof DDiagramElementContainer) {
        TransactionalEditingDomain editingDomain = getEditingDomain();
        CompositeTransactionalCommand ctc =
            new CompositeTransactionalCommand(
                editingDomain,
                collapsed
                    ? Messages
                        .RegionCollapseAwarePropertyHandlerEditPolicy_collapseRegionCommandLabel
                    : Messages
                        .RegionCollapseAwarePropertyHandlerEditPolicy_expandRegionCommandLabel);
        Command result = new ICommandProxy(ctc);
        if (initialCommand != null) {
          ctc.add(new CommandProxy(initialCommand));
        }

        Size size = (Size) ((Node) notationView).getLayoutConstraint();
        DDiagramElementContainer ddec = (DDiagramElementContainer) notationView.getElement();
        Iterable<AbsoluteBoundsFilter> boundsFilters =
            Iterables.filter(ddec.getGraphicalFilters(), AbsoluteBoundsFilter.class);
        AbsoluteBoundsFilter expandedBoundsMarker =
            Iterables.isEmpty(boundsFilters) ? null : boundsFilters.iterator().next();

        // Update GMF size
        Dimension newGmfSize = new Dimension(size.getWidth(), size.getHeight());
        int parentStackDirection = regionPart.getParentStackDirection();
        if (parentStackDirection == PositionConstants.NORTH_SOUTH) {
          if (!collapsed) {
            newGmfSize.setHeight(
                expandedBoundsMarker == null ? -1 : expandedBoundsMarker.getHeight());
          } else if (size.getHeight() != -1) {
            newGmfSize.setHeight(LayoutUtils.COLLAPSED_VERTICAL_REGION_HEIGHT);
          }
        } else if (parentStackDirection == PositionConstants.EAST_WEST) {
          if (!collapsed) {
            newGmfSize.setWidth(
                expandedBoundsMarker == null ? -1 : expandedBoundsMarker.getWidth());
          } else if (!isTruncatedLabel(regionPart)) {
            // Change the GMF width only when label is not truncated
            // to avoid to have a collapsed Region bigger than the
            // expanded size (resized by the user).
            // Do not specify a collapsed width as it will depend on
            // the label size.
            newGmfSize.setWidth(-1);
          }
        }

        SetBoundsCommand setBoundsCommand =
            new SetBoundsCommand(
                editingDomain,
                Messages.RegionCollapseAwarePropertyHandlerEditPolicy_gmfSizeUpdateCommandLabel,
                new EObjectAdapter(notationView),
                newGmfSize);
        ctc.add(setBoundsCommand);

        // Remember expanded size: create/update/remove an
        // AbsoluteBoundsFilter marker on the DDiagramElement.
        if (collapsed) {
          if (expandedBoundsMarker != null) {
            ctc.add(
                new GMFCommandWrapper(
                    editingDomain,
                    new SetCommand(
                        editingDomain,
                        expandedBoundsMarker,
                        DiagramPackage.eINSTANCE.getAbsoluteBoundsFilter_Height(),
                        size.getHeight())));
            ctc.add(
                new GMFCommandWrapper(
                    editingDomain,
                    new SetCommand(
                        editingDomain,
                        expandedBoundsMarker,
                        DiagramPackage.eINSTANCE.getAbsoluteBoundsFilter_Width(),
                        size.getWidth())));
          } else {
            expandedBoundsMarker = DiagramFactory.eINSTANCE.createAbsoluteBoundsFilter();
            expandedBoundsMarker.setHeight(size.getHeight());
            expandedBoundsMarker.setWidth(size.getWidth());
            ctc.add(
                new GMFCommandWrapper(
                    editingDomain,
                    new AddCommand(
                        editingDomain, ddec.getGraphicalFilters(), expandedBoundsMarker)));
          }
        } else if (expandedBoundsMarker != null) {
          ctc.add(
              new GMFCommandWrapper(
                  editingDomain,
                  new RemoveCommand(
                      editingDomain, ddec.getGraphicalFilters(), expandedBoundsMarker)));
        }

        return result;
      }
    }
    return initialCommand;
  }
 /** @generated */
 protected void refreshSemantic() {
   if (resolveSemanticElement() == null) {
     return;
   }
   LinkedList<IAdaptable> createdViews = new LinkedList<IAdaptable>();
   List<UMLNodeDescriptor> childDescriptors =
       UMLDiagramUpdater.getStateMachine_2000SemanticChildren((View) getHost().getModel());
   LinkedList<View> orphaned = new LinkedList<View>();
   // we care to check only views we recognize as ours
   LinkedList<View> knownViewChildren = new LinkedList<View>();
   for (View v : getViewChildren()) {
     if (isMyDiagramElement(v)) {
       knownViewChildren.add(v);
     }
   }
   // alternative to #cleanCanonicalSemanticChildren(getViewChildren(), semanticChildren)
   HashMap<UMLNodeDescriptor, LinkedList<View>> potentialViews =
       new HashMap<UMLNodeDescriptor, LinkedList<View>>();
   //
   // iteration happens over list of desired semantic elements, trying to find best matching View,
   // while original CEP
   // iterates views, potentially losing view (size/bounds) information - i.e. if there are few
   // views to reference same EObject, only last one
   // to answer isOrphaned == true will be used for the domain element representation, see
   // #cleanCanonicalSemanticChildren()
   for (Iterator<UMLNodeDescriptor> descriptorsIterator = childDescriptors.iterator();
       descriptorsIterator.hasNext(); ) {
     UMLNodeDescriptor next = descriptorsIterator.next();
     String hint = UMLVisualIDRegistry.getType(next.getVisualID());
     LinkedList<View> perfectMatch =
         new LinkedList<View>(); // both semanticElement and hint match that of NodeDescriptor
     LinkedList<View> potentialMatch =
         new LinkedList<View>(); // semanticElement matches, hint does not
     for (View childView : getViewChildren()) {
       EObject semanticElement = childView.getElement();
       if (next.getModelElement().equals(semanticElement)) {
         if (hint.equals(childView.getType())) {
           perfectMatch.add(childView);
           // actually, can stop iteration over view children here, but
           // may want to use not the first view but last one as a 'real' match (the way original
           // CEP does
           // with its trick with viewToSemanticMap inside #cleanCanonicalSemanticChildren
         } else {
           potentialMatch.add(childView);
         }
       }
     }
     if (perfectMatch.size() > 0) {
       descriptorsIterator
           .remove(); // precise match found no need to create anything for the NodeDescriptor
       // use only one view (first or last?), keep rest as orphaned for further consideration
       knownViewChildren.remove(perfectMatch.getFirst());
     } else if (potentialMatch.size() > 0) {
       potentialViews.put(next, potentialMatch);
     }
   }
   // those left in knownViewChildren are subject to removal - they are our diagram elements we
   // didn't find match to,
   // or those we have potential matches to, and thus need to be recreated, preserving
   // size/location information.
   orphaned.addAll(knownViewChildren);
   //
   CompositeTransactionalCommand boundsCommand =
       new CompositeTransactionalCommand(
           host().getEditingDomain(), DiagramUIMessages.SetLocationCommand_Label_Resize);
   ArrayList<CreateViewRequest.ViewDescriptor> viewDescriptors =
       new ArrayList<CreateViewRequest.ViewDescriptor>(childDescriptors.size());
   for (UMLNodeDescriptor next : childDescriptors) {
     String hint = UMLVisualIDRegistry.getType(next.getVisualID());
     IAdaptable elementAdapter = new CanonicalElementAdapter(next.getModelElement(), hint);
     CreateViewRequest.ViewDescriptor descriptor =
         new CreateViewRequest.ViewDescriptor(
             elementAdapter,
             Node.class,
             hint,
             ViewUtil.APPEND,
             false,
             host().getDiagramPreferencesHint());
     viewDescriptors.add(descriptor);
     LinkedList<View> possibleMatches = potentialViews.get(next);
     if (possibleMatches != null) {
       // from potential matches, leave those that were not eventually used for some other
       // NodeDescriptor (i.e. those left as orphaned)
       possibleMatches.retainAll(knownViewChildren);
     }
     if (possibleMatches != null && !possibleMatches.isEmpty()) {
       View originalView = possibleMatches.getFirst();
       knownViewChildren.remove(
           originalView); // remove not to copy properties of the same view again and again
       // add command to copy properties
       if (originalView instanceof Node) {
         if (((Node) originalView).getLayoutConstraint() instanceof Bounds) {
           Bounds b = (Bounds) ((Node) originalView).getLayoutConstraint();
           boundsCommand.add(
               new SetBoundsCommand(
                   boundsCommand.getEditingDomain(),
                   boundsCommand.getLabel(),
                   descriptor,
                   new Rectangle(b.getX(), b.getY(), b.getWidth(), b.getHeight())));
         } else if (((Node) originalView).getLayoutConstraint() instanceof Location) {
           Location l = (Location) ((Node) originalView).getLayoutConstraint();
           boundsCommand.add(
               new SetBoundsCommand(
                   boundsCommand.getEditingDomain(),
                   boundsCommand.getLabel(),
                   descriptor,
                   new Point(l.getX(), l.getY())));
         } else if (((Node) originalView).getLayoutConstraint() instanceof Size) {
           Size s = (Size) ((Node) originalView).getLayoutConstraint();
           boundsCommand.add(
               new SetBoundsCommand(
                   boundsCommand.getEditingDomain(),
                   boundsCommand.getLabel(),
                   descriptor,
                   new Dimension(s.getWidth(), s.getHeight())));
         }
       }
     }
   }
   boolean changed = deleteViews(orphaned.iterator());
   //
   CreateViewRequest request = getCreateViewRequest(viewDescriptors);
   Command cmd = getCreateViewCommand(request);
   if (cmd != null && cmd.canExecute()) {
     SetViewMutabilityCommand.makeMutable(new EObjectAdapter(host().getNotationView())).execute();
     executeCommand(cmd);
     if (boundsCommand.canExecute()) {
       executeCommand(new ICommandProxy(boundsCommand.reduce()));
     }
     @SuppressWarnings("unchecked")
     List<IAdaptable> nl = (List<IAdaptable>) request.getNewObject();
     createdViews.addAll(nl);
   }
   if (changed || createdViews.size() > 0) {
     postProcessRefreshSemantic(createdViews);
   }
   if (createdViews.size() > 1) {
     // perform a layout of the container
     DeferredLayoutCommand layoutCmd =
         new DeferredLayoutCommand(host().getEditingDomain(), createdViews, host());
     executeCommand(new ICommandProxy(layoutCmd));
   }
   makeViewsImmutable(createdViews);
 }