@Nullable
  public Object getData(String dataId) {

    if (CommonDataKeys.PROJECT.is(dataId)) {
      return editor != null ? editor.getProject() : null;
    } else if (CommonDataKeys.VIRTUAL_FILE.is(dataId)) {
      return editor != null ? editor.getFile() : null;
    } else if (CommonDataKeys.VIRTUAL_FILE_ARRAY.is(dataId)) {
      return editor != null ? new VirtualFile[] {editor.getFile()} : new VirtualFile[] {};
    } else if (CommonDataKeys.PSI_FILE.is(dataId)) {
      return getData(CommonDataKeys.PSI_ELEMENT.getName());
    } else if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
      VirtualFile file = editor != null ? editor.getFile() : null;
      return file != null && file.isValid()
          ? PsiManager.getInstance(editor.getProject()).findFile(file)
          : null;
    } else if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
      return editor != null
          ? new PsiElement[] {(PsiElement) getData(CommonDataKeys.PSI_ELEMENT.getName())}
          : new PsiElement[] {};
    } else if (PlatformDataKeys.COPY_PROVIDER.is(dataId) && copyPasteSupport != null) {
      return this;
    } else if (PlatformDataKeys.CUT_PROVIDER.is(dataId) && copyPasteSupport != null) {
      return copyPasteSupport.getCutProvider();
    } else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
      return deleteProvider;
    } else if (ImageComponentDecorator.DATA_KEY.is(dataId)) {
      return editor != null ? editor : this;
    }

    return null;
  }
  @Nullable
  @Override
  public Object getData(Collection<AbstractTreeNode> selected, String dataName) {
    if (selected == null) {
      return null;
    }

    if (PlatformDataKeys.COPY_PROVIDER.is(dataName) || PlatformDataKeys.CUT_PROVIDER.is(dataName)) {
      return getProvider(selected, CUT_COPY_PROVIDER_FACTORY);
    }
    if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataName)) {
      return getProvider(selected, DELETE_PROVIDER_FACTORY);
    }
    if (MPSDataKeys.MODEL_FILES.is(dataName)) {
      return getModelFiles(selected);
    }

    if (selected.size() != 1) {
      return null;
    }

    // Applicable only to single element selection
    AbstractTreeNode selectedNode = selected.iterator().next();

    if (PlatformDataKeys.VIRTUAL_FILE_ARRAY.is(dataName)) {
      return getModelFilesArray(selectedNode);
    }
    if (PlatformDataKeys.PASTE_PROVIDER.is(dataName)) {
      return getModelProvider(selectedNode, PASTE_PROVIDER_FACTORY);
    }
    if (MPSCommonDataKeys.NODE.is(dataName)) {
      return getNode(selectedNode);
    }
    if (MPSCommonDataKeys.CONTEXT_MODEL.is(dataName) || MPSCommonDataKeys.MODEL.is(dataName)) {
      return getModel(selectedNode);
    }
    if (MPSCommonDataKeys.CONTEXT_MODULE.is(dataName) || MPSCommonDataKeys.MODULE.is(dataName)) {
      return getModule(selectedNode);
    }
    if (LangDataKeys.MODULE.is(dataName)) {
      return getIdeaModule(selectedNode);
    }
    return null;
  }
 public void calcData(DataKey key, DataSink sink) {
   if (key == VcsDataKeys.CHANGES) {
     List<Change> list = getSelectedChanges();
     if (list.isEmpty()) list = getAllChanges();
     sink.put(VcsDataKeys.CHANGES, list.toArray(new Change[list.size()]));
   } else if (key == VcsDataKeys.CHANGES_SELECTION) {
     sink.put(VcsDataKeys.CHANGES_SELECTION, getChangesSelection());
   } else if (key == VcsDataKeys.CHANGE_LISTS) {
     sink.put(VcsDataKeys.CHANGE_LISTS, getSelectedChangeLists());
   } else if (key == VcsDataKeys.CHANGE_LEAD_SELECTION) {
     final Change highestSelection =
         ObjectUtils.tryCast(myViewer.getHighestLeadSelection(), Change.class);
     sink.put(
         VcsDataKeys.CHANGE_LEAD_SELECTION,
         (highestSelection == null) ? new Change[] {} : new Change[] {highestSelection});
   } else if (key == CommonDataKeys.VIRTUAL_FILE_ARRAY) {
     sink.put(CommonDataKeys.VIRTUAL_FILE_ARRAY, getSelectedFiles().toArray(VirtualFile[]::new));
   } else if (key == CommonDataKeys.NAVIGATABLE_ARRAY) {
     sink.put(
         CommonDataKeys.NAVIGATABLE_ARRAY, getNavigatableArray(myProject, getSelectedFiles()));
   } else if (VcsDataKeys.IO_FILE_ARRAY.equals(key)) {
     sink.put(VcsDataKeys.IO_FILE_ARRAY, getSelectedIoFiles());
   } else if (key == DATA_KEY) {
     sink.put(DATA_KEY, this);
   } else if (VcsDataKeys.SELECTED_CHANGES_IN_DETAILS.equals(key)) {
     final List<Change> selectedChanges = getSelectedChanges();
     sink.put(
         VcsDataKeys.SELECTED_CHANGES_IN_DETAILS,
         selectedChanges.toArray(new Change[selectedChanges.size()]));
   } else if (UNVERSIONED_FILES_DATA_KEY.equals(key)) {
     sink.put(
         UNVERSIONED_FILES_DATA_KEY,
         getVirtualFiles(myViewer.getSelectionPaths(), UNVERSIONED_FILES_TAG));
   } else if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.equals(key)) {
     sink.put(PlatformDataKeys.DELETE_ELEMENT_PROVIDER, myDeleteProvider);
   }
 }
 @Nullable
 protected DeleteProvider getDeleteProvider(DataContext dataContext) {
   return PlatformDataKeys.DELETE_ELEMENT_PROVIDER.getData(dataContext);
 }
  public Object getData(String dataId) {
    if (PlatformDataKeys.PROJECT.is(dataId)) {
      return myProject;
    }
    if (PlatformDataKeys.NAVIGATABLE.is(dataId)) {
      final FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors();
      return selectedNodeDescriptors.length == 1 ? selectedNodeDescriptors[0].getElement() : null;
    }
    if (PlatformDataKeys.NAVIGATABLE_ARRAY.is(dataId)) {
      final List<Navigatable> selectedElements = getSelectedElements(Navigatable.class);
      return selectedElements.toArray(new Navigatable[selectedElements.size()]);
    }

    if (PlatformDataKeys.CUT_PROVIDER.is(dataId)) {
      return myCopyPasteDelegator.getCutProvider();
    }
    if (PlatformDataKeys.COPY_PROVIDER.is(dataId)) {
      return myCopyPasteDelegator.getCopyProvider();
    }
    if (PlatformDataKeys.PASTE_PROVIDER.is(dataId)) {
      return myCopyPasteDelegator.getPasteProvider();
    }
    if (PlatformDataKeys.HELP_ID.is(dataId)) {
      return myHelpId;
    }
    if (LangDataKeys.PSI_ELEMENT.is(dataId)) {
      PsiElement[] elements = getSelectedPsiElements();
      if (elements.length != 1) {
        return null;
      }
      return elements[0] != null && elements[0].isValid() ? elements[0] : null;
    }
    if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
      final PsiElement[] elements = getSelectedPsiElements();
      ArrayList<PsiElement> result = new ArrayList<PsiElement>();
      for (PsiElement element : elements) {
        if (element.isValid()) {
          result.add(element);
        }
      }
      return result.isEmpty() ? null : result.toArray(new PsiElement[result.size()]);
    }

    if (LangDataKeys.IDE_VIEW.is(dataId)) {
      return myIdeView;
    }

    if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) {
      return null;
    }

    if (LangDataKeys.MODULE_CONTEXT.is(dataId)) {
      Module[] selected = getSelectedModules();
      return selected != null && selected.length == 1 ? selected[0] : null;
    }
    if (LangDataKeys.MODULE_CONTEXT_ARRAY.is(dataId)) {
      return getSelectedModules();
    }

    if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
      final Object[] elements = getSelectedNodeElements();
      return elements != null && elements.length >= 1 && elements[0] instanceof Module
          ? myDeleteModuleProvider
          : myDeletePSIElementProvider;
    }
    if (ModuleGroup.ARRAY_DATA_KEY.is(dataId)) {
      final List<ModuleGroup> selectedElements = getSelectedElements(ModuleGroup.class);
      return selectedElements.isEmpty()
          ? null
          : selectedElements.toArray(new ModuleGroup[selectedElements.size()]);
    }
    if (LibraryGroupElement.ARRAY_DATA_KEY.is(dataId)) {
      final List<LibraryGroupElement> selectedElements =
          getSelectedElements(LibraryGroupElement.class);
      return selectedElements.isEmpty()
          ? null
          : selectedElements.toArray(new LibraryGroupElement[selectedElements.size()]);
    }
    if (NamedLibraryElement.ARRAY_DATA_KEY.is(dataId)) {
      final List<NamedLibraryElement> selectedElements =
          getSelectedElements(NamedLibraryElement.class);
      return selectedElements.isEmpty()
          ? null
          : selectedElements.toArray(new NamedLibraryElement[selectedElements.size()]);
    }
    if (CONTEXT_FAVORITES_ROOTS_DATA_KEY.is(dataId)) {
      List<FavoritesTreeNodeDescriptor> result = new ArrayList<FavoritesTreeNodeDescriptor>();
      FavoritesTreeNodeDescriptor[] selectedNodeDescriptors = getSelectedNodeDescriptors();
      for (FavoritesTreeNodeDescriptor selectedNodeDescriptor : selectedNodeDescriptors) {
        FavoritesTreeNodeDescriptor root = selectedNodeDescriptor.getFavoritesRoot();
        if (root != null && !(root.getElement().getValue() instanceof String)) {
          result.add(root);
        }
      }
      return result.toArray(new FavoritesTreeNodeDescriptor[result.size()]);
    }
    if (FAVORITES_LIST_NAME_DATA_KEY.is(dataId)) {
      return myListName;
    }
    FavoritesTreeNodeDescriptor[] descriptors = getSelectedNodeDescriptors();
    if (descriptors.length > 0) {
      List<AbstractTreeNode> nodes = new ArrayList<AbstractTreeNode>();
      for (FavoritesTreeNodeDescriptor descriptor : descriptors) {
        nodes.add(descriptor.getElement());
      }
      return myFavoritesTreeStructure.getDataFromProviders(nodes, dataId);
    }
    return null;
  }