public void installDndSupport(ChangeListOwner owner) {
    myDragOwner = owner;
    myDropTarget = new DropTarget();
    myDndManager = DnDManager.getInstance();

    myDndManager.registerSource(this);
    myDndManager.registerTarget(myDropTarget, this);
  }
  @Override
  public void dispose() {
    if (myDropTarget != null) {
      myDndManager.unregisterSource(this);
      myDndManager.unregisterTarget(myDropTarget, this);

      myDropTarget = null;
      myDndManager = null;
      myDragOwner = null;
    }
  }
 @Override
 public void dispose() {
   if (myDndManager != null) {
     if (myDropTarget != null) {
       myDndManager.unregisterTarget(myDropTarget, myTree);
       myDropTarget = null;
     }
     if (myDragSource != null) {
       myDndManager.unregisterSource(myDragSource, myTree);
       myDragSource = null;
     }
     myDndManager = null;
   }
   setTreeBuilder(null);
   myTree = null;
   myTreeStructure = null;
 }
  protected void enableDnD() {
    if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
      myDropTarget =
          new ProjectViewDropTarget(
              myTree,
              new Retriever() {
                @Override
                public PsiElement getPsiElement(@Nullable TreeNode node) {
                  return getPSIElement(getElementFromTreeNode(node));
                }

                @Override
                public Module getModule(TreeNode treeNode) {
                  return getNodeModule(getElementFromTreeNode(treeNode));
                }
              },
              myProject);
      myDragSource = new MyDragSource();
      myDndManager = DnDManager.getInstance();
      myDndManager.registerSource(myDragSource, myTree);
      myDndManager.registerTarget(myDropTarget, myTree);
    }
  }
  protected final JTree createTree(boolean dndAware) {
    final Tree tree;
    final NullableFunction<Object, PsiElement> toPsiConverter =
        o -> {
          if (o instanceof HierarchyNodeDescriptor) {
            return ((HierarchyNodeDescriptor) o).getContainingFile();
          }
          return null;
        };

    if (dndAware) {
      tree =
          new DnDAwareTree(new DefaultTreeModel(new DefaultMutableTreeNode(""))) {
            @Override
            public void removeNotify() {
              super.removeNotify();
              if (ScreenUtil.isStandardAddRemoveNotify(this))
                myRefreshAction.unregisterCustomShortcutSet(this);
            }

            @Override
            public boolean isFileColorsEnabled() {
              return ProjectViewTree.isFileColorsEnabledFor(this);
            }

            @Override
            public Color getFileColorFor(Object object) {
              return ProjectViewTree.getColorForObject(object, myProject, toPsiConverter);
            }
          };

      if (!ApplicationManager.getApplication().isHeadlessEnvironment()) {
        DnDManager.getInstance()
            .registerSource(
                new DnDSource() {
                  @Override
                  public boolean canStartDragging(final DnDAction action, final Point dragOrigin) {
                    return getSelectedElements().length > 0;
                  }

                  @Override
                  public DnDDragStartBean startDragging(
                      final DnDAction action, final Point dragOrigin) {
                    return new DnDDragStartBean(
                        new TransferableWrapper() {
                          @Override
                          public TreeNode[] getTreeNodes() {
                            return tree.getSelectedNodes(TreeNode.class, null);
                          }

                          @Override
                          public PsiElement[] getPsiElements() {
                            return getSelectedElements();
                          }

                          @Override
                          public List<File> asFileList() {
                            return PsiCopyPasteManager.asFileList(getPsiElements());
                          }
                        });
                  }

                  @Override
                  public Pair<Image, Point> createDraggedImage(
                      final DnDAction action, final Point dragOrigin) {
                    return null;
                  }

                  @Override
                  public void dragDropEnd() {}

                  @Override
                  public void dropActionChanged(final int gestureModifiers) {}
                },
                tree);
      }
    } else {
      tree =
          new Tree(new DefaultTreeModel(new DefaultMutableTreeNode(""))) {
            @Override
            public void removeNotify() {
              super.removeNotify();
              if (ScreenUtil.isStandardAddRemoveNotify(this))
                myRefreshAction.unregisterCustomShortcutSet(this);
            }

            @Override
            public boolean isFileColorsEnabled() {
              return ProjectViewTree.isFileColorsEnabledFor(this);
            }

            @Override
            public Color getFileColorFor(Object object) {
              return ProjectViewTree.getColorForObject(object, myProject, toPsiConverter);
            }
          };
    }
    configureTree(tree);
    EditSourceOnDoubleClickHandler.install(tree);
    myRefreshAction.registerShortcutOn(tree);

    return tree;
  }