/**
   * Allocate a superBlock
   *
   * @param parentGraph the base graph
   * @param selection the selected blocks
   * @return the allocated super block (without specific listeners)
   */
  private SuperBlock allocateSuperBlock(final XcosDiagram parentGraph, final Object[] selection) {
    final SuperBlock superBlock = (SuperBlock) BlockFactory.createBlock(INTERFUNCTION_NAME);
    superBlock.setStyle(INTERFUNCTION_NAME);

    /*
     * Allocate the diagram
     */
    final SuperBlockDiagram diag = new SuperBlockDiagram(superBlock);
    superBlock.setChild(diag);
    superBlock.setParentDiagram(parentGraph);

    /*
     * Place the super block
     */
    final mxRectangle dims = parentGraph.getBoundingBoxFromGeometry(selection);
    final double minX = dims.getX();
    final double maxX = minX + dims.getWidth();

    final double minY = dims.getY();
    final double maxY = minY + dims.getHeight();

    superBlock.getGeometry().setX((maxX + minX - superBlock.getGeometry().getWidth()) / 2.0);
    superBlock.getGeometry().setY((maxY + minY - superBlock.getGeometry().getHeight()) / 2.0);

    /*
     * get statistics
     */
    int angleCounter = 0;
    int flipCounter = 0;
    int mirrorCounter = 0;
    for (Object object : selection) {
      if (object instanceof BasicBlock) {
        final BasicBlock b = (BasicBlock) object;

        angleCounter += b.getAngle();
        if (b.getFlip()) {
          flipCounter++;
        }
        if (b.getMirror()) {
          mirrorCounter++;
        }
      }
    }

    /*
     * apply statistics
     */
    final int halfSize = selection.length / 2;
    superBlock.setAngle(BlockPositioning.roundAngle(angleCounter / selection.length));
    superBlock.setFlip(flipCounter > halfSize);
    superBlock.setMirror(mirrorCounter > halfSize);

    return superBlock;
  }
  /**
   * Create child cells and add them to the parent diagram. All links are also reconnected
   *
   * @param parentGraph the parent diagram
   * @param superBlock the superblock
   * @param inSelectionCells the cells in the selection
   * @return the broken descriptor set
   */
  private Collection<Broken> updateParent(
      final XcosDiagram parentGraph,
      final SuperBlock superBlock,
      final Set<Object> inSelectionCells) {
    final Collection<Broken> brokenLinks;
    final mxGraphModel parentModel = (mxGraphModel) parentGraph.getModel();

    parentModel.beginUpdate();
    try {
      /*
       * Add the internal links and fill border links Sort the broken
       * links by position (to perform a good numbering order) and keep
       * only one occurrence of a broken link.
       */
      brokenLinks = new TreeSet<Broken>();
      fillLinks(parentModel, inSelectionCells, brokenLinks);

      /*
       * Disconnect the broken links
       */
      for (Broken broken : brokenLinks) {
        mxGraphModel.setTerminals(parentModel, broken.getParentLink(), null, null);
      }

      /*
       * Add the super block
       */
      parentGraph.addCell(superBlock);

      /*
       * Main broken loop
       */
      // ordering access is : IN, OUT, e_IN, e_OUT
      final int[] ordering = {0, 0, 0, 0};
      for (Broken broken : brokenLinks) {

        // set the ordering
        incrementOrdering(ordering, broken);

        connectParent(parentGraph, parentModel, superBlock, broken);
        connectChild(parentGraph, parentModel, broken);

        /*
         * Update the view
         */
        BlockPositioning.updateBlockView(broken.getChildBlock());
      }
    } finally {
      parentModel.endUpdate();
    }

    return brokenLinks;
  }
  /**
   * Move the cells to the child graph
   *
   * @param parentGraph the parent graph
   * @param superBlock the superBlock
   * @param brokenLinks the broken links set
   * @param inSelectionCells the cells in selection
   * @return the superblock child diagram
   */
  private SuperBlockDiagram moveToChild(
      final XcosDiagram parentGraph,
      final SuperBlock superBlock,
      final Collection<Broken> brokenLinks,
      final Set<Object> inSelectionCells) {
    final SuperBlockDiagram childGraph = superBlock.getChild();
    final mxGraphModel childModel = (mxGraphModel) childGraph.getModel();

    childModel.beginUpdate();
    try {
      final Collection<Object> cellsToCopy = new ArrayList<Object>();

      /*
       * create a collection with all the cells to move
       */
      cellsToCopy.addAll(inSelectionCells);
      for (Broken b : brokenLinks) {
        cellsToCopy.add(b.getChildBlock());
        cellsToCopy.add(b.getChildLink());
      }

      /*
       * Really copy the cells
       */
      final Object[] cells = cellsToCopy.toArray();
      parentGraph.removeCells(cells, false);
      childGraph.addCells(cells);

      childGraph.setChildrenParentDiagram();
      BlockPositioning.updateBlockView(superBlock);
    } finally {
      childModel.endUpdate();
    }

    return childGraph;
  }