/**
   * @param childBlock
   * @param widget
   * @requires widget != null
   * @modifies
   * @effects Does nothing if: childBlock is invalid (null) Otherwise, remove childBlock from it's
   *     parent block if the childBlock has a parent. If it does not have a parent, do nothing.
   */
  private void disconnectBlock(Block childBlock, WorkspaceWidget widget) {
    if (childBlock == null || invalidBlockID(childBlock.getBlockID())) {
      return;
    }
    BlockConnector childPlug = BlockLinkChecker.getPlugEquivalent(childBlock);
    if (childPlug == null || !childPlug.hasBlock() || isNullBlockInstance(childPlug.getBlockID())) {
      return;
    }
    Block parentBlock = workspace.getEnv().getBlock(childPlug.getBlockID());
    BlockConnector parentSocket = parentBlock.getConnectorTo(childBlock.getBlockID());
    if (parentSocket == null) {
      return;
    }
    // disconector if child connector exists and has a block connected to it
    BlockLink link =
        BlockLink.getBlockLink(workspace, childBlock, parentBlock, childPlug, parentSocket);
    if (link == null) {
      return;
    }

    link.disconnect();

    RenderableBlock parentRenderable =
        workspace.getEnv().getRenderableBlock(parentBlock.getBlockID());
    if (parentRenderable == null) {
      throw new RuntimeException(
          "INCONSISTANCY VIOLATION: "
              + "parent block was valid, non-null, and existed.\n\tBut yet, when we get it's renderable"
              + "representation, we recieve a null instance.\n\tIf the Block instance of an ID is non-null"
              + "then its graphical RenderableBlock should be non-null as well");
    }
    parentRenderable.blockDisconnected(parentSocket);
    workspace.notifyListeners(
        new WorkspaceEvent(workspace, widget, link, WorkspaceEvent.BLOCKS_DISCONNECTED));
  }