/*
 * 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.internal.psiView;

import com.intellij.diagnostic.AttachmentFactory;
import com.intellij.diagnostic.LogMessageEx;
import com.intellij.formatting.ASTBlock;
import com.intellij.formatting.Block;
import com.intellij.formatting.FormattingModel;
import com.intellij.formatting.FormattingModelBuilder;
import com.intellij.ide.util.treeView.AbstractTreeStructure;
import com.intellij.ide.util.treeView.NodeRenderer;
import com.intellij.internal.psiView.formattingblocks.BlockTreeBuilder;
import com.intellij.internal.psiView.formattingblocks.BlockTreeNode;
import com.intellij.internal.psiView.formattingblocks.BlockTreeStructure;
import com.intellij.lang.ASTNode;
import com.intellij.lang.Language;
import com.intellij.lang.LanguageFormatting;
import com.intellij.lang.LanguageUtil;
import com.intellij.lang.injection.InjectedLanguageManager;
import com.intellij.openapi.Disposable;
import com.intellij.openapi.actionSystem.CommonDataKeys;
import com.intellij.openapi.actionSystem.DataProvider;
import com.intellij.openapi.application.AccessToken;
import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.diagnostic.Logger;
import com.intellij.openapi.editor.*;
import com.intellij.openapi.editor.colors.EditorColors;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.event.*;
import com.intellij.openapi.editor.ex.EditorEx;
import com.intellij.openapi.editor.highlighter.EditorHighlighterFactory;
import com.intellij.openapi.editor.markup.*;
import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileTypes.*;
import com.intellij.openapi.fileTypes.impl.AbstractFileType;
import com.intellij.openapi.ide.CopyPasteManager;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.ui.DialogWrapper;
import com.intellij.openapi.ui.Messages;
import com.intellij.openapi.util.DimensionService;
import com.intellij.openapi.util.Disposer;
import com.intellij.openapi.util.SystemInfo;
import com.intellij.openapi.util.TextRange;
import com.intellij.openapi.util.io.FileUtilRt;
import com.intellij.openapi.wm.IdeFocusManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
import com.intellij.psi.PsiFileFactory;
import com.intellij.psi.PsiReference;
import com.intellij.psi.codeStyle.CodeStyleSettings;
import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
import com.intellij.psi.impl.DebugUtil;
import com.intellij.psi.impl.source.resolve.FileContextUtil;
import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
import com.intellij.psi.search.FilenameIndex;
import com.intellij.psi.search.GlobalSearchScope;
import com.intellij.testFramework.LightVirtualFile;
import com.intellij.ui.*;
import com.intellij.ui.components.JBLabel;
import com.intellij.ui.components.JBList;
import com.intellij.ui.treeStructure.Tree;
import com.intellij.util.ArrayUtil;
import com.intellij.util.IncorrectOperationException;
import com.intellij.util.ObjectUtils;
import com.intellij.util.containers.ContainerUtil;
import com.intellij.util.ui.UIUtil;
import com.intellij.util.ui.tree.TreeUtil;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import javax.swing.*;
import javax.swing.event.ListSelectionEvent;
import javax.swing.event.ListSelectionListener;
import javax.swing.event.TreeSelectionEvent;
import javax.swing.event.TreeSelectionListener;
import javax.swing.tree.*;
import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.*;
import java.util.*;
import java.util.List;
import java.util.regex.Pattern;

/**
 * @author Konstantin Bulenkov
 */
public class PsiViewerDialog extends DialogWrapper implements DataProvider, Disposable {
  private static final String REFS_CACHE = "References Resolve Cache";
  private static final Color BOX_COLOR = new JBColor(new Color(0xFC6C00), new Color(0xDE6C01));
  private static final Logger LOG = Logger.getInstance("#com.intellij.internal.psiView.PsiViewerDialog");
  private final Project myProject;

  private JPanel myPanel;
  private JComboBox myFileTypeComboBox;
  private JCheckBox myShowWhiteSpacesBox;
  private JCheckBox myShowTreeNodesCheckBox;
  private JBLabel myDialectLabel;
  private JComboBox myDialectComboBox;
  private JLabel myExtensionLabel;
  private JComboBox myExtensionComboBox;
  private JPanel myTextPanel;
  private JPanel myStructureTreePanel;
  private JPanel myReferencesPanel;
  private JSplitPane myTextSplit;
  private JSplitPane myTreeSplit;
  private Tree myPsiTree;
  private ViewerTreeBuilder myPsiTreeBuilder;
  private JList myRefs;

  private Tree myBlockTree;
  private JPanel myBlockStructurePanel;
  private JSplitPane myBlockRefSplitPane;
  private JCheckBox myShowBlocksCheckBox;
  private TitledSeparator myTextSeparator;
  private TitledSeparator myPsiTreeSeparator;
  private TitledSeparator myRefsSeparator;
  private TitledSeparator myBlockTreeSeparator;
  @Nullable
  private BlockTreeBuilder myBlockTreeBuilder;
  private RangeHighlighter myHighlighter;
  private HashMap<PsiElement, BlockTreeNode> myPsiToBlockMap;

  private final Set<SourceWrapper> mySourceWrappers = ContainerUtil.newTreeSet();
  private final EditorEx myEditor;
  private final EditorListener myEditorListener = new EditorListener();
  private String myLastParsedText = null;
  private int myLastParsedTextHashCode = 17;
  private int myNewDocumentHashCode = 11;

  private int myIgnoreBlockTreeSelectionMarker = 0;

  private PsiFile myCurrentFile;
  private String myInitText;
  private String myFileType;

  private void createUIComponents() {
    myPsiTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
    myBlockTree = new Tree(new DefaultTreeModel(new DefaultMutableTreeNode()));
    myRefs = new JBList(new DefaultListModel());
  }

  private static class ExtensionComparator implements Comparator<String> {
    private final String myOnTop;

    public ExtensionComparator(String onTop) {
      myOnTop = onTop;
    }

    @Override
    public int compare(@NotNull String o1, @NotNull String o2) {
      if (o1.equals(myOnTop)) return -1;
      if (o2.equals(myOnTop)) return 1;
      return o1.compareToIgnoreCase(o2);
    }
  }

  private static class SourceWrapper implements Comparable<SourceWrapper> {
    private final FileType myFileType;
    private final PsiViewerExtension myExtension;

    public SourceWrapper(final FileType fileType) {
      myFileType = fileType;
      myExtension = null;
    }

    public SourceWrapper(final PsiViewerExtension extension) {
      myFileType = null;
      myExtension = extension;
    }

    public String getText() {
      return myFileType != null ? myFileType.getName() + " file" : myExtension.getName();
    }

    @Nullable
    public Icon getIcon() {
      return myFileType != null ? myFileType.getIcon() : myExtension.getIcon();
    }

    @Override
    public int compareTo(@NotNull final SourceWrapper o) {
      return getText().compareToIgnoreCase(o.getText());
    }
  }

  public PsiViewerDialog(Project project, boolean modal, @Nullable PsiFile currentFile, @Nullable Editor currentEditor) {
    super(project, true);
    myCurrentFile = currentFile;
    myProject = project;
    setModal(modal);
    setOKButtonText("&Build PSI Tree");
    setCancelButtonText("&Close");
    Disposer.register(myProject, getDisposable());
    EditorEx editor = null;
    if (myCurrentFile == null) {
      setTitle("PSI Viewer");
    }
    else {
      setTitle("PSI Context Viewer: " + myCurrentFile.getName());
      myFileType = myCurrentFile.getLanguage().getDisplayName();
      if (currentEditor != null) {
        myInitText = currentEditor.getSelectionModel().getSelectedText();
      }
      if (myInitText == null) {
        myInitText = currentFile.getText();
        editor = (EditorEx)EditorFactory.getInstance().createEditor(currentFile.getViewProvider().getDocument(), myProject);
      }
    }
    if (editor == null) {
      final Document document = EditorFactory.getInstance().createDocument("");
      editor = (EditorEx)EditorFactory.getInstance().createEditor(document, myProject);
    }
    editor.getSettings().setLineMarkerAreaShown(false);
    myEditor = editor;
    init();
    if (myCurrentFile != null) {
      doOKAction();
    }
  }

  @Override
  protected void init() {
    initMnemonics();

    initTree(myPsiTree);
    final TreeCellRenderer renderer = myPsiTree.getCellRenderer();
    myPsiTree.setCellRenderer(new TreeCellRenderer() {
      @Override
      public Component getTreeCellRendererComponent(@NotNull JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
        final Component c = renderer.getTreeCellRendererComponent(tree, value, selected, expanded, leaf, row, hasFocus);
        if (value instanceof DefaultMutableTreeNode) {
          final Object userObject = ((DefaultMutableTreeNode)value).getUserObject();
          if (userObject instanceof ViewerNodeDescriptor) {
            final Object element = ((ViewerNodeDescriptor)userObject).getElement();
            if (c instanceof NodeRenderer) {
              ((NodeRenderer)c).setToolTipText(element == null ? null : element.getClass().getName());
            }
            if (element instanceof PsiElement && FileContextUtil.getFileContext(((PsiElement)element).getContainingFile()) != null ||
                element instanceof ViewerTreeStructure.Inject) {
              final TextAttributes attr = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.INJECTED_LANGUAGE_FRAGMENT);
              c.setBackground(attr.getBackgroundColor());
            }
          }
        }
        return c;
      }
    });
    myPsiTreeBuilder = new ViewerTreeBuilder(myProject, myPsiTree);
    Disposer.register(getDisposable(), myPsiTreeBuilder);
    myPsiTree.addTreeSelectionListener(new MyPsiTreeSelectionListener());

    final GoToListener listener = new GoToListener();
    myRefs.addKeyListener(listener);
    myRefs.addMouseListener(listener);
    myRefs.getSelectionModel().addListSelectionListener(listener);
    myRefs.setCellRenderer(new DefaultListCellRenderer() {
      @Override
      public Component getListCellRendererComponent(@NotNull JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
        final Component comp = super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
        if (resolve(index) == null) {
          comp.setForeground(JBColor.RED);
        }
        return comp;
      }
    });

    initTree(myBlockTree);

    myEditor.getSettings().setFoldingOutlineShown(false);
    myEditor.getDocument().addDocumentListener(myEditorListener);
    myEditor.getSelectionModel().addSelectionListener(myEditorListener);
    myEditor.getCaretModel().addCaretListener(myEditorListener);

    getPeer().getWindow().setFocusTraversalPolicy(new LayoutFocusTraversalPolicy() {
      @Override
      public Component getInitialComponent(@NotNull Window window) {
        return myEditor.getComponent();
      }
    });
    final PsiViewerSettings settings = PsiViewerSettings.getSettings();
    final String type = myFileType != null ? myFileType : settings.type;
    SourceWrapper lastUsed = null;
    for (PsiViewerExtension extension : Extensions.getExtensions(PsiViewerExtension.EP_NAME)) {
      final SourceWrapper wrapper = new SourceWrapper(extension);
      mySourceWrappers.add(wrapper);
    }
    final Set<FileType> allFileTypes = ContainerUtil.newHashSet();
    Collections.addAll(allFileTypes, FileTypeManager.getInstance().getRegisteredFileTypes());
    for (Language language : Language.getRegisteredLanguages()) {
      final FileType fileType = language.getAssociatedFileType();
      if (fileType != null) {
        allFileTypes.add(fileType);
      }
    }
    Language curLanguage = myCurrentFile != null ? myCurrentFile.getLanguage() : null;
    for (FileType fileType : allFileTypes) {
      if (fileType != StdFileTypes.GUI_DESIGNER_FORM &&
          fileType != StdFileTypes.IDEA_MODULE &&
          fileType != StdFileTypes.IDEA_PROJECT &&
          fileType != StdFileTypes.IDEA_WORKSPACE &&
          fileType != FileTypes.ARCHIVE &&
          fileType != FileTypes.UNKNOWN &&
          fileType != FileTypes.PLAIN_TEXT &&
          !(fileType instanceof AbstractFileType) &&
          !fileType.isBinary() &&
          !fileType.isReadOnly()) {
        final SourceWrapper wrapper = new SourceWrapper(fileType);
        mySourceWrappers.add(wrapper);
        if (lastUsed == null && wrapper.getText().equals(type)) lastUsed = wrapper;
        if (myCurrentFile != null && wrapper.myFileType instanceof LanguageFileType &&
            wrapper.myFileType.equals(curLanguage.getAssociatedFileType())) {
          lastUsed = wrapper;
        }
      }
    }
    myFileTypeComboBox.setModel(new CollectionComboBoxModel(ContainerUtil.newArrayList(mySourceWrappers), lastUsed));
    myFileTypeComboBox.setRenderer(new ListCellRendererWrapper<SourceWrapper>() {
      @Override
      public void customize(JList list, SourceWrapper value, int index, boolean selected, boolean hasFocus) {
        if (value != null) {
          setText(value.getText());
          setIcon(value.getIcon());
        }
      }
    });
    new ComboboxSpeedSearch(myFileTypeComboBox) {
      @Override
      protected String getElementText(Object element) {
        return element instanceof SourceWrapper? ((SourceWrapper)element).getText() : null;
      }
    };
    myFileTypeComboBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        updateDialectsCombo(null);
        updateExtensionsCombo();
        updateEditor();
      }
    });
    myDialectComboBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        updateEditor();
      }
    });
    myFileTypeComboBox.addFocusListener(new AutoExpandFocusListener(myFileTypeComboBox));
    if (myCurrentFile == null && lastUsed == null && mySourceWrappers.size() > 0) {
      myFileTypeComboBox.setSelectedIndex(0);
    }

    myDialectComboBox.setRenderer(new ListCellRendererWrapper<Language>() {
      @Override
      public void customize(final JList list, final Language value, final int index, final boolean selected, final boolean hasFocus) {
        setText(value != null ? value.getDisplayName() : "<default>");
      }
    });
    myDialectComboBox.addFocusListener(new AutoExpandFocusListener(myDialectComboBox));
    myExtensionComboBox.setRenderer(new ListCellRendererWrapper<String>() {
      @Override
      public void customize(JList list, String value, int index, boolean selected, boolean hasFocus) {
        if (value != null) setText("." + value);
      }
    });
    myExtensionComboBox.addFocusListener(new AutoExpandFocusListener(myExtensionComboBox));

    final ViewerTreeStructure psiTreeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
    myShowWhiteSpacesBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        psiTreeStructure.setShowWhiteSpaces(myShowWhiteSpacesBox.isSelected());
        myPsiTreeBuilder.queueUpdate();
      }
    });
    myShowTreeNodesCheckBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        psiTreeStructure.setShowTreeNodes(myShowTreeNodesCheckBox.isSelected());
        myPsiTreeBuilder.queueUpdate();
      }
    });
    myShowWhiteSpacesBox.setSelected(settings.showWhiteSpaces);
    psiTreeStructure.setShowWhiteSpaces(settings.showWhiteSpaces);
    myShowTreeNodesCheckBox.setSelected(settings.showTreeNodes);
    psiTreeStructure.setShowTreeNodes(settings.showTreeNodes);
    myShowBlocksCheckBox.setSelected(settings.showBlocks);
    myBlockStructurePanel.setVisible(settings.showBlocks);
    myShowBlocksCheckBox.addActionListener(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        if (!myShowBlocksCheckBox.isSelected()) {
          settings.blockRefDividerLocation = myBlockRefSplitPane.getDividerLocation();
        }
        else {
          myBlockRefSplitPane.setDividerLocation(settings.blockRefDividerLocation);
        }
        myBlockStructurePanel.setVisible(myShowBlocksCheckBox.isSelected());
        myBlockStructurePanel.repaint();
      }
    });
    myTextPanel.setLayout(new BorderLayout());
    myTextPanel.add(myEditor.getComponent(), BorderLayout.CENTER);

    final String text = myCurrentFile == null ? settings.text : myInitText;
    final AccessToken token = ApplicationManager.getApplication().acquireWriteActionLock(getClass());
    try {
      myEditor.getDocument().setText(text);
      myEditor.getSelectionModel().setSelection(0, text.length());
    }
    finally {
      token.finish();
    }

    updateDialectsCombo(settings.dialect);
    updateExtensionsCombo();

    registerCustomKeyboardActions();

    final Dimension size = DimensionService.getInstance().getSize(getDimensionServiceKey(), myProject);
    if (size == null) {
      DimensionService.getInstance().setSize(getDimensionServiceKey(), new Dimension(800, 600));
    }
    myTextSplit.setDividerLocation(settings.textDividerLocation);
    myTreeSplit.setDividerLocation(settings.treeDividerLocation);
    myBlockRefSplitPane.setDividerLocation(settings.blockRefDividerLocation);

    updateEditor();
    super.init();
  }

  private static void initTree(JTree tree) {
    UIUtil.setLineStyleAngled(tree);
    tree.setRootVisible(false);
    tree.setShowsRootHandles(true);
    tree.updateUI();
    ToolTipManager.sharedInstance().registerComponent(tree);
    TreeUtil.installActions(tree);
    new TreeSpeedSearch(tree);
  }

  @Override
  protected String getDimensionServiceKey() {
    return "#com.intellij.internal.psiView.PsiViewerDialog";
  }

  @Override
  protected String getHelpId() {
    return "reference.psi.viewer";
  }

  @Override
  public JComponent getPreferredFocusedComponent() {
    return myEditor.getContentComponent();
  }

  private void registerCustomKeyboardActions() {
    final int mask = SystemInfo.isMac ? InputEvent.META_DOWN_MASK : InputEvent.ALT_DOWN_MASK;

    registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        focusEditor();
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_T, mask));

    registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        focusTree();
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_S, mask));


    registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        focusBlockTree();
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_K, mask));

    registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        focusRefs();
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_R, mask));

    registerKeyboardAction(new ActionListener() {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        if (myRefs.isFocusOwner()) {
          focusBlockTree();
        }
        else if (myPsiTree.isFocusOwner()) {
          focusRefs();
        }
        else if (myBlockTree.isFocusOwner()) {
          focusTree();
        }
      }
    }, KeyStroke.getKeyStroke(KeyEvent.VK_TAB, 0));
  }

  private void registerKeyboardAction(ActionListener actionListener, KeyStroke keyStroke) {
    getRootPane().registerKeyboardAction(actionListener, keyStroke, JComponent.WHEN_IN_FOCUSED_WINDOW);
  }

  private void focusEditor() {
    IdeFocusManager.getInstance(myProject).requestFocus(myEditor.getContentComponent(), true);
  }

  private void focusTree() {
    IdeFocusManager.getInstance(myProject).requestFocus(myPsiTree, true);
  }

  private void focusRefs() {
    IdeFocusManager.getInstance(myProject).requestFocus(myRefs, true);
    if (myRefs.getModel().getSize() > 0) {
      if (myRefs.getSelectedIndex() == -1) {
        myRefs.setSelectedIndex(0);
      }
    }
  }

  private void focusBlockTree() {
    IdeFocusManager.getInstance(myProject).requestFocus(myBlockTree, true);
  }

  private void initMnemonics() {
    myTextSeparator.setLabelFor(myEditor.getContentComponent());
    myPsiTreeSeparator.setLabelFor(myPsiTree);
    myRefsSeparator.setLabelFor(myRefs);
    myBlockTreeSeparator.setLabelFor(myBlockTree);
  }

  @Nullable
  private PsiElement getPsiElement() {
    final TreePath path = myPsiTree.getSelectionPath();
    return path == null ? null : getPsiElement((DefaultMutableTreeNode)path.getLastPathComponent());
  }

  @Nullable
  private static PsiElement getPsiElement(DefaultMutableTreeNode node) {
    if (node.getUserObject() instanceof ViewerNodeDescriptor) {
      ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject();
      Object elementObject = descriptor.getElement();
      return elementObject instanceof PsiElement
             ? (PsiElement)elementObject
             : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null;
    }
    return null;
  }

  private void updateDialectsCombo(@Nullable final String lastUsed) {
    final Object source = getSource();
    ArrayList<Language> items = new ArrayList<Language>(); 
    if (source instanceof LanguageFileType) {
      final Language baseLang = ((LanguageFileType)source).getLanguage();
      items.add(baseLang);
      Language[] dialects = LanguageUtil.getLanguageDialects(baseLang);
      Arrays.sort(dialects, LanguageUtil.LANGUAGE_COMPARATOR);
      items.addAll(Arrays.asList(dialects));
    }
    myDialectComboBox.setModel(new CollectionComboBoxModel(items));

    final int size = items.size();
    final boolean visible = size > 1;
    myDialectLabel.setVisible(visible);
    myDialectComboBox.setVisible(visible);
    if (visible && (myCurrentFile != null || lastUsed != null)) {
      String curLanguage = myCurrentFile != null ? myCurrentFile.getLanguage().toString() : lastUsed;
      for (int i = 0; i < size; ++i) {
        if (curLanguage.equals(items.get(i).toString())) {
          myDialectComboBox.setSelectedIndex(i);
          return;
        }
      }
      myDialectComboBox.setSelectedIndex(size > 0 ? 0 : -1);
    }
  }

  private void updateExtensionsCombo() {
    final Object source = getSource();
    if (source instanceof LanguageFileType) {
      final List<String> extensions = getAllExtensions((LanguageFileType)source);
      if (extensions.size() > 1) {
        final ExtensionComparator comp = new ExtensionComparator(extensions.get(0));
        Collections.sort(extensions, comp);
        final SortedComboBoxModel<String> model = new SortedComboBoxModel<String>(comp);
        model.setAll(extensions);
        myExtensionComboBox.setModel(model);
        myExtensionComboBox.setVisible(true);
        myExtensionLabel.setVisible(true);
        String fileExt = myCurrentFile != null ? FileUtilRt.getExtension(myCurrentFile.getName()) : "";
        if (fileExt.length() > 0 && extensions.contains(fileExt)) {
          myExtensionComboBox.setSelectedItem(fileExt);
          return;
        }
        myExtensionComboBox.setSelectedIndex(0);
        return;
      }
    }
    myExtensionComboBox.setVisible(false);
    myExtensionLabel.setVisible(false);
  }

  private static final Pattern EXT_PATTERN = Pattern.compile("[a-z0-9]*");

  private static List<String> getAllExtensions(LanguageFileType fileType) {
    final List<FileNameMatcher> associations = FileTypeManager.getInstance().getAssociations(fileType);
    final List<String> extensions = new ArrayList<String>();
    extensions.add(fileType.getDefaultExtension().toLowerCase());
    for (FileNameMatcher matcher : associations) {
      final String presentableString = matcher.getPresentableString().toLowerCase();
      if (presentableString.startsWith("*.")) {
        final String ext = presentableString.substring(2);
        if (ext.length() > 0 && !extensions.contains(ext) && EXT_PATTERN.matcher(ext).matches()) {
          extensions.add(ext);
        }
      }
    }
    return extensions;
  }

  @Override
  protected JComponent createCenterPanel() {
    return myPanel;
  }

  @Nullable
  private Object getSource() {
    final SourceWrapper wrapper = (SourceWrapper)myFileTypeComboBox.getSelectedItem();
    if (wrapper != null) {
      return wrapper.myFileType != null ? wrapper.myFileType : wrapper.myExtension;
    }
    return null;
  }

  @NotNull
  @Override
  protected Action[] createActions() {
    AbstractAction copyPsi = new AbstractAction("Cop&y PSI") {
      @Override
      public void actionPerformed(@NotNull ActionEvent e) {
        PsiElement element = parseText(myEditor.getDocument().getText());
        List<PsiElement> allToParse = new ArrayList<PsiElement>();
        if (element instanceof PsiFile) {
          allToParse.addAll(((PsiFile)element).getViewProvider().getAllFiles());
        }
        else if (element != null) {
          allToParse.add(element);
        }
        String data = "";
        for (PsiElement psiElement : allToParse) {
          data += DebugUtil.psiToString(psiElement, !myShowWhiteSpacesBox.isSelected(), true);
        }
        CopyPasteManager.getInstance().setContents(new StringSelection(data));
      }
    };
    return ArrayUtil.mergeArrays(new Action[]{copyPsi}, super.createActions());
  }

  @Override
  protected void doOKAction() {
    if (myBlockTreeBuilder != null) {
      Disposer.dispose(myBlockTreeBuilder);
    }
    final String text = myEditor.getDocument().getText();
    myEditor.getSelectionModel().removeSelection();

    myLastParsedText = text;
    myLastParsedTextHashCode = text.hashCode();
    myNewDocumentHashCode = myLastParsedTextHashCode;
    PsiElement rootElement = parseText(text);
    focusTree();
    ViewerTreeStructure structure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
    structure.setRootPsiElement(rootElement);

    myPsiTreeBuilder.queueUpdate();
    myPsiTree.setRootVisible(true);
    myPsiTree.expandRow(0);
    myPsiTree.setRootVisible(false);

    if (!myShowBlocksCheckBox.isSelected()) {
      return;
    }
    Block rootBlock = rootElement == null ? null : buildBlocks(rootElement);
    if (rootBlock == null) {
      myBlockTreeBuilder = null;
      myBlockTree.setRootVisible(false);
      myBlockTree.setVisible(false);
      return;
    }

    myBlockTree.setVisible(true);
    BlockTreeStructure blockTreeStructure = new BlockTreeStructure();
    BlockTreeNode rootNode = new BlockTreeNode(rootBlock, null);
    blockTreeStructure.setRoot(rootNode);
    myBlockTreeBuilder = new BlockTreeBuilder(myBlockTree, blockTreeStructure);
    myPsiToBlockMap = new HashMap<PsiElement, BlockTreeNode>();
    final PsiElement psiFile = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
    initMap(rootNode, psiFile);
    PsiElement rootPsi = rootNode.getBlock() instanceof ASTBlock ?
                         ((ASTBlock)rootNode.getBlock()).getNode().getPsi() : rootElement;
    BlockTreeNode blockNode = myPsiToBlockMap.get(rootPsi);

    if (blockNode == null) {
      LOG.error(LogMessageEx
                  .createEvent("PsiViewer: rootNode not found", "Current language: " + rootElement.getContainingFile().getLanguage(),
                               AttachmentFactory.createAttachment(rootElement.getContainingFile().getOriginalFile().getVirtualFile())));
      blockNode = findBlockNode(rootPsi);
    }

    blockTreeStructure.setRoot(blockNode);
    myBlockTree.addTreeSelectionListener(new MyBlockTreeSelectionListener());
    myBlockTree.setRootVisible(true);
    myBlockTree.expandRow(0);
    myBlockTreeBuilder.queueUpdate();
  }

  private PsiElement parseText(String text) {
    final Object source = getSource();
    try {
      if (source instanceof PsiViewerExtension) {
        return ((PsiViewerExtension)source).createElement(myProject, text);
      }
      if (source instanceof FileType) {
        final FileType type = (FileType)source;
        String ext = type.getDefaultExtension();
        if (myExtensionComboBox.isVisible()) {
          ext = myExtensionComboBox.getSelectedItem().toString().toLowerCase();
        }
        if (type instanceof LanguageFileType) {
          final Language language = ((LanguageFileType)type).getLanguage();
          final Language dialect = (Language)myDialectComboBox.getSelectedItem();
          return PsiFileFactory.getInstance(myProject).createFileFromText("Dummy." + ext, dialect == null ? language : dialect, text);
        }
        return PsiFileFactory.getInstance(myProject).createFileFromText("Dummy." + ext, type, text);
      }
    }
    catch (IncorrectOperationException e) {
      Messages.showMessageDialog(myProject, e.getMessage(), "Error", Messages.getErrorIcon());
    }
    return null;
  }

  @Nullable
  private static Block buildBlocks(@NotNull PsiElement rootElement) {
    FormattingModelBuilder formattingModelBuilder = LanguageFormatting.INSTANCE.forContext(rootElement);
    CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(rootElement.getProject());
    if (formattingModelBuilder != null) {
      FormattingModel formattingModel = formattingModelBuilder.createModel(rootElement, settings);
      return formattingModel.getRootBlock();
    }
    else {
      return null;
    }
  }

  private void initMap(BlockTreeNode rootBlockNode, PsiElement psiEl) {
    PsiElement currentElem = null;
    if (rootBlockNode.getBlock() instanceof ASTBlock) {
      ASTNode node = ((ASTBlock)rootBlockNode.getBlock()).getNode();
      if (node != null) {
        currentElem = node.getPsi();
      }
    }
    if (currentElem == null) {
      currentElem =
        InjectedLanguageUtil
          .findElementAtNoCommit(psiEl.getContainingFile(), rootBlockNode.getBlock().getTextRange().getStartOffset());
    }
    myPsiToBlockMap.put(currentElem, rootBlockNode);

//nested PSI elements with same ranges will be mapped to one blockNode
//    assert currentElem != null;      //for Scala-language plugin etc it can be null, because formatterBlocks is not instance of ASTBlock
    TextRange curTextRange = currentElem.getTextRange();
    PsiElement parentElem = currentElem.getParent();
    while (parentElem != null && parentElem.getTextRange().equals(curTextRange)) {
      myPsiToBlockMap.put(parentElem, rootBlockNode);
      parentElem = parentElem.getParent();
    }
    for (BlockTreeNode block : rootBlockNode.getChildren()) {
      initMap(block, psiEl);
    }
  }

  @Override
  public Object getData(@NonNls String dataId) {
    if (CommonDataKeys.NAVIGATABLE.is(dataId)) {
      String fqn = null;
      if (myPsiTree.hasFocus()) {
        final TreePath path = myPsiTree.getSelectionPath();
        if (path != null) {
          DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
          if (!(node.getUserObject() instanceof ViewerNodeDescriptor)) return null;
          ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject();
          Object elementObject = descriptor.getElement();
          final PsiElement element = elementObject instanceof PsiElement
                                     ? (PsiElement)elementObject
                                     : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null;
          if (element != null) {
            fqn = element.getClass().getName();
          }
        }
      } else if (myRefs.hasFocus()) {
        final Object value = myRefs.getSelectedValue();
        if (value instanceof String) {
          fqn = (String)value;
        }
      }
      if (fqn != null) {
        return getContainingFileForClass(fqn);
      }
    }
    return null;
  }

  private class MyPsiTreeSelectionListener implements TreeSelectionListener {
    private final TextAttributes myAttributes;

    public MyPsiTreeSelectionListener() {
      myAttributes = new TextAttributes();
      myAttributes.setEffectColor(BOX_COLOR);
      myAttributes.setEffectType(EffectType.ROUNDED_BOX);
    }

    @Override
    public void valueChanged(@NotNull TreeSelectionEvent e) {
      if (!myEditor.getDocument().getText().equals(myLastParsedText) || myBlockTree.hasFocus()) return;
      TreePath path = myPsiTree.getSelectionPath();
      clearSelection();
      if (path != null) {
        DefaultMutableTreeNode node = (DefaultMutableTreeNode)path.getLastPathComponent();
        if (!(node.getUserObject() instanceof ViewerNodeDescriptor)) return;
        ViewerNodeDescriptor descriptor = (ViewerNodeDescriptor)node.getUserObject();
        Object elementObject = descriptor.getElement();
        final PsiElement element = elementObject instanceof PsiElement
                                   ? (PsiElement)elementObject
                                   : elementObject instanceof ASTNode ? ((ASTNode)elementObject).getPsi() : null;
        if (element != null) {
          TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
          int start = rangeInHostFile.getStartOffset();
          int end = rangeInHostFile.getEndOffset();
          final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
          PsiElement rootPsiElement = treeStructure.getRootPsiElement();
          if (rootPsiElement != null) {
            int baseOffset = rootPsiElement.getTextRange().getStartOffset();
            start -= baseOffset;
            end -= baseOffset;
          }
          final int textLength = myEditor.getDocument().getTextLength();
          if (end <= textLength) {
            myHighlighter = myEditor.getMarkupModel().addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);
            if (myPsiTree.hasFocus()) {
              myEditor.getCaretModel().moveToOffset(start);
              myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
            }
          }
          if (myBlockTreeBuilder != null && myPsiTree.hasFocus()) {
            BlockTreeNode currentBlockNode = findBlockNode(element);
            if (currentBlockNode != null) {
              selectBlockNode(currentBlockNode);
            }
          }
          updateReferences(element);
        }
      }
    }
  }

  @Nullable
  private BlockTreeNode findBlockNode(PsiElement element) {
    BlockTreeNode result = myPsiToBlockMap.get(element);
    if (result == null) {
      TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
      result = findBlockNode(rangeInHostFile, true);
    }
    return result;
  }

  private void selectBlockNode(@Nullable BlockTreeNode currentBlockNode) {
    if (myBlockTreeBuilder == null) return;
    if (currentBlockNode != null) {
      myIgnoreBlockTreeSelectionMarker++;
      myBlockTreeBuilder.select(currentBlockNode, new Runnable() {
        @Override
        public void run() {
          // hope this is always called!
          assert myIgnoreBlockTreeSelectionMarker > 0;
          myIgnoreBlockTreeSelectionMarker--;
        }
      });
    }
    else {
      myIgnoreBlockTreeSelectionMarker++;
      try {
        myBlockTree.getSelectionModel().clearSelection();
      }
      finally {
        assert myIgnoreBlockTreeSelectionMarker > 0;
        myIgnoreBlockTreeSelectionMarker--;
      }
    }
  }

  private class MyBlockTreeSelectionListener implements TreeSelectionListener {
    private final TextAttributes myAttributes;

    public MyBlockTreeSelectionListener() {
      myAttributes = new TextAttributes();
      myAttributes.setEffectColor(BOX_COLOR);
      myAttributes.setEffectType(EffectType.ROUNDED_BOX);
    }

    @Override
    public void valueChanged(@NotNull TreeSelectionEvent e) {
      if (myIgnoreBlockTreeSelectionMarker > 0 || myBlockTreeBuilder == null) {
        return;
      }

      Set<?> blockElementsSet = myBlockTreeBuilder.getSelectedElements();
      if (blockElementsSet.isEmpty()) return;
      BlockTreeNode descriptor = (BlockTreeNode)blockElementsSet.iterator().next();
      PsiElement rootPsi = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
      int blockStart = descriptor.getBlock().getTextRange().getStartOffset();
      PsiFile file = rootPsi.getContainingFile();
      PsiElement currentPsiEl = InjectedLanguageUtil.findElementAtNoCommit(file, blockStart);
      if (currentPsiEl == null) currentPsiEl = file;
      int blockLength = descriptor.getBlock().getTextRange().getLength();
      while (currentPsiEl.getParent() != null &&
             currentPsiEl.getTextRange().getStartOffset() == blockStart &&
             currentPsiEl.getTextLength() != blockLength) {
        currentPsiEl = currentPsiEl.getParent();
      }
      final BlockTreeStructure treeStructure = (BlockTreeStructure)myBlockTreeBuilder.getTreeStructure();
      BlockTreeNode rootBlockNode = treeStructure.getRootElement();
      int baseOffset = 0;
      if (rootBlockNode != null) {
        baseOffset = rootBlockNode.getBlock().getTextRange().getStartOffset();
      }
      if (currentPsiEl != null) {
        TextRange range = descriptor.getBlock().getTextRange();
        range = range.shiftRight(-baseOffset);
        int start = range.getStartOffset();
        int end = range.getEndOffset();
        final int textLength = myEditor.getDocument().getTextLength();

        if (myBlockTree.hasFocus()) {
          clearSelection();
          if (end <= textLength) {
            myHighlighter = myEditor.getMarkupModel()
              .addRangeHighlighter(start, end, HighlighterLayer.LAST, myAttributes, HighlighterTargetArea.EXACT_RANGE);

            myEditor.getCaretModel().moveToOffset(start);
            myEditor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
          }
        }
        updateReferences(currentPsiEl);
        if (!myPsiTree.hasFocus()) {
          myPsiTreeBuilder.select(currentPsiEl);
        }
      }
    }
  }


  public void updateReferences(PsiElement element) {
    final DefaultListModel model = (DefaultListModel)myRefs.getModel();
    model.clear();
    final Object cache = myRefs.getClientProperty(REFS_CACHE);
    if (cache instanceof Map) {
      ((Map)cache).clear();
    } else {
      myRefs.putClientProperty(REFS_CACHE, new HashMap());
    }
    if (element != null) {
      for (PsiReference reference : element.getReferences()) {
        model.addElement(reference.getClass().getName());
      }
    }
  }

  private void clearSelection() {
    if (myHighlighter != null) {
      myEditor.getMarkupModel().removeHighlighter(myHighlighter);
      myHighlighter.dispose();
    }
  }

  @Override
  public void doCancelAction() {
    final PsiViewerSettings settings = PsiViewerSettings.getSettings();
    final SourceWrapper wrapper = (SourceWrapper)myFileTypeComboBox.getSelectedItem();
    if (wrapper != null) settings.type = wrapper.getText();
    settings.text = myEditor.getDocument().getText();
    settings.showTreeNodes = myShowTreeNodesCheckBox.isSelected();
    settings.showWhiteSpaces = myShowWhiteSpacesBox.isSelected();
    final Object selectedDialect = myDialectComboBox.getSelectedItem();
    settings.dialect = myDialectComboBox.isVisible() && selectedDialect != null ? selectedDialect.toString() : "";
    settings.textDividerLocation = myTextSplit.getDividerLocation();
    settings.treeDividerLocation = myTreeSplit.getDividerLocation();
    settings.showBlocks = myShowBlocksCheckBox.isSelected();
    if( myShowBlocksCheckBox.isSelected()) {
         settings.blockRefDividerLocation = myBlockRefSplitPane.getDividerLocation();
    }
    super.doCancelAction();
  }

  @Override
  public void dispose() {
    Disposer.dispose(myPsiTreeBuilder);
    if (myBlockTreeBuilder != null) {
      Disposer.dispose(myBlockTreeBuilder);
    }
    if (!myEditor.isDisposed()) {
      EditorFactory.getInstance().releaseEditor(myEditor);
    }
    super.dispose();
  }

  @Nullable
  private PsiElement resolve(int index) {
    final PsiElement element = getPsiElement();
    if (element == null) return null;
    @SuppressWarnings("unchecked")
    Map<PsiElement, PsiElement[]> map = (Map<PsiElement, PsiElement[]>)myRefs.getClientProperty(REFS_CACHE);
    if (map == null) {
      myRefs.putClientProperty(REFS_CACHE, map = new HashMap<PsiElement, PsiElement[]>());
    }
    PsiElement[] cache = map.get(element);
    if (cache == null) {
      final PsiReference[] references = element.getReferences();
      cache = new PsiElement[references.length];
      for (int i = 0; i < references.length; i++) {
        cache[i] = references[i].resolve();
      }
      map.put(element, cache);
    }
    return index >= cache.length ? null : cache[index];
  }

  @Nullable
  private PsiFile getContainingFileForClass(String fqn) {
    String filename = fqn;
    if (fqn.contains(".")) {
      filename = fqn.substring(fqn.lastIndexOf('.') + 1);
    }
    if (filename.contains("$")) {
      filename = filename.substring(0, filename.indexOf('$'));
    }
    filename += ".java";
    final PsiFile[] files = FilenameIndex.getFilesByName(myProject, filename, GlobalSearchScope.allScope(myProject));
    if (files != null && files.length > 0) {
      return files[0];
    }
    return null;
  }

  @Nullable
  public static TreeNode findNodeWithObject(final Object object, final TreeModel model, final Object parent) {
    for (int i = 0; i < model.getChildCount(parent); i++) {
      final DefaultMutableTreeNode childNode = (DefaultMutableTreeNode) model.getChild(parent, i);
      if (childNode.getUserObject().equals(object)) {
        return childNode;
      } else {
        final TreeNode node = findNodeWithObject(object, model, childNode);
        if (node != null) return node;
      }
    }
    return null;
  }

  private class GoToListener implements KeyListener, MouseListener, ListSelectionListener {
    private RangeHighlighter myListenerHighlighter;
    private final TextAttributes myAttributes =
      new TextAttributes(JBColor.RED, null, null, null, Font.PLAIN);

    private void navigate() {
      final Object value = myRefs.getSelectedValue();
      if (value instanceof String) {
        final String fqn = (String)value;
        final PsiFile file = getContainingFileForClass(fqn);
        if (file != null) file.navigate(true);
      }
    }

    @Override
    public void keyPressed(@NotNull KeyEvent e) {
      if (e.getKeyCode() == KeyEvent.VK_ENTER) {
        navigate();
      }
    }

    @Override
    public void mouseClicked(@NotNull MouseEvent e) {
      if (e.getClickCount() > 1) {
        navigate();
      }
    }

    @Override
    public void valueChanged(@NotNull ListSelectionEvent e) {
      clearSelection();
      updateDialectsCombo(null);
      updateExtensionsCombo();
      final int ind = myRefs.getSelectedIndex();
      final PsiElement element = getPsiElement();
      if (ind > -1 && element != null) {
        final PsiReference[] references = element.getReferences();
        if (ind < references.length) {
          final TextRange textRange = references[ind].getRangeInElement();
          TextRange range = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
          int start = range.getStartOffset();
          int end = range.getEndOffset();
          final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
          PsiElement rootPsiElement = treeStructure.getRootPsiElement();
          if (rootPsiElement != null) {
            int baseOffset = rootPsiElement.getTextRange().getStartOffset();
            start -= baseOffset;
            end -= baseOffset;
          }

          start += textRange.getStartOffset();
          end = start + textRange.getLength();
          myListenerHighlighter = myEditor.getMarkupModel()
            .addRangeHighlighter(start, end, HighlighterLayer.FIRST + 1, myAttributes, HighlighterTargetArea.EXACT_RANGE);
        }
      }
    }

    public void clearSelection() {
      if (myListenerHighlighter != null &&
          ArrayUtil.contains(myListenerHighlighter, (Object[])myEditor.getMarkupModel().getAllHighlighters())) {
        myListenerHighlighter.dispose();
        myListenerHighlighter = null;
      }
    }

    @Override
    public void keyTyped(@NotNull KeyEvent e) {}
    @Override
    public void keyReleased(KeyEvent e) {}
    @Override
    public void mousePressed(@NotNull MouseEvent e) {}
    @Override
    public void mouseReleased(@NotNull MouseEvent e) {}
    @Override
    public void mouseEntered(@NotNull MouseEvent e) {}
    @Override
    public void mouseExited(@NotNull MouseEvent e) {}
  }

  private void updateEditor() {
    final Object source = getSource();

    final String fileName = "Dummy." + (source instanceof FileType? ((FileType)source).getDefaultExtension() : "txt");
    final LightVirtualFile lightFile;
    if (source instanceof PsiViewerExtension) {
      lightFile = new LightVirtualFile(fileName, ((PsiViewerExtension)source).getDefaultFileType(), "");
    }
    else if (source instanceof LanguageFileType) {
      lightFile = new LightVirtualFile(fileName, ObjectUtils
        .chooseNotNull((Language)myDialectComboBox.getSelectedItem(), ((LanguageFileType)source).getLanguage()), "");
    }
    else if (source instanceof FileType) {
      lightFile = new LightVirtualFile(fileName, (FileType)source, "");
    }
    else {
      return;
    }
    myEditor.setHighlighter(EditorHighlighterFactory.getInstance().createEditorHighlighter(myProject, lightFile));
  }

  private class EditorListener extends CaretAdapter implements SelectionListener, DocumentListener {
    @Override
    public void caretPositionChanged(CaretEvent e) {
      if (!available() || myEditor.getSelectionModel().hasSelection()) return;
      final ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
      final PsiElement rootPsiElement = treeStructure.getRootPsiElement();
      if (rootPsiElement == null) return;
      final PsiElement rootElement = ((ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure()).getRootPsiElement();
      int baseOffset = rootPsiElement.getTextRange().getStartOffset();
      final int offset = myEditor.getCaretModel().getOffset() + baseOffset;
      final PsiElement element = InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), offset);
      if (element != null && myBlockTreeBuilder != null) {
        TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
        selectBlockNode(findBlockNode(rangeInHostFile, true));
      }
      myPsiTreeBuilder.select(element);
    }

    @Override
    public void selectionChanged(SelectionEvent e) {
      if (!available() || !myEditor.getSelectionModel().hasSelection()) return;
      ViewerTreeStructure treeStructure = (ViewerTreeStructure)myPsiTreeBuilder.getTreeStructure();
      if (treeStructure == null) return;
      final PsiElement rootElement = treeStructure.getRootPsiElement();
      if (rootElement == null) return;
      final SelectionModel selection = myEditor.getSelectionModel();
      final TextRange textRange = rootElement.getTextRange();
      int baseOffset = textRange != null ? textRange.getStartOffset() : 0;
      final int start = selection.getSelectionStart()+baseOffset;
      final int end = selection.getSelectionEnd()+baseOffset - 1;
      final PsiElement element =
        findCommonParent(InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), start),
                         InjectedLanguageUtil.findElementAtNoCommit(rootElement.getContainingFile(), end));
      if (element != null  && myBlockTreeBuilder != null) {
        if (myEditor.getContentComponent().hasFocus()) {
          TextRange rangeInHostFile = InjectedLanguageManager.getInstance(myProject).injectedToHost(element, element.getTextRange());
          selectBlockNode(findBlockNode(rangeInHostFile, true));
        }
      }
      myPsiTreeBuilder.select(element);
    }

    @Nullable
    private PsiElement findCommonParent(PsiElement start, PsiElement end) {
      if (end == null || start == end) {
        return start;
      }
      final TextRange endRange = end.getTextRange();
      PsiElement parent = start.getContext();
      while (parent != null && !parent.getTextRange().contains(endRange)) {
        parent = parent.getContext();
      }
      return parent;
    }

    private boolean available() {
      return myLastParsedTextHashCode == myNewDocumentHashCode && myEditor.getContentComponent().hasFocus();
    }

    @Override
    public void beforeDocumentChange(DocumentEvent event) {

    }
    @Override
    public void documentChanged(DocumentEvent event) {
      myNewDocumentHashCode = event.getDocument().getText().hashCode();
    }
  }

  private static class AutoExpandFocusListener extends FocusAdapter {
    private final JComboBox myComboBox;
    private final Component myParent;

    private AutoExpandFocusListener(final JComboBox comboBox) {
      myComboBox = comboBox;
      myParent = UIUtil.findUltimateParent(myComboBox);
    }

    @Override
    public void focusGained(@NotNull final FocusEvent e) {
      final Component from = e.getOppositeComponent();
      if (!e.isTemporary() && from != null && !myComboBox.isPopupVisible() && isUnder(from, myParent)) {
        myComboBox.setPopupVisible(true);
      }
    }

    private static boolean isUnder(Component component, final Component parent) {
      while (component != null) {
        if (component == parent) return true;
        component = component.getParent();
      }
      return false;
    }
  }

  @Nullable
  private BlockTreeNode findBlockNode(TextRange range, boolean selectParentIfNotFound) {
    final BlockTreeBuilder builder = myBlockTreeBuilder;
    if (builder == null || !myBlockStructurePanel.isVisible()) {
      return null;
    }

    AbstractTreeStructure treeStructure = builder.getTreeStructure();
    if (treeStructure == null) return null;
    BlockTreeNode node = (BlockTreeNode)treeStructure.getRootElement();
    main_loop:
    while (true) {
      if (node.getBlock().getTextRange().equals(range)) {
        return node;
      }

      for (BlockTreeNode child : node.getChildren()) {
        if (child.getBlock().getTextRange().contains(range)) {
          node = child;
          continue main_loop;
        }
      }
      return selectParentIfNotFound ? node : null;
    }
  }
}
