/**
   * Creates a docking path for the given dockable. It contains the information how the dockable is
   * docked now. The docking path is added to the docking path model of the docking manager.
   *
   * @param dockable The dockable for which a docking path has to be created.
   * @return The docking path model. Null if the dockable is not docked.
   */
  private DockingPath addDockingPath(Dockable dockable) {

    if (dockable.getDock() != null) {
      // Create the docking path of the dockable.
      DockingPath dockingPath = DefaultDockingPath.createDockingPath(dockable);
      DockingManager.getDockingPathModel().add(dockingPath);
      return dockingPath;
    }

    return null;
  }
  /**
   * Resets the cursor. Cleans up what was painted before. Searches a destination dock for the last
   * mouse location and tries to dock the dragged dockable in this dock.
   */
  public void stopDragging(MouseEvent mouseEvent) {

    // Reset the old cursor.
    cursorManager.resetCursor();

    // Clean up what was painted for dragging.
    dockableDragPainter.clear();

    // Get the mouse location in screen coordinates.
    computeScreenLocation(mouseEvent);

    // Do we have to move an externalized dockable?
    if (draggedDockable.getState() == DockableState.EXTERNALIZED) {
      // Move the dockable.
      ExternalizedDraggerSupport.moveExternalizedDockable(
          draggedDockable, screenLocation, dockableOffset);

      // No dragging anymore.
      reset();

      return;
    }

    // Get the destination dock.
    Dock[] destinationDocks =
        dockRetriever.retrieveHighestPriorityDock(screenLocation, draggedDockable);
    if (destinationDocks == null) {
      return;
    }
    Dock destinationDock = destinationDocks[0];

    // Is the destination dock different from the origin?
    if (destinationDock != null) {
      if (!destinationDock.equals(originDock)) {
        // Get the mouse location for the new dock.
        locationInDestinationDock.setLocation(screenLocation.x, screenLocation.y);
        if (destinationDock instanceof Component) {
          SwingUtilities.convertPointFromScreen(
              locationInDestinationDock, (Component) destinationDock);
        }

        // Check if we can move the dock of the dockable in the float dock.
        if (destinationDock instanceof FloatDock) {
          // Get the root dock and the dock under the root.
          Dock rootDock = originDock;
          Dock dockUnderRoot = null;
          while (rootDock.getParentDock() != null) {
            dockUnderRoot = rootDock;
            rootDock = rootDock.getParentDock();
          }

          // Is the root dock the float dock?
          if (rootDock instanceof FloatDock) {
            // Is the dockable already in this dock and are there no others?
            List childrenOfDockable = new ArrayList();
            List childrenOfDock = new ArrayList();
            DockingUtil.retrieveDockables(draggedDockable, childrenOfDockable);
            DockingUtil.retrieveDockables(dockUnderRoot, childrenOfDock);
            if (sameElements(childrenOfDockable, childrenOfDock)) {
              ((FloatDock) rootDock)
                  .moveDock(dockUnderRoot, locationInDestinationDock, dockableOffset);
              return;
            }
          }
        }

        // Get the real dockable in the model with this ID.
        Dockable dockableWrapper = DockingUtil.retrieveDockableOfDockModel(draggedDockable.getID());
        if (dockableWrapper == null) {
          throw new IllegalStateException(
              "The dragged dockable should be docked in the dock model.");
        }

        // Remove the dockable from the old dock, add to the new dock.
        // Use the docking manager for the addition and removal, because the listenenrs have to
        // informed.
        if (!originDock.equals(draggedDockable.getDock())) {
          throw new IllegalStateException("The origin dock is not the parent of the dockable.");
        }
        DockingManager.getDockingExecutor()
            .changeDocking(
                dockableWrapper, destinationDock, locationInDestinationDock, dockableOffset);

        // Clean the dock from which the dockable is removed.
        DockingManager.getDockingExecutor().cleanDock(originDock, false);

      } else {
        // Get the real dockable in the model with this ID.
        Dockable dockableWrapper = DockingUtil.retrieveDockableOfDockModel(draggedDockable.getID());
        if (dockableWrapper == null) {
          throw new IllegalStateException(
              "The dragged dockable should be docked in the dock model.");
        }

        // Move the dockable to a new position in the same dock.
        if (!originDock.equals(draggedDockable.getDock())) {
          throw new IllegalStateException("The origin dock is not the parent of the dockable.");
        }
        DockingManager.getDockingExecutor()
            .changeDocking(dockableWrapper, originDock, locationInDestinationDock, new Point(0, 0));
      }
    }

    // No dragging anymore.
    reset();
  }