@Nullable
  private FilePath unshelveBinaryFile(
      final ShelvedBinaryFile file, @NotNull final VirtualFile patchTarget) throws IOException {
    final Ref<FilePath> result = new Ref<FilePath>();
    final Ref<IOException> ex = new Ref<IOException>();
    final Ref<VirtualFile> patchedFileRef = new Ref<VirtualFile>();
    final File shelvedFile = file.SHELVED_PATH == null ? null : new File(file.SHELVED_PATH);

    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              public void run() {
                try {
                  result.set(new FilePathImpl(patchTarget));
                  if (shelvedFile == null) {
                    patchTarget.delete(this);
                  } else {
                    patchTarget.setBinaryContent(FileUtil.loadFileBytes(shelvedFile));
                    patchedFileRef.set(patchTarget);
                  }
                } catch (IOException e) {
                  ex.set(e);
                }
              }
            });
    if (!ex.isNull()) {
      throw ex.get();
    }
    return result.get();
  }
 @Override
 protected JPanel processSplitter(
     @NotNull Element splitterElement,
     Element firstChild,
     Element secondChild,
     final JPanel context) {
   if (context == null) {
     final boolean orientation =
         "vertical".equals(splitterElement.getAttributeValue("split-orientation"));
     final float proportion =
         Float.valueOf(splitterElement.getAttributeValue("split-proportion")).floatValue();
     final JPanel firstComponent = process(firstChild, null);
     final JPanel secondComponent = process(secondChild, null);
     final Ref<JPanel> panelRef = new Ref<JPanel>();
     UIUtil.invokeAndWaitIfNeeded(
         new Runnable() {
           @Override
           public void run() {
             JPanel panel = new JPanel(new BorderLayout());
             panel.setOpaque(false);
             Splitter splitter = new OnePixelSplitter(orientation, proportion, 0.1f, 0.9f);
             panel.add(splitter, BorderLayout.CENTER);
             splitter.setFirstComponent(firstComponent);
             splitter.setSecondComponent(secondComponent);
             panelRef.set(panel);
           }
         });
     return panelRef.get();
   }
   final Ref<JPanel> firstComponent = new Ref<JPanel>();
   final Ref<JPanel> secondComponent = new Ref<JPanel>();
   UIUtil.invokeAndWaitIfNeeded(
       new Runnable() {
         @Override
         public void run() {
           if (context.getComponent(0) instanceof Splitter) {
             Splitter splitter = (Splitter) context.getComponent(0);
             firstComponent.set((JPanel) splitter.getFirstComponent());
             secondComponent.set((JPanel) splitter.getSecondComponent());
           } else {
             firstComponent.set(context);
             secondComponent.set(context);
           }
         }
       });
   process(firstChild, firstComponent.get());
   process(secondChild, secondComponent.get());
   return context;
 }
  public boolean navigateSelectedElement() {
    final Ref<Boolean> succeeded = new Ref<Boolean>();
    final CommandProcessor commandProcessor = CommandProcessor.getInstance();
    commandProcessor.executeCommand(
        myProject,
        new Runnable() {
          public void run() {
            final AbstractTreeNode selectedNode = getSelectedNode();
            if (selectedNode != null) {
              if (selectedNode.canNavigateToSource()) {
                myPopup.cancel();
                selectedNode.navigate(true);
                succeeded.set(true);
              } else {
                succeeded.set(false);
              }
            } else {
              succeeded.set(false);
            }

            IdeDocumentHistory.getInstance(myProject).includeCurrentCommandAsNavigation();
          }
        },
        "Navigate",
        null);
    return succeeded.get();
  }
  /**
   * remove highlights (bounded with <marker>...</marker>) from test case file
   *
   * @param document document to process
   */
  private void extractExpectedHighlightsSet(final Document document) {
    final String text = document.getText();

    final Set<String> markers = myHighlightingTypes.keySet();
    final String typesRx = "(?:" + StringUtil.join(markers, ")|(?:") + ")";
    final String openingTagRx =
        "<("
            + typesRx
            + ")"
            + "(?:\\s+descr=\"((?:[^\"]|\\\\\"|\\\\\\\\\"|\\\\\\[|\\\\\\])*)\")?"
            + "(?:\\s+type=\"([0-9A-Z_]+)\")?"
            + "(?:\\s+foreground=\"([0-9xa-f]+)\")?"
            + "(?:\\s+background=\"([0-9xa-f]+)\")?"
            + "(?:\\s+effectcolor=\"([0-9xa-f]+)\")?"
            + "(?:\\s+effecttype=\"([A-Z]+)\")?"
            + "(?:\\s+fonttype=\"([0-9]+)\")?"
            + "(?:\\s+textAttributesKey=\"((?:[^\"]|\\\\\"|\\\\\\\\\"|\\\\\\[|\\\\\\])*)\")?"
            + "(?:\\s+bundleMsg=\"((?:[^\"]|\\\\\"|\\\\\\\\\")*)\")?"
            + "(/)?>";

    final Matcher matcher = Pattern.compile(openingTagRx).matcher(text);
    int pos = 0;
    final Ref<Integer> textOffset = Ref.create(0);
    while (matcher.find(pos)) {
      textOffset.set(textOffset.get() + matcher.start() - pos);
      pos = extractExpectedHighlight(matcher, text, document, textOffset);
    }
  }
 @Override
 public <T> T commitAndRunReadAction(@NotNull final Computable<T> computation) {
   final Ref<T> ref = Ref.create(null);
   commitAndRunReadAction(
       new Runnable() {
         @Override
         public void run() {
           ref.set(computation.compute());
         }
       });
   return ref.get();
 }
 private static TextRange adjustRange(final PsiElement element, final TextRange originalRange) {
   final Ref<TextRange> rangeRef = new Ref<TextRange>(originalRange);
   element.accept(
       new JavaRecursiveElementVisitor() {
         @Override
         public void visitExpressionStatement(final PsiExpressionStatement statement) {
           final TextRange stRange = statement.getTextRange();
           if (originalRange.intersects(stRange)) {
             final TextRange currentRange = rangeRef.get();
             final int start = Math.min(currentRange.getStartOffset(), stRange.getStartOffset());
             final int end = Math.max(currentRange.getEndOffset(), stRange.getEndOffset());
             rangeRef.set(new TextRange(start, end));
           }
         }
       });
   return rangeRef.get();
 }
  @Nullable
  public static PsiType getQualifiedMemberReferenceType(
      @Nullable PsiType qualifierType, @NotNull final PsiMember member) {
    final Ref<PsiSubstitutor> subst = Ref.create(PsiSubstitutor.EMPTY);
    class MyProcessor extends BaseScopeProcessor implements NameHint, ElementClassHint {
      @Override
      public boolean execute(@NotNull PsiElement element, @NotNull ResolveState state) {
        if (element == member) {
          subst.set(state.get(PsiSubstitutor.KEY));
        }
        return true;
      }

      @Override
      public String getName(@NotNull ResolveState state) {
        return member.getName();
      }

      @Override
      public boolean shouldProcess(DeclarationKind kind) {
        return member instanceof PsiEnumConstant
            ? kind == DeclarationKind.ENUM_CONST
            : member instanceof PsiField
                ? kind == DeclarationKind.FIELD
                : kind == DeclarationKind.METHOD;
      }

      @Override
      public <T> T getHint(@NotNull Key<T> hintKey) {
        return hintKey == NameHint.KEY || hintKey == ElementClassHint.KEY ? (T) this : null;
      }
    }

    PsiScopesUtil.processTypeDeclarations(qualifierType, member, new MyProcessor());

    PsiType rawType =
        member instanceof PsiField
            ? ((PsiField) member).getType()
            : member instanceof PsiMethod
                ? ((PsiMethod) member).getReturnType()
                : JavaPsiFacade.getElementFactory(member.getProject())
                    .createType((PsiClass) member);
    return subst.get().substitute(rawType);
  }
 public void openFiles() {
   if (mySplittersElement != null) {
     Ref<EditorWindow> currentWindow = new Ref<EditorWindow>();
     final JPanel comp = readExternalPanel(mySplittersElement, getTopPanel(), currentWindow);
     if (comp != null) {
       removeAll();
       add(comp, BorderLayout.CENTER);
       mySplittersElement = null;
     }
     // clear empty splitters
     for (EditorWindow window : getWindows()) {
       if (window.getEditors().length == 0) {
         for (EditorWindow sibling : window.findSiblings()) {
           sibling.unsplit(false);
         }
       }
     }
     if (!currentWindow.isNull()) {
       setCurrentWindow(currentWindow.get(), true);
     }
   }
 }
    @Override
    protected JPanel processFiles(@NotNull List<Element> fileElements, final JPanel context) {
      final Ref<EditorWindow> windowRef = new Ref<EditorWindow>();
      UIUtil.invokeAndWaitIfNeeded(
          new Runnable() {
            @Override
            public void run() {
              windowRef.set(context == null ? createEditorWindow() : findWindowWith(context));
            }
          });
      final EditorWindow window = windowRef.get();
      LOG.assertTrue(window != null);
      VirtualFile focusedFile = null;

      for (int i = 0; i < fileElements.size(); i++) {
        final Element file = fileElements.get(i);
        if (i == 0) {
          EditorTabbedContainer tabbedPane = window.getTabbedPane();
          if (tabbedPane != null) {
            try {
              int limit =
                  Integer.parseInt(
                      file.getParentElement()
                          .getAttributeValue(
                              JBTabsImpl.SIDE_TABS_SIZE_LIMIT_KEY.toString(),
                              String.valueOf(JBTabsImpl.DEFAULT_MAX_TAB_WIDTH)));
              UIUtil.putClientProperty(
                  tabbedPane.getComponent(), JBTabsImpl.SIDE_TABS_SIZE_LIMIT_KEY, limit);
            } catch (NumberFormatException e) {
              // ignore
            }
          }
        }
        try {
          final FileEditorManagerImpl fileEditorManager = getManager();
          Element historyElement = file.getChild(HistoryEntry.TAG);
          final HistoryEntry entry =
              HistoryEntry.createLight(fileEditorManager.getProject(), historyElement);
          final VirtualFile virtualFile = entry.getFile();
          if (virtualFile == null)
            throw new InvalidDataException("No file exists: " + entry.getFilePointer().getUrl());
          Document document =
              ApplicationManager.getApplication()
                  .runReadAction(
                      new Computable<Document>() {
                        @Override
                        public Document compute() {
                          return virtualFile.isValid()
                              ? FileDocumentManager.getInstance().getDocument(virtualFile)
                              : null;
                        }
                      });
          final boolean isCurrentInTab =
              Boolean.valueOf(file.getAttributeValue(CURRENT_IN_TAB)).booleanValue();
          Boolean pin = Boolean.valueOf(file.getAttributeValue(PINNED));
          fileEditorManager.openFileImpl4(
              window, virtualFile, entry, isCurrentInTab, isCurrentInTab, pin, i);
          if (isCurrentInTab) {
            focusedFile = virtualFile;
          }
          if (document != null) {
            // This is just to make sure document reference is kept on stack till this point
            // so that document is available for folding state deserialization in HistoryEntry
            // constructor
            // and that document will be created only once during file opening
            document.putUserData(DUMMY_KEY, null);
          }
          updateProgress();
        } catch (InvalidDataException e) {
          if (ApplicationManager.getApplication().isUnitTestMode()) {
            LOG.error(e);
          }
        }
      }
      if (focusedFile != null) {
        getManager().addSelectionRecord(focusedFile, window);
      }
      return window.myPanel;
    }
  private int extractExpectedHighlight(
      final Matcher matcher,
      final String text,
      final Document document,
      final Ref<Integer> textOffset) {
    document.deleteString(textOffset.get(), textOffset.get() + matcher.end() - matcher.start());

    int groupIdx = 1;
    final String marker = matcher.group(groupIdx++);
    String descr = matcher.group(groupIdx++);
    final String typeString = matcher.group(groupIdx++);
    final String foregroundColor = matcher.group(groupIdx++);
    final String backgroundColor = matcher.group(groupIdx++);
    final String effectColor = matcher.group(groupIdx++);
    final String effectType = matcher.group(groupIdx++);
    final String fontType = matcher.group(groupIdx++);
    final String attrKey = matcher.group(groupIdx++);
    final String bundleMessage = matcher.group(groupIdx++);
    final boolean closed = matcher.group(groupIdx) != null;

    if (descr == null) {
      descr = ANY_TEXT; // no descr means any string by default
    } else if (descr.equals("null")) {
      descr = null; // explicit "null" descr
    }
    if (descr != null) {
      descr =
          descr.replaceAll(
              "\\\\\\\\\"", "\""); // replace: \\" to ", doesn't check symbol before sequence \\"
      descr = descr.replaceAll("\\\\\"", "\"");
    }

    HighlightInfoType type = WHATEVER;
    if (typeString != null) {
      try {
        type = getTypeByName(typeString);
      } catch (Exception e) {
        LOG.error(e);
      }
      LOG.assertTrue(type != null, "Wrong highlight type: " + typeString);
    }

    TextAttributes forcedAttributes = null;
    if (foregroundColor != null) {
      //noinspection MagicConstant
      forcedAttributes =
          new TextAttributes(
              Color.decode(foregroundColor),
              Color.decode(backgroundColor),
              Color.decode(effectColor),
              EffectType.valueOf(effectType),
              Integer.parseInt(fontType));
    }

    final int rangeStart = textOffset.get();
    final int toContinueFrom;
    if (closed) {
      toContinueFrom = matcher.end();
    } else {
      int pos = matcher.end();
      final Matcher closingTagMatcher = Pattern.compile("</" + marker + ">").matcher(text);
      while (true) {
        if (!closingTagMatcher.find(pos)) {
          LOG.error("Cannot find closing </" + marker + "> in position " + pos);
        }

        final int nextTagStart = matcher.find(pos) ? matcher.start() : text.length();
        if (closingTagMatcher.start() < nextTagStart) {
          textOffset.set(textOffset.get() + closingTagMatcher.start() - pos);
          document.deleteString(
              textOffset.get(),
              textOffset.get() + closingTagMatcher.end() - closingTagMatcher.start());
          toContinueFrom = closingTagMatcher.end();
          break;
        }

        textOffset.set(textOffset.get() + nextTagStart - pos);
        pos = extractExpectedHighlight(matcher, text, document, textOffset);
      }
    }

    final ExpectedHighlightingSet expectedHighlightingSet = myHighlightingTypes.get(marker);
    if (expectedHighlightingSet.enabled) {
      TextAttributesKey forcedTextAttributesKey =
          attrKey == null ? null : TextAttributesKey.createTextAttributesKey(attrKey);
      HighlightInfo.Builder builder =
          HighlightInfo.newHighlightInfo(type)
              .range(rangeStart, textOffset.get())
              .severity(expectedHighlightingSet.severity);

      if (forcedAttributes != null) builder.textAttributes(forcedAttributes);
      if (forcedTextAttributesKey != null) builder.textAttributes(forcedTextAttributesKey);
      if (bundleMessage != null) {
        final List<String> split = StringUtil.split(bundleMessage, "|");
        final ResourceBundle bundle = ResourceBundle.getBundle(split.get(0));
        descr = CommonBundle.message(bundle, split.get(1), split.stream().skip(2).toArray());
      }
      if (descr != null) {
        builder.description(descr);
        builder.unescapedToolTip(descr);
      }
      if (expectedHighlightingSet.endOfLine) builder.endOfLine();
      HighlightInfo highlightInfo = builder.createUnconditionally();
      expectedHighlightingSet.infos.add(highlightInfo);
    }

    return toContinueFrom;
  }
  private void buildOutputItemsList(
      final String outputDir,
      final Module module,
      VirtualFile from,
      final FileTypeManager typeManager,
      final VirtualFile sourceRoot,
      final String packagePrefix,
      final List<File> filesToRefresh,
      final Map<String, Collection<TranslatingCompiler.OutputItem>> results)
      throws CacheCorruptedException {
    final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
    final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex();
    final GlobalSearchScope srcRootScope =
        GlobalSearchScope.moduleScope(module)
            .intersectWith(GlobalSearchScopes.directoryScope(myProject, sourceRoot, true));

    final Collection<FileType> registeredInputTypes =
        CompilerManager.getInstance(myProject).getRegisteredInputTypes(myTranslatingCompiler);

    final ContentIterator contentIterator =
        new ContentIterator() {
          public boolean processFile(final VirtualFile child) {
            try {
              if (child.isValid()) {
                if (!child.isDirectory() && registeredInputTypes.contains(child.getFileType())) {
                  updateOutputItemsList(
                      outputDir,
                      child,
                      sourceRoot,
                      packagePrefix,
                      filesToRefresh,
                      results,
                      srcRootScope);
                }
              }
              return true;
            } catch (CacheCorruptedException e) {
              exRef.set(e);
              return false;
            }
          }
        };
    if (fileIndex.isInContent(from)) {
      // use file index for iteration to handle 'inner modules' and excludes properly
      fileIndex.iterateContentUnderDirectory(from, contentIterator);
    } else {
      // seems to be a root for generated sources
      VfsUtilCore.visitChildrenRecursively(
          from,
          new VirtualFileVisitor() {
            @Override
            public boolean visitFile(@NotNull VirtualFile file) {
              if (!file.isDirectory()) {
                contentIterator.processFile(file);
              }
              return true;
            }
          });
    }
    final CacheCorruptedException exc = exRef.get();
    if (exc != null) {
      throw exc;
    }
  }