private void pasteStack(BlockNode node) {
    //		====================>>>>>>>>>>>>>>>>>>>>>>>>>
    //		====================focus coming in>>>>>>>>>> TODO
    //		====================>>>>>>>>>>>>>>>>>>>>>>>>>
    if (node == null) {
      return;
    }
    WorkspaceWidget widget = null;
    Iterable<WorkspaceWidget> widgets = null;
    Point spot = null;
    if (invalidBlockID(focusManager.getFocusBlockID())) {
      // canvas has focus
      Point location =
          SwingUtilities.convertPoint(
              this.blockCanvas.getCanvas(), this.focusManager.getCanvasPoint(), workspace);
      widget = workspace.getWidgetAt(location);
      spot =
          SwingUtilities.convertPoint(
              this.blockCanvas.getCanvas(),
              this.focusManager.getCanvasPoint(),
              widget.getJComponent());
    } else {
      RenderableBlock focusRenderable =
          workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID());
      widget = focusRenderable.getParentWidget();
      spot = focusRenderable.getLocation();
    }

    if (widget == null) {
      // TODO: To be examined and fixed, occurs on macs
      JOptionPane.showMessageDialog(
          frame, "Please click somewhere on the canvas first.", "Error", JOptionPane.PLAIN_MESSAGE);
      // throw new RuntimeException("Why are we adding a block to a null widget?");
    } else {
      // checks to see if the copied block still exists
      if (BlockUtilities.blockExists(workspace, node)) {
        // create mirror block and mirror childrens
        spot.translate(10, 10);
        RenderableBlock mirror = BlockUtilities.makeRenderable(workspace, node, widget);
        mirror.setLocation(spot);
        mirror.moveConnectedBlocks(); // make sure the childrens are placed correctly
      } else {
        // TODO: future version, allow them to paste
        JOptionPane.showMessageDialog(
            frame,
            "You cannot paste blocks that are currently NOT on the canvas."
                + "\nThis function will be available in a future version.\n",
            "Error",
            JOptionPane.PLAIN_MESSAGE);
      }
    }
  }
 /**
  * @requires this.blockCanvas.getCanvas() != null
  * @param character
  */
 private void displayAutoCompletePanel(char character) {
   //		====================>>>>>>>>>>>>>>>>>>>>>>>>>
   //		====================focus coming in>>>>>>>>>> TODO
   //		====================>>>>>>>>>>>>>>>>>>>>>>>>>
   if (invalidBlockID(focusManager.getFocusBlockID())) {
     // canvas has focus
     this.blockCanvas.getCanvas().add(autoCompletePanel, JLayeredPane.DRAG_LAYER);
     autoCompletePanel.setLocation(this.focusManager.getCanvasPoint());
     autoCompletePanel.setVisible(true);
     autoCompletePanel.requestFocus();
   } else {
     // renderableblock has focus
     this.blockCanvas.getCanvas().add(autoCompletePanel, JLayeredPane.DRAG_LAYER);
     RenderableBlock block = workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID());
     Point location =
         SwingUtilities.convertPoint(
             block, this.focusManager.getBlockPoint(), this.blockCanvas.getCanvas());
     location.translate(10, 10);
     autoCompletePanel.setLocation(location);
     autoCompletePanel.setVisible(true);
     autoCompletePanel.requestFocus();
   }
   autoCompletePanel.setText(String.valueOf(character));
 }
 private void traverseFocus(Direction dir) {
   if (isNullBlockInstance(focusManager.getFocusBlockID())) {
     if (dir == Direction.UP) {
       blockCanvas.getVerticalModel().setValue(blockCanvas.getVerticalModel().getValue() - 5);
     } else if (dir == Direction.DOWN) {
       blockCanvas.getVerticalModel().setValue(blockCanvas.getVerticalModel().getValue() + 5);
     } else if (dir == Direction.LEFT) {
       blockCanvas.getHorizontalModel().setValue(blockCanvas.getHorizontalModel().getValue() - 5);
     } else if (dir == Direction.RIGHT) {
       blockCanvas.getHorizontalModel().setValue(blockCanvas.getHorizontalModel().getValue() + 5);
     } else if (dir == Direction.ESCAPE) {
       // according to the focus manager, the canvas already
       // has focus. So, just request focus again.
       this.blockCanvas.getCanvas().requestFocus();
     } else if (dir == Direction.ENTER) {
     }
   } else {
     if (dir == Direction.UP) {
       focusManager.focusBeforeBlock();
     } else if (dir == Direction.DOWN) {
       focusManager.focusAfterBlock();
     } else if (dir == Direction.LEFT) {
       focusManager.focusPrevBlock();
     } else if (dir == Direction.RIGHT) {
       focusManager.focusNextBlock();
     } else if (dir == Direction.ESCAPE) {
       RenderableBlock block =
           workspace.getEnv().getRenderableBlock(focusManager.getFocusBlockID());
       Point location =
           SwingUtilities.convertPoint(block, new Point(0, 0), this.blockCanvas.getCanvas());
       this.focusManager.setFocus(location, Block.NULL);
       this.blockCanvas.getCanvas().requestFocus();
     } else if (dir == Direction.ENTER) {
       workspace
           .getEnv()
           .getRenderableBlock(focusManager.getFocusBlockID())
           .switchToLabelEditingMode(true);
     }
   }
 }
  /**
   * @requires the current block with focus must exist with non-null ID in a non-null widget with a
   *     non-null parent
   * @modifies the current block with focus
   * @effects removes the current block with focus and children from the GUI and destroys the link
   *     between the block with focus and it's parent block if one exist and children blocks if it
   *     has childrens.
   */
  private void deleteBlockAndChildren() {
    //		====================>>>>>>>>>>>>>>>>>>>>>>>>>
    //		====================focus coming in>>>>>>>>>>TODO
    //		====================>>>>>>>>>>>>>>>>>>>>>>>>>

    // Do not delete null block references.  Otherwise, get Block and RenderableBlock instances.
    if (isNullBlockInstance(focusManager.getFocusBlockID())) {
      throw new RuntimeException("TypeBlockManager: deleting a null block references.");
    }
    Block block = workspace.getEnv().getBlock(focusManager.getFocusBlockID());
    RenderableBlock renderable = workspace.getEnv().getRenderableBlock(block.getBlockID());

    // get workspace widget associated with current focus
    WorkspaceWidget widget = renderable.getParentWidget();
    // do not delete block instances in null widgets
    if (widget == null) {
      throw new RuntimeException("TypeBlockManager: do not delete blocks with no parent widget.");
      // return;
    }
    // get parent container of this graphical representation
    Container container = renderable.getParent();
    // do not delete block instances in null parents
    if (container == null) {
      throw new RuntimeException(
          "TypeBlockManager: do not delete blocks with no parent container.");
      // return;
    }
    // get the Block's location on the canvas
    Point location =
        SwingUtilities.convertPoint(renderable, new Point(0, 0), this.blockCanvas.getCanvas());

    // for every valid and active connection, disconnect it.
    Long parentID = null;
    if (validConnection(block.getPlug())) {
      parentID = block.getPlugBlockID();
      this.disconnectBlock(block, widget);
      if (validConnection(block.getAfterConnector())) {
        disconnectBlock(workspace.getEnv().getBlock(block.getAfterBlockID()), widget);
      }
    } else if (validConnection(block.getBeforeConnector())) {
      parentID = block.getBeforeBlockID();
      BlockConnector parentConnectorToBlock =
          workspace.getEnv().getBlock(parentID).getConnectorTo(block.getBlockID());
      this.disconnectBlock(block, widget);
      if (validConnection(block.getAfterConnector())) {
        Long afterBlockID = block.getAfterBlockID();
        disconnectBlock(workspace.getEnv().getBlock(afterBlockID), widget);
        if (parentID != null) {
          BlockLink link =
              BlockLinkChecker.canLink(
                  workspace,
                  workspace.getEnv().getBlock(parentID),
                  workspace.getEnv().getBlock(afterBlockID),
                  parentConnectorToBlock,
                  workspace.getEnv().getBlock(afterBlockID).getBeforeConnector());
          if (link != null) {
            link.connect();
            workspace.notifyListeners(
                new WorkspaceEvent(
                    workspace,
                    workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).getParentWidget(),
                    link,
                    WorkspaceEvent.BLOCKS_CONNECTED));
            workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).repaintBlock();
            workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).repaint();
            workspace.getEnv().getRenderableBlock(link.getPlugBlockID()).moveConnectedBlocks();
            workspace.getEnv().getRenderableBlock(link.getSocketBlockID()).repaintBlock();
            workspace.getEnv().getRenderableBlock(link.getSocketBlockID()).repaint();
          }
        }
      }
    } else if (validConnection(block.getAfterConnector())) {
      parentID = block.getAfterBlockID();
    }

    // remove form widget and container
    this.removeChildrenBlock(renderable, widget, container);

    //		<<<<<<<<<<<<<<<<<<<<<<<<<<==========================
    //		<<<<<<<<<<<<<<<<<<<<<<<<<<focus changing, coming out TODO
    //		<<<<<<<<<<<<<<<<<<<<<<<<<<==========================
    // If the deleted block had a parent, give the parent the focus,
    // Otherwise, give the focus to the canvas (NOT BLOCK CANVAS)
    if (invalidBlockID(parentID)) {
      this.focusManager.setFocus(location, Block.NULL);
      this.blockCanvas.getCanvas().requestFocus();
      return;
    } else {
      this.focusManager.setFocus(parentID);
      this.blockCanvas.getCanvas().requestFocus();
      return;
    }
  }