/*
 * Copyright 2000-2014 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.intellij.ide.projectView.impl;

import com.intellij.ProjectTopics;
import com.intellij.history.LocalHistory;
import com.intellij.history.LocalHistoryAction;
import com.intellij.icons.AllIcons;
import com.intellij.ide.*;
import com.intellij.ide.actions.CollapseAllToolbarAction;
import com.intellij.ide.impl.ProjectViewSelectInTarget;
import com.intellij.ide.projectView.HelpID;
import com.intellij.ide.projectView.ProjectView;
import com.intellij.ide.projectView.ProjectViewNode;
import com.intellij.ide.projectView.impl.nodes.*;
import com.intellij.ide.scopeView.ScopeViewPane;
import com.intellij.ide.ui.SplitterProportionsDataImpl;
import com.intellij.ide.ui.UISettings;
import com.intellij.ide.util.DeleteHandler;
import com.intellij.ide.util.DirectoryChooserUtil;
import com.intellij.ide.util.EditorHelper;
import com.intellij.ide.util.treeView.AbstractTreeBuilder;
import com.intellij.ide.util.treeView.AbstractTreeNode;
import com.intellij.ide.util.treeView.NodeDescriptor;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.*;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.command.CommandProcessor;
import com.intellij.openapi.components.PersistentStateComponent;
import com.intellij.openapi.components.State;
import com.intellij.openapi.components.Storage;
import com.intellij.openapi.components.StoragePathMacros;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.Editor;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileEditor;
import com.intellij.openapi.fileEditor.FileEditorManager;
import com.intellij.openapi.fileEditor.TextEditor;
import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
import com.intellij.openapi.module.Module;
import com.intellij.openapi.module.ModuleUtilCore;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.roots.*;
import com.intellij.openapi.roots.ui.configuration.actions.ModuleDeleteProvider;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.ui.SimpleToolWindowPanel;
import com.intellij.openapi.ui.SplitterProportionsData;
import com.intellij.openapi.ui.popup.PopupChooserBuilder;
import com.intellij.openapi.util.*;
import com.intellij.openapi.util.text.StringUtil;
import com.intellij.openapi.vfs.JarFileSystem;
import com.intellij.openapi.vfs.LocalFileSystem;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.openapi.wm.*;
import com.intellij.openapi.wm.ex.ToolWindowEx;
import com.intellij.openapi.wm.ex.ToolWindowManagerAdapter;
import com.intellij.openapi.wm.ex.ToolWindowManagerEx;
import com.intellij.openapi.wm.impl.content.ToolWindowContentUi;
import com.intellij.psi.*;
import com.intellij.psi.impl.file.PsiDirectoryFactory;
import com.intellij.psi.util.PsiUtilCore;
import com.intellij.ui.AutoScrollFromSourceHandler;
import com.intellij.ui.AutoScrollToSourceHandler;
import com.intellij.ui.GuiUtils;
import com.intellij.ui.components.JBList;
import com.intellij.ui.content.Content;
import com.intellij.ui.content.ContentManager;
import com.intellij.ui.content.ContentManagerAdapter;
import com.intellij.ui.content.ContentManagerEvent;
import com.intellij.ui.switcher.QuickActionProvider;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IJSwingUtilities;
import com.intellij.util.PlatformIcons;
import com.intellij.util.messages.MessageBusConnection;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import gnu.trove.THashMap;
import gnu.trove.THashSet;
import org.jdom.Attribute;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.tree.DefaultMutableTreeNode;
import javax.swing.tree.DefaultTreeModel;
import javax.swing.tree.TreePath;
import java.awt.*;
import java.util.*;
import java.util.List;

@State(
  name="ProjectView",
  storages= {
    @Storage(
      file = StoragePathMacros.WORKSPACE_FILE
    )}
)
public class ProjectViewImpl extends ProjectView implements PersistentStateComponent<Element>, Disposable, QuickActionProvider, BusyObject  {
  private static final Logger LOG = Logger.getInstance("#com.intellij.ide.projectView.impl.ProjectViewImpl");
  private static final Key<String> ID_KEY = Key.create("pane-id");
  private static final Key<String> SUB_ID_KEY = Key.create("pane-sub-id");
  private final CopyPasteDelegator myCopyPasteDelegator;
  private boolean isInitialized;
  private boolean myExtensionsLoaded = false;
  @NotNull private final Project myProject;

  // + options
  private final Map<String, Boolean> myFlattenPackages = new THashMap<String, Boolean>();
  private static final boolean ourFlattenPackagesDefaults = false;
  private final Map<String, Boolean> myShowMembers = new THashMap<String, Boolean>();
  private static final boolean ourShowMembersDefaults = false;
  private final Map<String, Boolean> mySortByType = new THashMap<String, Boolean>();
  private static final boolean ourSortByTypeDefaults = false;
  private final Map<String, Boolean> myShowModules = new THashMap<String, Boolean>();
  private static final boolean ourShowModulesDefaults = true;
  private final Map<String, Boolean> myShowLibraryContents = new THashMap<String, Boolean>();
  private static final boolean ourShowLibraryContentsDefaults = true;
  private final Map<String, Boolean> myHideEmptyPackages = new THashMap<String, Boolean>();
  private static final boolean ourHideEmptyPackagesDefaults = true;
  private final Map<String, Boolean> myAbbreviatePackageNames = new THashMap<String, Boolean>();
  private static final boolean ourAbbreviatePackagesDefaults = false;
  private final Map<String, Boolean> myAutoscrollToSource = new THashMap<String, Boolean>();
  private final Map<String, Boolean> myAutoscrollFromSource = new THashMap<String, Boolean>();
  private static final boolean ourAutoscrollFromSourceDefaults = false;

  private String myCurrentViewId;
  private String myCurrentViewSubId;
  // - options

  private final AutoScrollToSourceHandler myAutoScrollToSourceHandler;
  private final MyAutoScrollFromSourceHandler myAutoScrollFromSourceHandler;

  private final IdeView myIdeView = new MyIdeView();
  private final MyDeletePSIElementProvider myDeletePSIElementProvider = new MyDeletePSIElementProvider();
  private final ModuleDeleteProvider myDeleteModuleProvider = new ModuleDeleteProvider();

  private SimpleToolWindowPanel myPanel;
  private final Map<String, AbstractProjectViewPane> myId2Pane = new LinkedHashMap<String, AbstractProjectViewPane>();
  private final Collection<AbstractProjectViewPane> myUninitializedPanes = new THashSet<AbstractProjectViewPane>();

  static final DataKey<ProjectViewImpl> DATA_KEY = DataKey.create("com.intellij.ide.projectView.impl.ProjectViewImpl");

  private DefaultActionGroup myActionGroup;
  private String mySavedPaneId = "AndroidView"; // was ProjectViewPane.ID, but in Android Studio, we want the Android View to be the default
  private String mySavedPaneSubId;
  //private static final Icon COMPACT_EMPTY_MIDDLE_PACKAGES_ICON = IconLoader.getIcon("/objectBrowser/compactEmptyPackages.png");
  //private static final Icon HIDE_EMPTY_MIDDLE_PACKAGES_ICON = IconLoader.getIcon("/objectBrowser/hideEmptyPackages.png");
  @NonNls private static final String ELEMENT_NAVIGATOR = "navigator";
  @NonNls private static final String ELEMENT_PANES = "panes";
  @NonNls private static final String ELEMENT_PANE = "pane";
  @NonNls private static final String ATTRIBUTE_CURRENT_VIEW = "currentView";
  @NonNls private static final String ATTRIBUTE_CURRENT_SUBVIEW = "currentSubView";
  @NonNls private static final String ELEMENT_FLATTEN_PACKAGES = "flattenPackages";
  @NonNls private static final String ELEMENT_SHOW_MEMBERS = "showMembers";
  @NonNls private static final String ELEMENT_SHOW_MODULES = "showModules";
  @NonNls private static final String ELEMENT_SHOW_LIBRARY_CONTENTS = "showLibraryContents";
  @NonNls private static final String ELEMENT_HIDE_EMPTY_PACKAGES = "hideEmptyPackages";
  @NonNls private static final String ELEMENT_ABBREVIATE_PACKAGE_NAMES = "abbreviatePackageNames";
  @NonNls private static final String ELEMENT_AUTOSCROLL_TO_SOURCE = "autoscrollToSource";
  @NonNls private static final String ELEMENT_AUTOSCROLL_FROM_SOURCE = "autoscrollFromSource";
  @NonNls private static final String ELEMENT_SORT_BY_TYPE = "sortByType";

  private static final String ATTRIBUTE_ID = "id";
  private JPanel myViewContentPanel;
  private static final Comparator<AbstractProjectViewPane> PANE_WEIGHT_COMPARATOR = new Comparator<AbstractProjectViewPane>() {
    @Override
    public int compare(final AbstractProjectViewPane o1, final AbstractProjectViewPane o2) {
      return o1.getWeight() - o2.getWeight();
    }
  };
  private final FileEditorManager myFileEditorManager;
  private final MyPanel myDataProvider;
  private final SplitterProportionsData splitterProportions = new SplitterProportionsDataImpl();
  private final MessageBusConnection myConnection;
  private final Map<String, Element> myUninitializedPaneState = new HashMap<String, Element>();
  private final Map<String, SelectInTarget> mySelectInTargets = new LinkedHashMap<String, SelectInTarget>();
  private ContentManager myContentManager;
  private boolean myFoldersAlwaysOnTop = true;

  public ProjectViewImpl(@NotNull Project project, final FileEditorManager fileEditorManager, final ToolWindowManagerEx toolWindowManager) {
    myProject = project;

    constructUi();


    Disposer.register(myProject, this);
    myFileEditorManager = fileEditorManager;

    myConnection = project.getMessageBus().connect();
    myConnection.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
      @Override
      public void rootsChanged(ModuleRootEvent event) {
        refresh();
      }
    });

    myAutoScrollFromSourceHandler = new MyAutoScrollFromSourceHandler();

    myDataProvider = new MyPanel();
    myDataProvider.add(myPanel, BorderLayout.CENTER);
    myCopyPasteDelegator = new CopyPasteDelegator(myProject, myPanel) {
      @Override
      @NotNull
      protected PsiElement[] getSelectedElements() {
        final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
        return viewPane == null ? PsiElement.EMPTY_ARRAY : viewPane.getSelectedPSIElements();
      }
    };
    myAutoScrollToSourceHandler = new AutoScrollToSourceHandler() {
      @Override
      protected boolean isAutoScrollMode() {
        return isAutoscrollToSource(myCurrentViewId);
      }

      @Override
      protected void setAutoScrollMode(boolean state) {
        setAutoscrollToSource(state, myCurrentViewId);
      }
    };
    toolWindowManager.addToolWindowManagerListener(new ToolWindowManagerAdapter(){
      private boolean toolWindowVisible;

      @Override
      public void stateChanged() {
        ToolWindow window = toolWindowManager.getToolWindow(ToolWindowId.PROJECT_VIEW);
        if (window == null) return;
        if (window.isVisible() && !toolWindowVisible) {
          String id = getCurrentViewId();
          if (isAutoscrollToSource(id)) {
            AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane();

            if (currentProjectViewPane != null) {
              myAutoScrollToSourceHandler.onMouseClicked(currentProjectViewPane.getTree());
            }
          }
          if (isAutoscrollFromSource(id)) {
            myAutoScrollFromSourceHandler.setAutoScrollEnabled(true);
          }
        }
        toolWindowVisible = window.isVisible();
      }
    });
  }

  private void constructUi() {
    myViewContentPanel = new JPanel();
    myPanel = new SimpleToolWindowPanel(true).setProvideQuickActions(false);
    myPanel.setContent(myViewContentPanel);
  }

  @Override
  public String getName() {
    return "Project";
  }

  @Override
  @NotNull
  public List<AnAction> getActions(boolean originalProvider) {
    ArrayList<AnAction> result = new ArrayList<AnAction>();

    DefaultActionGroup views = new DefaultActionGroup("Change View", true);
    boolean lastHeaderHadKids = false;
    for (int i = 0; i < myContentManager.getContentCount(); i++) {
      Content each = myContentManager.getContent(i);
      if (each != null) {
        if (each.getUserData(SUB_ID_KEY) == null) {
          if (lastHeaderHadKids) {
            views.add(new Separator());
          } else {
            if (i + 1 < myContentManager.getContentCount()) {
              Content next = myContentManager.getContent(i + 1);
              if (next != null) {
                if (next.getUserData(SUB_ID_KEY) != null) {
                  views.add(new Separator());
                }
              }
            }
          }
        }
        else {
          lastHeaderHadKids = true;
        }

        views.add(new ChangeViewAction(each.getUserData(ID_KEY), each.getUserData(SUB_ID_KEY)));
      }
    }
    result.add(views);
    result.add(new Separator());


    List<AnAction> secondary = new ArrayList<AnAction>();
    if (myActionGroup != null) {
      AnAction[] kids = myActionGroup.getChildren(null);
      for (AnAction each : kids) {
        if (myActionGroup.isPrimary(each)) {
          result.add(each);
        }
        else {
          secondary.add(each);
        }
      }
    }
    result.add(new Separator());
    result.addAll(secondary);

    return result;
  }

  private class ChangeViewAction extends AnAction {
    private final String myId;
    private final String mySubId;

    private ChangeViewAction(@NotNull String id, String subId) {
      myId = id;
      mySubId = subId;
    }

    @Override
    public void update(AnActionEvent e) {
      AbstractProjectViewPane pane = getProjectViewPaneById(myId);
      e.getPresentation().setText(pane.getTitle() + (mySubId != null ? (" - " + pane.getPresentableSubIdName(mySubId)) : ""));
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
      changeView(myId, mySubId);
    }
  }

  @Override
  public boolean isCycleRoot() {
    return false;
  }

  @Override
  public synchronized void addProjectPane(@NotNull final AbstractProjectViewPane pane) {
    myUninitializedPanes.add(pane);
    SelectInTarget selectInTarget = pane.createSelectInTarget();
    if (selectInTarget != null) {
      mySelectInTargets.put(pane.getId(), selectInTarget);
    }
    if (isInitialized) {
      doAddUninitializedPanes();
    }
  }

  @Override
  public synchronized void removeProjectPane(@NotNull AbstractProjectViewPane pane) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    myUninitializedPanes.remove(pane);
    //assume we are completely initialized here
    String idToRemove = pane.getId();

    if (!myId2Pane.containsKey(idToRemove)) return;
    pane.removeTreeChangeListener();
    for (int i = myContentManager.getContentCount() - 1; i >= 0; i--) {
      Content content = myContentManager.getContent(i);
      String id = content != null ? content.getUserData(ID_KEY) : null;
      if (id != null && id.equals(idToRemove)) {
        myContentManager.removeContent(content, true);
      }
    }
    myId2Pane.remove(idToRemove);
    mySelectInTargets.remove(idToRemove);
    viewSelectionChanged();
  }

  private synchronized void doAddUninitializedPanes() {
    for (AbstractProjectViewPane pane : myUninitializedPanes) {
      doAddPane(pane);
    }
    final Content[] contents = myContentManager.getContents();
    for (int i = 1; i < contents.length; i++) {
      Content content = contents[i];
      Content prev = contents[i - 1];
      if (!StringUtil.equals(content.getUserData(ID_KEY), prev.getUserData(ID_KEY)) &&
          prev.getUserData(SUB_ID_KEY) != null && content.getSeparator() == null) {
        content.setSeparator("");
      }
    }

    String selectID = null;
    String selectSubID = null;

    // try to find saved selected view...
    for (Content content : contents) {
      final String id = content.getUserData(ID_KEY);
      final String subId = content.getUserData(SUB_ID_KEY);
      if (id != null &&
          id.equals(mySavedPaneId) &&
          StringUtil.equals(subId, mySavedPaneSubId)) {
        selectID = id;
        selectSubID = subId;
        break;
      }
    }

    // saved view not found (plugin disabled, ID changed etc.) - select first available view...
    if (selectID == null && contents.length > 0) {
      Content content = contents[0];
      selectID = content.getUserData(ID_KEY);
      selectSubID = content.getUserData(SUB_ID_KEY);
    }

    if (selectID != null) {
      changeView(selectID, selectSubID);
      mySavedPaneId = null;
      mySavedPaneSubId = null;
    }

    myUninitializedPanes.clear();
  }

  private void doAddPane(@NotNull final AbstractProjectViewPane newPane) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    int index;
    final ContentManager manager = myContentManager;
    for (index = 0; index < manager.getContentCount(); index++) {
      Content content = manager.getContent(index);
      String id = content.getUserData(ID_KEY);
      AbstractProjectViewPane pane = myId2Pane.get(id);

      int comp = PANE_WEIGHT_COMPARATOR.compare(pane, newPane);
      if (comp == 0) {
        System.out.println("here");
      }
      LOG.assertTrue(comp != 0);
      if (comp > 0) {
        break;
      }
    }
    final String id = newPane.getId();
    myId2Pane.put(id, newPane);
    String[] subIds = newPane.getSubIds();
    subIds = subIds.length == 0 ? new String[]{null} : subIds;
    boolean first = true;
    for (String subId : subIds) {
      final String title = subId != null ?  newPane.getPresentableSubIdName(subId) : newPane.getTitle();
      final Content content = myContentManager.getFactory().createContent(getComponent(), title, false);
      content.setTabName(title);
      content.putUserData(ID_KEY, id);
      content.putUserData(SUB_ID_KEY, subId);
      content.putUserData(ToolWindow.SHOW_CONTENT_ICON, Boolean.TRUE);
      content.setIcon(newPane.getIcon());
      content.setPopupIcon(subId != null ? AllIcons.General.Bullet : newPane.getIcon());
      content.setPreferredFocusedComponent(new Computable<JComponent>() {
        @Override
        public JComponent compute() {
          final AbstractProjectViewPane current = getCurrentProjectViewPane();
          return current != null ? current.getComponentToFocus() : null;
        }
      });
      content.setBusyObject(this);
      if (first && subId != null) {
        content.setSeparator(newPane.getTitle());
      }
      manager.addContent(content, index++);
      first = false;
    }
    Disposer.register(this, newPane);
  }

  private void showPane(@NotNull AbstractProjectViewPane newPane) {
    AbstractProjectViewPane currentPane = getCurrentProjectViewPane();
    PsiElement selectedPsiElement = null;
    if (currentPane != null) {
      if (currentPane != newPane) {
        currentPane.saveExpandedPaths();
      }
      final PsiElement[] elements = currentPane.getSelectedPSIElements();
      if (elements.length > 0) {
        selectedPsiElement = elements[0];
      }
    }
    myViewContentPanel.removeAll();
    JComponent component = newPane.createComponent();
    UIUtil.removeScrollBorder(component);
    myViewContentPanel.setLayout(new BorderLayout());
    myViewContentPanel.add(component, BorderLayout.CENTER);
    myCurrentViewId = newPane.getId();
    String newSubId = myCurrentViewSubId = newPane.getSubId();
    myViewContentPanel.revalidate();
    myViewContentPanel.repaint();
    createToolbarActions();
    updateTitleActions();

    myAutoScrollToSourceHandler.install(newPane.myTree);

    IdeFocusManager.getInstance(myProject).requestFocus(newPane.getComponentToFocus(), false);

    newPane.restoreExpandedPaths();
    if (selectedPsiElement != null) {
      final VirtualFile virtualFile = PsiUtilCore.getVirtualFile(selectedPsiElement);
      if (virtualFile != null && ((ProjectViewSelectInTarget)newPane.createSelectInTarget()).isSubIdSelectable(newSubId, new SelectInContext() {
        @Override
        @NotNull
        public Project getProject() {
          return myProject;
        }

        @Override
        @NotNull
        public VirtualFile getVirtualFile() {
          return virtualFile;
        }

        @Override
        public Object getSelectorInFile() {
          return null;
        }

        @Override
        public FileEditorProvider getFileEditorProvider() {
          return null;
        }
      })) {
        newPane.select(selectedPsiElement, virtualFile, true);
      }
    }
    myAutoScrollToSourceHandler.onMouseClicked(newPane.myTree);
  }

  private void updateTitleActions() {
    final ToolWindow window = ToolWindowManager.getInstance(myProject).getToolWindow("Project");
    if (!(window instanceof ToolWindowEx)) return;
    ScrollFromSourceAction scrollAction = null;
    CollapseAllToolbarAction collapseAction = null;
    for (AnAction action : myActionGroup.getChildren(null)) {
      if (action instanceof ScrollFromSourceAction) {
        scrollAction = (ScrollFromSourceAction)action;
        myActionGroup.remove(scrollAction);
      }
      if (action instanceof CollapseAllToolbarAction) {
        collapseAction = (CollapseAllToolbarAction)action;
        collapseAction.getTemplatePresentation().setIcon(AllIcons.General.CollapseAll);
        collapseAction.getTemplatePresentation().setHoveredIcon(AllIcons.General.CollapseAllHover);
        myActionGroup.remove(collapseAction);
      }
    }
    ((ToolWindowEx)window).setTitleActions(scrollAction, collapseAction);
  }

  // public for tests
  public synchronized void setupImpl(@NotNull ToolWindow toolWindow) {
    setupImpl(toolWindow, true);
  }

  // public for tests
  public synchronized void setupImpl(@NotNull ToolWindow toolWindow, final boolean loadPaneExtensions) {
    ApplicationManager.getApplication().assertIsDispatchThread();
    myActionGroup = new DefaultActionGroup();

    myAutoScrollFromSourceHandler.install();

    myContentManager = toolWindow.getContentManager();
    if (!ApplicationManager.getApplication().isUnitTestMode()) {
      toolWindow.setContentUiType(ToolWindowContentUiType.COMBO, null);
      ((ToolWindowEx)toolWindow).setAdditionalGearActions(myActionGroup);
      toolWindow.getComponent().putClientProperty(ToolWindowContentUi.HIDE_ID_LABEL, "true");
    }

    GuiUtils.replaceJSplitPaneWithIDEASplitter(myPanel);
    SwingUtilities.invokeLater(new Runnable() {
      @Override
      public void run() {
        splitterProportions.restoreSplitterProportions(myPanel);
      }
    });

    if (loadPaneExtensions) {
      ensurePanesLoaded();
    }
    isInitialized = true;
    doAddUninitializedPanes();

    myContentManager.addContentManagerListener(new ContentManagerAdapter() {
      @Override
      public void selectionChanged(ContentManagerEvent event) {
        if (event.getOperation() == ContentManagerEvent.ContentOperation.add) {
          viewSelectionChanged();
        }
      }
    });
  }

  private void ensurePanesLoaded() {
    if (myExtensionsLoaded) return;
    myExtensionsLoaded = true;
    for(AbstractProjectViewPane pane: Extensions.getExtensions(AbstractProjectViewPane.EP_NAME, myProject)) {
      if (myUninitializedPaneState.containsKey(pane.getId())) {
        try {
          pane.readExternal(myUninitializedPaneState.get(pane.getId()));
        }
        catch (InvalidDataException e) {
          // ignore
        }
        myUninitializedPaneState.remove(pane.getId());
      }
      if (pane.isInitiallyVisible() && !myId2Pane.containsKey(pane.getId())) {
        addProjectPane(pane);
      }
      Disposer.register(this, pane);
    }
  }

  private boolean viewSelectionChanged() {
    Content content = myContentManager.getSelectedContent();
    if (content == null) return false;
    final String id = content.getUserData(ID_KEY);
    String subId = content.getUserData(SUB_ID_KEY);
    if (content.equals(Pair.create(myCurrentViewId, myCurrentViewSubId))) return false;
    final AbstractProjectViewPane newPane = getProjectViewPaneById(id);
    if (newPane == null) return false;
    newPane.setSubId(subId);
    showPane(newPane);
    if (isAutoscrollFromSource(id)) {
      myAutoScrollFromSourceHandler.scrollFromSource();
    }
    return true;
  }

  private void createToolbarActions() {
    myActionGroup.removeAll();
    if (ProjectViewDirectoryHelper.getInstance(myProject).supportsFlattenPackages()) {
      myActionGroup.addAction(new PaneOptionAction(myFlattenPackages, IdeBundle.message("action.flatten.packages"),
                                             IdeBundle.message("action.flatten.packages"), PlatformIcons.FLATTEN_PACKAGES_ICON,
                                             ourFlattenPackagesDefaults) {
        @Override
        public void setSelected(AnActionEvent event, boolean flag) {
          final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
          final SelectionInfo selectionInfo = SelectionInfo.create(viewPane);

          super.setSelected(event, flag);

          selectionInfo.apply(viewPane);
        }
      }).setAsSecondary(true);
    }

    class FlattenPackagesDependableAction extends PaneOptionAction {
      FlattenPackagesDependableAction(@NotNull Map<String, Boolean> optionsMap,
                                      @NotNull String text,
                                      @NotNull String description,
                                      @NotNull Icon icon,
                                      boolean optionDefaultValue) {
        super(optionsMap, text, description, icon, optionDefaultValue);
      }

      @Override
      public void update(AnActionEvent e) {
        super.update(e);
        final Presentation presentation = e.getPresentation();
        presentation.setVisible(isFlattenPackages(myCurrentViewId));
      }
    }
    if (ProjectViewDirectoryHelper.getInstance(myProject).supportsHideEmptyMiddlePackages()) {
      myActionGroup.addAction(new HideEmptyMiddlePackagesAction()).setAsSecondary(true);
    }
    if (ProjectViewDirectoryHelper.getInstance(myProject).supportsFlattenPackages()) {
      myActionGroup.addAction(new FlattenPackagesDependableAction(myAbbreviatePackageNames,
                                                            IdeBundle.message("action.abbreviate.qualified.package.names"),
                                                            IdeBundle.message("action.abbreviate.qualified.package.names"),
                                                            AllIcons.ObjectBrowser.AbbreviatePackageNames,
                                                            ourAbbreviatePackagesDefaults) {
        @Override
        public boolean isSelected(AnActionEvent event) {
          return super.isSelected(event) && isAbbreviatePackageNames(myCurrentViewId);
        }


        @Override
        public void update(AnActionEvent e) {
          super.update(e);
          if (ScopeViewPane.ID.equals(myCurrentViewId)) {
            e.getPresentation().setEnabled(false);
          }
        }
      }).setAsSecondary(true);
    }

    if (isShowMembersOptionSupported()) {
      myActionGroup.addAction(new PaneOptionAction(myShowMembers, IdeBundle.message("action.show.members"),
                                                   IdeBundle.message("action.show.hide.members"),
                                                   AllIcons.ObjectBrowser.ShowMembers, ourShowMembersDefaults))
        .setAsSecondary(true);
    }
    myActionGroup.addAction(myAutoScrollToSourceHandler.createToggleAction()).setAsSecondary(true);
    myActionGroup.addAction(myAutoScrollFromSourceHandler.createToggleAction()).setAsSecondary(true);
    myActionGroup.addAction(new SortByTypeAction()).setAsSecondary(true);
    myActionGroup.addAction(new FoldersAlwaysOnTopAction()).setAsSecondary(true);

    if (!myAutoScrollFromSourceHandler.isAutoScrollEnabled()) {
      myActionGroup.addAction(new ScrollFromSourceAction());
    }
    AnAction collapseAllAction = CommonActionsManager.getInstance().createCollapseAllAction(new TreeExpander() {
      @Override
      public void expandAll() {

      }

      @Override
      public boolean canExpand() {
        return false;
      }

      @Override
      public void collapseAll() {
        AbstractProjectViewPane pane = getCurrentProjectViewPane();
        JTree tree = pane.myTree;
        if (tree != null) {
          TreeUtil.collapseAll(tree, 0);
        }
      }

      @Override
      public boolean canCollapse() {
        return true;
      }
    }, getComponent());
    myActionGroup.add(collapseAllAction);
    getCurrentProjectViewPane().addToolbarActions(myActionGroup);
  }

  protected boolean isShowMembersOptionSupported() {
    return true;
  }

  @Override
  public AbstractProjectViewPane getProjectViewPaneById(String id) {
    if (!ApplicationManager.getApplication().isUnitTestMode()) {   // most tests don't need all panes to be loaded
      ensurePanesLoaded();
    }

    final AbstractProjectViewPane pane = myId2Pane.get(id);
    if (pane != null) {
      return pane;
    }
    for (AbstractProjectViewPane viewPane : myUninitializedPanes) {
      if (viewPane.getId().equals(id)) {
        return viewPane;
      }
    }
    return null;
  }

  @Override
  public AbstractProjectViewPane getCurrentProjectViewPane() {
    return getProjectViewPaneById(myCurrentViewId);
  }

  @Override
  public void refresh() {
    AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane();
    if (currentProjectViewPane != null) {
      // may be null for e.g. default project
      currentProjectViewPane.updateFromRoot(false);
    }
  }

  @Override
  public void select(final Object element, VirtualFile file, boolean requestFocus) {
    final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
    if (viewPane != null) {
      viewPane.select(element, file, requestFocus);
    }
  }

  @NotNull
  @Override
  public ActionCallback selectCB(Object element, VirtualFile file, boolean requestFocus) {
    final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
    if (viewPane != null && viewPane instanceof AbstractProjectViewPSIPane) {
      return ((AbstractProjectViewPSIPane)viewPane).selectCB(element, file, requestFocus);
    }
    select(element, file, requestFocus);
    return new ActionCallback.Done();
  }

  @Override
  public void dispose() {
    myConnection.disconnect();
  }

  @Override
  public JComponent getComponent() {
    return myDataProvider;
  }

  @Override
  public String getCurrentViewId() {
    return myCurrentViewId;
  }

  @Override
  public PsiElement getParentOfCurrentSelection() {
    final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
    if (viewPane == null) {
      return null;
    }
    TreePath path = viewPane.getSelectedPath();
    if (path == null) {
      return null;
    }
    path = path.getParentPath();
    if (path == null) {
      return null;
    }
    DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
    Object userObject = node.getUserObject();
    if (userObject instanceof ProjectViewNode) {
      ProjectViewNode descriptor = (ProjectViewNode)userObject;
      Object element = descriptor.getValue();
      if (element instanceof PsiElement) {
        PsiElement psiElement = (PsiElement)element;
        if (!psiElement.isValid()) return null;
        return psiElement;
      }
      else {
        return null;
      }
    }
    return null;
  }


  private class PaneOptionAction extends ToggleAction implements DumbAware {
    private final Map<String, Boolean> myOptionsMap;
    private final boolean myOptionDefaultValue;

    PaneOptionAction(@NotNull Map<String, Boolean> optionsMap,
                     @NotNull String text,
                     @NotNull String description,
                     Icon icon,
                     boolean optionDefaultValue) {
      super(text, description, icon);
      myOptionsMap = optionsMap;
      myOptionDefaultValue = optionDefaultValue;
    }

    @Override
    public boolean isSelected(AnActionEvent event) {
      return getPaneOptionValue(myOptionsMap, myCurrentViewId, myOptionDefaultValue);
    }

    @Override
    public void setSelected(AnActionEvent event, boolean flag) {
      setPaneOption(myOptionsMap, flag, myCurrentViewId, true);
    }
  }

  @Override
  public void changeView() {
    final List<AbstractProjectViewPane> views = new ArrayList<AbstractProjectViewPane>(myId2Pane.values());
    views.remove(getCurrentProjectViewPane());
    Collections.sort(views, PANE_WEIGHT_COMPARATOR);

    final JList list = new JBList(ArrayUtil.toObjectArray(views));
    list.setCellRenderer(new DefaultListCellRenderer() {
      @Override
      public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        AbstractProjectViewPane pane = (AbstractProjectViewPane)value;
        setText(pane.getTitle());
        return this;
      }
    });

    if (!views.isEmpty()) {
      list.setSelectedValue(views.get(0), true);
    }
    Runnable runnable = new Runnable() {
      @Override
      public void run() {
        if (list.getSelectedIndex() < 0) return;
        AbstractProjectViewPane pane = (AbstractProjectViewPane)list.getSelectedValue();
        changeView(pane.getId());
      }
    };

    new PopupChooserBuilder(list).
      setTitle(IdeBundle.message("title.popup.views")).
      setItemChoosenCallback(runnable).
      createPopup().showInCenterOf(getComponent());
  }

  @Override
  public void changeView(@NotNull String viewId) {
    changeView(viewId, null);
  }

  @Override
  public void changeView(@NotNull String viewId, @Nullable String subId) {
    AbstractProjectViewPane pane = getProjectViewPaneById(viewId);
    LOG.assertTrue(pane != null, "Project view pane not found: " + viewId + "; subId:" + subId);
    if (!viewId.equals(getCurrentViewId())
        || subId != null && !subId.equals(pane.getSubId())) {
      for (Content content : myContentManager.getContents()) {
        if (viewId.equals(content.getUserData(ID_KEY)) && StringUtil.equals(subId, content.getUserData(SUB_ID_KEY))) {
          myContentManager.setSelectedContent(content);
          break;
        }
      }
      viewSelectionChanged();
    }
  }

  private final class MyDeletePSIElementProvider implements DeleteProvider {
    @Override
    public boolean canDeleteElement(@NotNull DataContext dataContext) {
      final PsiElement[] elements = getElementsToDelete();
      return DeleteHandler.shouldEnableDeleteAction(elements);
    }

    @Override
    public void deleteElement(@NotNull DataContext dataContext) {
      List<PsiElement> allElements = Arrays.asList(getElementsToDelete());
      List<PsiElement> validElements = new ArrayList<PsiElement>();
      for (PsiElement psiElement : allElements) {
        if (psiElement != null && psiElement.isValid()) validElements.add(psiElement);
      }
      final PsiElement[] elements = PsiUtilCore.toPsiElementArray(validElements);

      LocalHistoryAction a = LocalHistory.getInstance().startAction(IdeBundle.message("progress.deleting"));
      try {
        DeleteHandler.deletePsiElement(elements, myProject);
      }
      finally {
        a.finish();
      }
    }

    @NotNull
    private PsiElement[] getElementsToDelete() {
      final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
      PsiElement[] elements = viewPane.getSelectedPSIElements();
      for (int idx = 0; idx < elements.length; idx++) {
        final PsiElement element = elements[idx];
        if (element instanceof PsiDirectory) {
          PsiDirectory directory = (PsiDirectory)element;
          final ProjectViewDirectoryHelper directoryHelper = ProjectViewDirectoryHelper.getInstance(myProject);
          if (isHideEmptyMiddlePackages(viewPane.getId()) && directory.getChildren().length == 0 && !directoryHelper.skipDirectory(directory)) {
            while (true) {
              PsiDirectory parent = directory.getParentDirectory();
              if (parent == null) break;
              if (directoryHelper.skipDirectory(parent) || PsiDirectoryFactory.getInstance(myProject).getQualifiedName(parent, false).length() == 0) break;
              PsiElement[] children = parent.getChildren();
              if (children.length == 0 || children.length == 1 && children[0] == directory) {
                directory = parent;
              }
              else {
                break;
              }
            }
            elements[idx] = directory;
          }
          final VirtualFile virtualFile = directory.getVirtualFile();
          final String path = virtualFile.getPath();
          if (path.endsWith(JarFileSystem.JAR_SEPARATOR)) { // if is jar-file root
            final VirtualFile vFile =
              LocalFileSystem.getInstance().findFileByPath(path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()));
            if (vFile != null) {
              final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(vFile);
              if (psiFile != null) {
                elements[idx] = psiFile;
              }
            }
          }
        }
      }
      return elements;
    }

  }

  private final class MyPanel extends JPanel implements DataProvider {
    MyPanel() {
      super(new BorderLayout());
    }

    @Nullable
    private Object getSelectedNodeElement() {
      final AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane();
      if (currentProjectViewPane == null) { // can happen if not initialized yet
        return null;
      }
      DefaultMutableTreeNode node = currentProjectViewPane.getSelectedNode();
      if (node == null) {
        return null;
      }
      Object userObject = node.getUserObject();
      if (userObject instanceof AbstractTreeNode) {
        return ((AbstractTreeNode)userObject).getValue();
      }
      if (!(userObject instanceof NodeDescriptor)) {
        return null;
      }
      return ((NodeDescriptor)userObject).getElement();
    }

    @Override
    public Object getData(String dataId) {
      final AbstractProjectViewPane currentProjectViewPane = getCurrentProjectViewPane();
      if (currentProjectViewPane != null) {
        final Object paneSpecificData = currentProjectViewPane.getData(dataId);
        if (paneSpecificData != null) return paneSpecificData;
      }

      if (CommonDataKeys.PSI_ELEMENT.is(dataId)) {
        if (currentProjectViewPane == null) return null;
        final PsiElement[] elements = currentProjectViewPane.getSelectedPSIElements();
        return elements.length == 1 ? elements[0] : null;
      }
      if (LangDataKeys.PSI_ELEMENT_ARRAY.is(dataId)) {
        if (currentProjectViewPane == null) {
          return null;
        }
        PsiElement[] elements = currentProjectViewPane.getSelectedPSIElements();
        return elements.length == 0 ? null : elements;
      }
      if (LangDataKeys.MODULE.is(dataId)) {
        VirtualFile[] virtualFiles = (VirtualFile[])getData(CommonDataKeys.VIRTUAL_FILE_ARRAY.getName());
        if (virtualFiles == null || virtualFiles.length <= 1) return null;
        final Set<Module> modules = new HashSet<Module>();
        for (VirtualFile virtualFile : virtualFiles) {
          modules.add(ModuleUtilCore.findModuleForFile(virtualFile, myProject));
        }
        return modules.size() == 1 ? modules.iterator().next() : null;
      }
      if (LangDataKeys.TARGET_PSI_ELEMENT.is(dataId)) {
        return null;
      }
      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 (LangDataKeys.IDE_VIEW.is(dataId)) {
        return myIdeView;
      }
      if (PlatformDataKeys.DELETE_ELEMENT_PROVIDER.is(dataId)) {
        final Module[] modules = getSelectedModules();
        if (modules != null) {
          return myDeleteModuleProvider;
        }
        final LibraryOrderEntry orderEntry = getSelectedLibrary();
        if (orderEntry != null) {
          return new DeleteProvider() {
            @Override
            public void deleteElement(@NotNull DataContext dataContext) {
              detachLibrary(orderEntry, myProject);
            }

            @Override
            public boolean canDeleteElement(@NotNull DataContext dataContext) {
              return true;
            }
          };
        }
        return myDeletePSIElementProvider;
      }
      if (PlatformDataKeys.HELP_ID.is(dataId)) {
        return HelpID.PROJECT_VIEWS;
      }
      if (ProjectViewImpl.DATA_KEY.is(dataId)) {
        return ProjectViewImpl.this;
      }
      if (PlatformDataKeys.PROJECT_CONTEXT.is(dataId)) {
        Object selected = getSelectedNodeElement();
        return selected instanceof Project ? selected : null;
      }
      if (LangDataKeys.MODULE_CONTEXT.is(dataId)) {
        Object selected = getSelectedNodeElement();
        if (selected instanceof Module) {
          return !((Module)selected).isDisposed() ? selected : null;
        }
        else if (selected instanceof PsiDirectory) {
          return moduleBySingleContentRoot(((PsiDirectory)selected).getVirtualFile());
        }
        else if (selected instanceof VirtualFile) {
          return moduleBySingleContentRoot((VirtualFile)selected);
        }
        else {
          return null;
        }
      }

      if (LangDataKeys.MODULE_CONTEXT_ARRAY.is(dataId)) {
        return getSelectedModules();
      }
      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 (QuickActionProvider.KEY.is(dataId)) {
        return ProjectViewImpl.this;
      }

      return null;
    }

    @Nullable
    private LibraryOrderEntry getSelectedLibrary() {
      final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
      DefaultMutableTreeNode node = viewPane != null ? viewPane.getSelectedNode() : null;
      if (node == null) return null;
      DefaultMutableTreeNode parent = (DefaultMutableTreeNode)node.getParent();
      if (parent == null) return null;
      Object userObject = parent.getUserObject();
      if (userObject instanceof LibraryGroupNode) {
        userObject = node.getUserObject();
        if (userObject instanceof NamedLibraryElementNode) {
          NamedLibraryElement element = ((NamedLibraryElementNode)userObject).getValue();
          OrderEntry orderEntry = element.getOrderEntry();
          return orderEntry instanceof LibraryOrderEntry ? (LibraryOrderEntry)orderEntry : null;
        }
        PsiDirectory directory = ((PsiDirectoryNode)userObject).getValue();
        VirtualFile virtualFile = directory.getVirtualFile();
        Module module = (Module)((AbstractTreeNode)((DefaultMutableTreeNode)parent.getParent()).getUserObject()).getValue();

        if (module == null) return null;
        ModuleFileIndex index = ModuleRootManager.getInstance(module).getFileIndex();
        OrderEntry entry = index.getOrderEntryForFile(virtualFile);
        if (entry instanceof LibraryOrderEntry) {
          return (LibraryOrderEntry)entry;
        }
      }

      return null;
    }

    private void detachLibrary(@NotNull final LibraryOrderEntry orderEntry, @NotNull Project project) {
      final Module module = orderEntry.getOwnerModule();
      String message = IdeBundle.message("detach.library.from.module", orderEntry.getPresentableName(), module.getName());
      String title = IdeBundle.message("detach.library");
      int ret = Messages.showOkCancelDialog(project, message, title, Messages.getQuestionIcon());
      if (ret != Messages.OK) return;
      CommandProcessor.getInstance().executeCommand(module.getProject(), new Runnable() {
        @Override
        public void run() {
          final Runnable action = new Runnable() {
            @Override
            public void run() {
              ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
              OrderEntry[] orderEntries = rootManager.getOrderEntries();
              ModifiableRootModel model = rootManager.getModifiableModel();
              OrderEntry[] modifiableEntries = model.getOrderEntries();
              for (int i = 0; i < orderEntries.length; i++) {
                OrderEntry entry = orderEntries[i];
                if (entry instanceof LibraryOrderEntry && ((LibraryOrderEntry)entry).getLibrary() == orderEntry.getLibrary()) {
                  model.removeOrderEntry(modifiableEntries[i]);
                }
              }
              model.commit();
            }
          };
          ApplicationManager.getApplication().runWriteAction(action);
        }
      }, title, null);
    }

    @Nullable
    private Module[] getSelectedModules() {
      final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
      if (viewPane == null) return null;
      final Object[] elements = viewPane.getSelectedElements();
      ArrayList<Module> result = new ArrayList<Module>();
      for (Object element : elements) {
        if (element instanceof Module) {
          final Module module = (Module)element;
          if (!module.isDisposed()) {
            result.add(module);
          }
        }
        else if (element instanceof ModuleGroup) {
          Collection<Module> modules = ((ModuleGroup)element).modulesInGroup(myProject, true);
          result.addAll(modules);
        }
        else if (element instanceof PsiDirectory) {
          Module module = moduleBySingleContentRoot(((PsiDirectory)element).getVirtualFile());
          if (module != null) result.add(module);
        }
        else if (element instanceof VirtualFile) {
          Module module = moduleBySingleContentRoot((VirtualFile)element);
          if (module != null) result.add(module);
        }
      }

      if (result.isEmpty()) {
        return null;
      }
      else {
        return result.toArray(new Module[result.size()]);
      }
    }
  }

  /** Project view has the same node for module and its single content root 
   *   => MODULE_CONTEXT data key should return the module when its content root is selected
   *  When there are multiple content roots, they have different nodes under the module node
   *   => MODULE_CONTEXT should be only available for the module node
   *      otherwise VirtualFileArrayRule will return all module's content roots when just one of them is selected
   */
  @Nullable
  private Module moduleBySingleContentRoot(@NotNull VirtualFile file) {
    if (ProjectRootsUtil.isModuleContentRoot(file, myProject)) {
      Module module = ProjectRootManager.getInstance(myProject).getFileIndex().getModuleForFile(file);
      if (module != null && !module.isDisposed() && ModuleRootManager.getInstance(module).getContentRoots().length == 1) {
        return module;
      }
    }

    return null;
  }

  @NotNull
  private <T> List<T> getSelectedElements(@NotNull Class<T> klass) {
    List<T> result = new ArrayList<T>();
    final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
    if (viewPane == null) return result;
    final Object[] elements = viewPane.getSelectedElements();
    for (Object element : elements) {
      //element still valid
      if (element != null && klass.isAssignableFrom(element.getClass())) {
        result.add((T)element);
      }
    }
    return result;
  }

  private final class MyIdeView implements IdeView {
    @Override
    public void selectElement(PsiElement element) {
      selectPsiElement(element, false);
      boolean requestFocus = true;
      if (element != null) {
        final boolean isDirectory = element instanceof PsiDirectory;
        if (!isDirectory) {
          FileEditor editor = EditorHelper.openInEditor(element, false);
          if (editor != null) {
            ToolWindowManager.getInstance(myProject).activateEditorComponent();
            requestFocus = false;
          }
        }
      }

      if (requestFocus) {
        selectPsiElement(element, true);
      }
    }

    @NotNull
    @Override
    public PsiDirectory[] getDirectories() {
      final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
      if (viewPane != null) {
        return viewPane.getSelectedDirectories();
      }

      return PsiDirectory.EMPTY_ARRAY;
    }

    @Override
    public PsiDirectory getOrChooseDirectory() {
      return DirectoryChooserUtil.getOrChooseDirectory(this);
    }
  }

  @Override
  public void selectPsiElement(PsiElement element, boolean requestFocus) {
    if (element == null) return;
    VirtualFile virtualFile = PsiUtilCore.getVirtualFile(element);
    select(element, virtualFile, requestFocus);
  }


  private static void readOption(Element node, @NotNull Map<String, Boolean> options) {
    if (node == null) return;
    List attributes = node.getAttributes();
    for (final Object attribute1 : attributes) {
      Attribute attribute = (Attribute)attribute1;
      options.put(attribute.getName(), Boolean.TRUE.toString().equals(attribute.getValue()) ? Boolean.TRUE : Boolean.FALSE);
    }
  }

  private static void writeOption(@NotNull Element parentNode, @NotNull Map<String, Boolean> optionsForPanes, @NotNull String optionName) {
    Element e = new Element(optionName);
    for (Map.Entry<String, Boolean> entry : optionsForPanes.entrySet()) {
      final String key = entry.getKey();
      if (key != null) { //SCR48267
        e.setAttribute(key, Boolean.toString(entry.getValue().booleanValue()));
      }
    }

    parentNode.addContent(e);
  }

  @Override
  public void loadState(Element parentNode) {
    Element navigatorElement = parentNode.getChild(ELEMENT_NAVIGATOR);
    if (navigatorElement != null) {
      mySavedPaneId = navigatorElement.getAttributeValue(ATTRIBUTE_CURRENT_VIEW);
      mySavedPaneSubId = navigatorElement.getAttributeValue(ATTRIBUTE_CURRENT_SUBVIEW);
      if (mySavedPaneId == null) {
        mySavedPaneId = ProjectViewPane.ID;
        mySavedPaneSubId = null;
      }
      readOption(navigatorElement.getChild(ELEMENT_FLATTEN_PACKAGES), myFlattenPackages);
      readOption(navigatorElement.getChild(ELEMENT_SHOW_MEMBERS), myShowMembers);
      readOption(navigatorElement.getChild(ELEMENT_SHOW_MODULES), myShowModules);
      readOption(navigatorElement.getChild(ELEMENT_SHOW_LIBRARY_CONTENTS), myShowLibraryContents);
      readOption(navigatorElement.getChild(ELEMENT_HIDE_EMPTY_PACKAGES), myHideEmptyPackages);
      readOption(navigatorElement.getChild(ELEMENT_ABBREVIATE_PACKAGE_NAMES), myAbbreviatePackageNames);
      readOption(navigatorElement.getChild(ELEMENT_AUTOSCROLL_TO_SOURCE), myAutoscrollToSource);
      readOption(navigatorElement.getChild(ELEMENT_AUTOSCROLL_FROM_SOURCE), myAutoscrollFromSource);
      readOption(navigatorElement.getChild(ELEMENT_SORT_BY_TYPE), mySortByType);

      try {
        splitterProportions.readExternal(navigatorElement);
      }
      catch (InvalidDataException e) {
        // ignore
      }
    }
    Element panesElement = parentNode.getChild(ELEMENT_PANES);
    if (panesElement != null) {
      readPaneState(panesElement);
    }
  }

  private void readPaneState(@NotNull Element panesElement) {
    @SuppressWarnings({"unchecked"})
    final List<Element> paneElements = panesElement.getChildren(ELEMENT_PANE);

    for (Element paneElement : paneElements) {
      String paneId = paneElement.getAttributeValue(ATTRIBUTE_ID);
      final AbstractProjectViewPane pane = myId2Pane.get(paneId);
      if (pane != null) {
        try {
          pane.readExternal(paneElement);
        }
        catch (InvalidDataException e) {
          // ignore
        }
      }
      else {
        myUninitializedPaneState.put(paneId, paneElement);
      }
    }
  }

  @Override
  public Element getState() {
    Element parentNode = new Element("projectView");
    Element navigatorElement = new Element(ELEMENT_NAVIGATOR);
    AbstractProjectViewPane currentPane = getCurrentProjectViewPane();
    if (currentPane != null) {
      navigatorElement.setAttribute(ATTRIBUTE_CURRENT_VIEW, currentPane.getId());
      String subId = currentPane.getSubId();
      if (subId != null) {
        navigatorElement.setAttribute(ATTRIBUTE_CURRENT_SUBVIEW, subId);
      }
    }
    writeOption(navigatorElement, myFlattenPackages, ELEMENT_FLATTEN_PACKAGES);
    writeOption(navigatorElement, myShowMembers, ELEMENT_SHOW_MEMBERS);
    writeOption(navigatorElement, myShowModules, ELEMENT_SHOW_MODULES);
    writeOption(navigatorElement, myShowLibraryContents, ELEMENT_SHOW_LIBRARY_CONTENTS);
    writeOption(navigatorElement, myHideEmptyPackages, ELEMENT_HIDE_EMPTY_PACKAGES);
    writeOption(navigatorElement, myAbbreviatePackageNames, ELEMENT_ABBREVIATE_PACKAGE_NAMES);
    writeOption(navigatorElement, myAutoscrollToSource, ELEMENT_AUTOSCROLL_TO_SOURCE);
    writeOption(navigatorElement, myAutoscrollFromSource, ELEMENT_AUTOSCROLL_FROM_SOURCE);
    writeOption(navigatorElement, mySortByType, ELEMENT_SORT_BY_TYPE);

    splitterProportions.saveSplitterProportions(myPanel);
    try {
      splitterProportions.writeExternal(navigatorElement);
    }
    catch (WriteExternalException e) {
      // ignore
    }
    parentNode.addContent(navigatorElement);

    Element panesElement = new Element(ELEMENT_PANES);
    writePaneState(panesElement);
    parentNode.addContent(panesElement);
    return parentNode;
  }

  private void writePaneState(@NotNull Element panesElement) {
    for (AbstractProjectViewPane pane : myId2Pane.values()) {
      Element paneElement = new Element(ELEMENT_PANE);
      paneElement.setAttribute(ATTRIBUTE_ID, pane.getId());
      try {
        pane.writeExternal(paneElement);
      }
      catch (WriteExternalException e) {
        continue;
      }
      panesElement.addContent(paneElement);
    }
    for (Element element : myUninitializedPaneState.values()) {
      panesElement.addContent(element.clone());
    }
  }

  @Override
  public boolean isAutoscrollToSource(String paneId) {
    return getPaneOptionValue(myAutoscrollToSource, paneId, UISettings.getInstance().DEFAULT_AUTOSCROLL_TO_SOURCE);
  }

  public void setAutoscrollToSource(boolean autoscrollMode, String paneId) {
    myAutoscrollToSource.put(paneId, autoscrollMode ? Boolean.TRUE : Boolean.FALSE);
  }

  @Override
  public boolean isAutoscrollFromSource(String paneId) {
    return getPaneOptionValue(myAutoscrollFromSource, paneId, ourAutoscrollFromSourceDefaults);
  }

  public void setAutoscrollFromSource(boolean autoscrollMode, String paneId) {
    setPaneOption(myAutoscrollFromSource, autoscrollMode, paneId, false);
  }

  @Override
  public boolean isFlattenPackages(String paneId) {
    return getPaneOptionValue(myFlattenPackages, paneId, ourFlattenPackagesDefaults);
  }

  public void setFlattenPackages(boolean flattenPackages, String paneId) {
    setPaneOption(myFlattenPackages, flattenPackages, paneId, true);
  }

  public boolean isFoldersAlwaysOnTop() {
    return myFoldersAlwaysOnTop;
  }

  public void setFoldersAlwaysOnTop(boolean foldersAlwaysOnTop) {
    if (myFoldersAlwaysOnTop != foldersAlwaysOnTop) {
      myFoldersAlwaysOnTop = foldersAlwaysOnTop;
      for (AbstractProjectViewPane pane : myId2Pane.values()) {
        if (pane.getTree() != null) {
          pane.updateFromRoot(false);
        }
      }
    }
  }

  @Override
  public boolean isShowMembers(String paneId) {
    return getPaneOptionValue(myShowMembers, paneId, ourShowMembersDefaults);
  }

  public void setShowMembers(boolean showMembers, String paneId) {
    setPaneOption(myShowMembers, showMembers, paneId, true);
  }

  @Override
  public boolean isHideEmptyMiddlePackages(String paneId) {
    return getPaneOptionValue(myHideEmptyPackages, paneId, ourHideEmptyPackagesDefaults);
  }

  @Override
  public boolean isAbbreviatePackageNames(String paneId) {
    return getPaneOptionValue(myAbbreviatePackageNames, paneId, ourAbbreviatePackagesDefaults);
  }

  @Override
  public boolean isShowLibraryContents(String paneId) {
    return getPaneOptionValue(myShowLibraryContents, paneId, ourShowLibraryContentsDefaults);
  }

  @Override
  public void setShowLibraryContents(boolean showLibraryContents, @NotNull String paneId) {
    setPaneOption(myShowLibraryContents, showLibraryContents, paneId, true);
  }

  @NotNull
  public ActionCallback setShowLibraryContentsCB(boolean showLibraryContents, String paneId) {
    return setPaneOption(myShowLibraryContents, showLibraryContents, paneId, true);
  }

  @Override
  public boolean isShowModules(String paneId) {
    return getPaneOptionValue(myShowModules, paneId, ourShowModulesDefaults);
  }

  @Override
  public void setShowModules(boolean showModules, @NotNull String paneId) {
    setPaneOption(myShowModules, showModules, paneId, true);
  }

  @Override
  public void setHideEmptyPackages(boolean hideEmptyPackages, @NotNull String paneId) {
    setPaneOption(myHideEmptyPackages, hideEmptyPackages, paneId, true);
  }

  @Override
  public void setAbbreviatePackageNames(boolean abbreviatePackageNames, @NotNull String paneId) {
    setPaneOption(myAbbreviatePackageNames, abbreviatePackageNames, paneId, true);
  }

  @NotNull
  private ActionCallback setPaneOption(@NotNull Map<String, Boolean> optionsMap, boolean value, String paneId, final boolean updatePane) {
    optionsMap.put(paneId, value ? Boolean.TRUE : Boolean.FALSE);
    if (updatePane) {
      final AbstractProjectViewPane pane = getProjectViewPaneById(paneId);
      if (pane != null) {
        return pane.updateFromRoot(false);
      }
    }
    return new ActionCallback.Done();
  }

  private static boolean getPaneOptionValue(@NotNull Map<String, Boolean> optionsMap, String paneId, boolean defaultValue) {
    final Boolean value = optionsMap.get(paneId);
    return value == null ? defaultValue : value.booleanValue();
  }

  private class HideEmptyMiddlePackagesAction extends PaneOptionAction {
    private HideEmptyMiddlePackagesAction() {
      super(myHideEmptyPackages, "", "", null, ourHideEmptyPackagesDefaults);
    }

    @Override
    public void setSelected(AnActionEvent event, boolean flag) {
      final AbstractProjectViewPane viewPane = getCurrentProjectViewPane();
      final SelectionInfo selectionInfo = SelectionInfo.create(viewPane);

      super.setSelected(event, flag);

      selectionInfo.apply(viewPane);
    }

    @Override
    public void update(AnActionEvent e) {
      super.update(e);
      final Presentation presentation = e.getPresentation();
      if (isFlattenPackages(myCurrentViewId)) {
        presentation.setText(IdeBundle.message("action.hide.empty.middle.packages"));
        presentation.setDescription(IdeBundle.message("action.show.hide.empty.middle.packages"));
      }
      else {
        presentation.setText(IdeBundle.message("action.compact.empty.middle.packages"));
        presentation.setDescription(IdeBundle.message("action.show.compact.empty.middle.packages"));
      }
    }
  }

  private static class SelectionInfo {
    private final Object[] myElements;

    private SelectionInfo(@NotNull Object[] elements) {
      myElements = elements;
    }

    public void apply(final AbstractProjectViewPane viewPane) {
      if (viewPane == null) {
        return;
      }
      AbstractTreeBuilder treeBuilder = viewPane.getTreeBuilder();
      JTree tree = viewPane.myTree;
      DefaultTreeModel treeModel = (DefaultTreeModel)tree.getModel();
      List<TreePath> paths = new ArrayList<TreePath>(myElements.length);
      for (final Object element : myElements) {
        DefaultMutableTreeNode node = treeBuilder.getNodeForElement(element);
        if (node == null) {
          treeBuilder.buildNodeForElement(element);
          node = treeBuilder.getNodeForElement(element);
        }
        if (node != null) {
          paths.add(new TreePath(treeModel.getPathToRoot(node)));
        }
      }
      if (!paths.isEmpty()) {
        tree.setSelectionPaths(paths.toArray(new TreePath[paths.size()]));
      }
    }

    @NotNull
    public static SelectionInfo create(final AbstractProjectViewPane viewPane) {
      List<Object> selectedElements = Collections.emptyList();
      if (viewPane != null) {
        final TreePath[] selectionPaths = viewPane.getSelectionPaths();
        if (selectionPaths != null) {
          selectedElements = new ArrayList<Object>();
          for (TreePath path : selectionPaths) {
            final DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
            final Object userObject = node.getUserObject();
            if (userObject instanceof NodeDescriptor) {
              selectedElements.add(((NodeDescriptor)userObject).getElement());
            }
          }
        }
      }
      return new SelectionInfo(selectedElements.toArray());
    }
  }

  private class MyAutoScrollFromSourceHandler extends AutoScrollFromSourceHandler {
    private MyAutoScrollFromSourceHandler() {
      super(ProjectViewImpl.this.myProject, myViewContentPanel, ProjectViewImpl.this);
    }

    @Override
    protected void selectElementFromEditor(@NotNull FileEditor fileEditor) {
      if (myProject.isDisposed() || !myViewContentPanel.isShowing()) return;
      if (isAutoscrollFromSource(getCurrentViewId())) {
        if (fileEditor instanceof TextEditor) {
          Editor editor = ((TextEditor)fileEditor).getEditor();
          selectElementAtCaretNotLosingFocus(editor);
        }
        else {
          final VirtualFile file = FileEditorManagerEx.getInstanceEx(myProject).getFile(fileEditor);
          if (file != null) {
            final PsiFile psiFile = PsiManager.getInstance(myProject).findFile(file);
            if (psiFile != null) {
              final SelectInTarget target = mySelectInTargets.get(getCurrentViewId());
              if (target != null) {
                final MySelectInContext selectInContext = new MySelectInContext(psiFile, null) {
                  @Override
                  public Object getSelectorInFile() {
                    return psiFile;
                  }
                };

                if (target.canSelect(selectInContext)) {
                  target.selectIn(selectInContext, false);
                }
              }
            }
          }
        }
      }
    }

    public void scrollFromSource() {
      final FileEditorManager fileEditorManager = FileEditorManager.getInstance(myProject);
      final Editor selectedTextEditor = fileEditorManager.getSelectedTextEditor();
      if (selectedTextEditor != null) {
        selectElementAtCaret(selectedTextEditor);
        return;
      }
      final FileEditor[] editors = fileEditorManager.getSelectedEditors();
      for (FileEditor fileEditor : editors) {
        if (fileEditor instanceof TextEditor) {
          Editor editor = ((TextEditor)fileEditor).getEditor();
          selectElementAtCaret(editor);
          return;
        }
      }
      final VirtualFile[] selectedFiles = fileEditorManager.getSelectedFiles();
      if (selectedFiles.length > 0) {
        final PsiFile file = PsiManager.getInstance(myProject).findFile(selectedFiles[0]);
        if (file != null) {
          scrollFromFile(file, null);
        }
      }
    }

    private void selectElementAtCaretNotLosingFocus(@NotNull Editor editor) {
      if (IJSwingUtilities.hasFocus(getCurrentProjectViewPane().getComponentToFocus())) return;
      selectElementAtCaret(editor);
    }

    private void selectElementAtCaret(@NotNull Editor editor) {
      final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(editor.getDocument());
      if (file == null) return;

      scrollFromFile(file, editor);
    }

    private void scrollFromFile(@NotNull PsiFile file, @Nullable Editor editor) {
      final MySelectInContext selectInContext = new MySelectInContext(file, editor);

      final SelectInTarget target = mySelectInTargets.get(getCurrentViewId());
      if (target != null && target.canSelect(selectInContext)) {
        target.selectIn(selectInContext, false);
      }
    }

    @Override
    protected boolean isAutoScrollEnabled() {
      return isAutoscrollFromSource(myCurrentViewId);
    }

    @Override
    protected void setAutoScrollEnabled(boolean state) {
      setAutoscrollFromSource(state, myCurrentViewId);
      if (state) {
        final Editor editor = myFileEditorManager.getSelectedTextEditor();
        if (editor != null) {
          selectElementAtCaretNotLosingFocus(editor);
        }
      }
      createToolbarActions();
      updateTitleActions();
    }

    private class MySelectInContext implements SelectInContext {
      @NotNull private final PsiFile myPsiFile;
      @Nullable private final Editor myEditor;

      private MySelectInContext(@NotNull PsiFile psiFile, @Nullable Editor editor) {
        myPsiFile = psiFile;
        myEditor = editor;
      }

      @Override
      @NotNull
      public Project getProject() {
        return myProject;
      }

      @NotNull
      private PsiFile getPsiFile() {
        return myPsiFile;
      }

      @Override
      @NotNull
      public FileEditorProvider getFileEditorProvider() {
        return new FileEditorProvider() {
          @Override
          public FileEditor openFileEditor() {
            return myFileEditorManager.openFile(myPsiFile.getContainingFile().getVirtualFile(), false)[0];
          }
        };
      }

      @NotNull
      private PsiElement getPsiElement() {
        PsiElement e = null;
        if (myEditor != null) {
          final int offset = myEditor.getCaretModel().getOffset();
          PsiDocumentManager.getInstance(myProject).commitAllDocuments();
          e = getPsiFile().findElementAt(offset);
        }
        if (e == null) {
          e = getPsiFile();
        }
        return e;
      }

      @Override
      @NotNull
      public VirtualFile getVirtualFile() {
        return getPsiFile().getVirtualFile();
      }

      @Override
      public Object getSelectorInFile() {
        return getPsiElement();
      }
    }
  }

  @Override
  public boolean isSortByType(String paneId) {
    return getPaneOptionValue(mySortByType, paneId, ourSortByTypeDefaults);
  }

  @Override
  public void setSortByType(@NotNull String paneId, final boolean sortByType) {
    setPaneOption(mySortByType, sortByType, paneId, false);
    final AbstractProjectViewPane pane = getProjectViewPaneById(paneId);
    pane.installComparator();
  }

  private class SortByTypeAction extends ToggleAction {
    private SortByTypeAction() {
      super(IdeBundle.message("action.sort.by.type"), IdeBundle.message("action.sort.by.type"), AllIcons.ObjectBrowser.SortByType);
    }

    @Override
    public boolean isSelected(AnActionEvent event) {
      return isSortByType(getCurrentViewId());
    }

    @Override
    public void setSelected(AnActionEvent event, boolean flag) {
      setSortByType(getCurrentViewId(), flag);
    }

    @Override
    public void update(final AnActionEvent e) {
      super.update(e);
      final Presentation presentation = e.getPresentation();
      presentation.setVisible(getCurrentProjectViewPane() != null);
    }
  }

  private class FoldersAlwaysOnTopAction extends ToggleAction {
    private FoldersAlwaysOnTopAction() {
      super("Folders Always on Top");
    }

    @Override
    public boolean isSelected(AnActionEvent event) {
      return isFoldersAlwaysOnTop();
    }

    @Override
    public void setSelected(AnActionEvent event, boolean flag) {
      setFoldersAlwaysOnTop(flag);
    }

    @Override
    public void update(final AnActionEvent e) {
      super.update(e);
      final Presentation presentation = e.getPresentation();
      presentation.setVisible(getCurrentProjectViewPane() != null);
    }
  }

  private class ScrollFromSourceAction extends AnAction implements DumbAware {
    private ScrollFromSourceAction() {
      super("Scroll from Source", "Select the file open in the active editor", AllIcons.General.Locate);
      getTemplatePresentation().setHoveredIcon(AllIcons.General.LocateHover);
    }

    @Override
    public void actionPerformed(AnActionEvent e) {
      myAutoScrollFromSourceHandler.scrollFromSource();
    }
  }

  @NotNull
  @Override
  public Collection<String> getPaneIds() {
    return myId2Pane.keySet();
  }

  @NotNull
  @Override
  public Collection<SelectInTarget> getSelectInTargets() {
    ensurePanesLoaded();
    return mySelectInTargets.values();
  }

  @NotNull
  @Override
  public ActionCallback getReady(@NotNull Object requestor) {
    AbstractProjectViewPane pane = myId2Pane.get(myCurrentViewSubId);
    if (pane == null) {
      pane = myId2Pane.get(myCurrentViewId);
    }
    return pane != null ? pane.getReady(requestor) : new ActionCallback.Done();
  }
}
