private boolean handshake() {
   boolean res;
   long started = System.currentTimeMillis();
   do {
     try {
       res = myPydevConsoleCommunication.handshake();
     } catch (XmlRpcException ignored) {
       res = false;
     }
     if (res) {
       break;
     } else {
       long now = System.currentTimeMillis();
       if (now - started > APPROPRIATE_TO_WAIT) {
         break;
       } else {
         try {
           Thread.sleep(100);
         } catch (InterruptedException ignored) {
         }
       }
     }
   } while (true);
   return res;
 }
  public Notification(
      @NotNull String groupDisplayId,
      @NotNull Icon icon,
      @Nullable String title,
      @Nullable String subtitle,
      @Nullable String content,
      @NotNull NotificationType type,
      @Nullable NotificationListener listener) {
    myGroupId = groupDisplayId;
    myTitle = StringUtil.notNullize(title);
    myContent = StringUtil.notNullize(content);
    myType = type;
    myListener = listener;
    myTimestamp = System.currentTimeMillis();

    myIcon = icon;
    mySubtitle = subtitle;

    LOG.assertTrue(
        isTitle() || isContent(),
        "Notification should have title: "
            + title
            + " and/or subtitle and/or content groupId: "
            + myGroupId);

    id =
        String.valueOf(System.currentTimeMillis())
            + "."
            + String.valueOf(System.identityHashCode(this));
  }
 @Override
 public int compare(AbstractFoldingAreaPainter afap1, AbstractFoldingAreaPainter afap2) {
   if (afap1.getWeight() == afap2.getWeight() && !afap1.equals(afap2)) {
     return System.identityHashCode(afap1) - System.identityHashCode(afap2);
   }
   return afap1.getWeight() - afap2.getWeight();
 }
  public static InputEvent getInputEvent(String actionName) {
    final Shortcut[] shortcuts =
        KeymapManager.getInstance().getActiveKeymap().getShortcuts(actionName);
    KeyStroke keyStroke = null;
    for (Shortcut each : shortcuts) {
      if (each instanceof KeyboardShortcut) {
        keyStroke = ((KeyboardShortcut) each).getFirstKeyStroke();
        if (keyStroke != null) break;
      }
    }

    if (keyStroke != null) {
      return new KeyEvent(
          JOptionPane.getRootFrame(),
          KeyEvent.KEY_PRESSED,
          System.currentTimeMillis(),
          keyStroke.getModifiers(),
          keyStroke.getKeyCode(),
          keyStroke.getKeyChar(),
          KeyEvent.KEY_LOCATION_STANDARD);
    } else {
      return new MouseEvent(
          JOptionPane.getRootFrame(),
          MouseEvent.MOUSE_PRESSED,
          0,
          0,
          0,
          0,
          1,
          false,
          MouseEvent.BUTTON1);
    }
  }
 private static void patchSystemFileEncoding(String encoding)
     throws NoSuchFieldException, IllegalAccessException {
   Field charset = Charset.class.getDeclaredField("defaultCharset");
   charset.setAccessible(true);
   charset.set(Charset.class, null);
   System.setProperty("file.encoding", encoding);
 }
  /**
   * @param groupDisplayId this should be a human-readable, capitalized string like "Facet
   *     Detector". It will appear in "Notifications" configurable.
   * @param title notification title
   * @param content notification content
   * @param type notification type
   * @param listener notification lifecycle listener
   */
  public Notification(
      @NotNull String groupDisplayId,
      @NotNull String title,
      @NotNull String content,
      @NotNull NotificationType type,
      @Nullable NotificationListener listener) {
    myGroupId = groupDisplayId;
    myTitle = title;
    myContent = content;
    myType = type;
    myListener = listener;
    myTimestamp = System.currentTimeMillis();

    LOG.assertTrue(
        isContent(),
        "Notification should have content, title: " + title + ", groupId: " + myGroupId);
    id = String.valueOf(System.currentTimeMillis()) + "." + String.valueOf(hashCode());
  }
 public static void assertTiming(
     String message, long expected, int attempts, @NotNull Runnable actionToMeasure) {
   while (true) {
     attempts--;
     long duration = measure(actionToMeasure);
     try {
       assertTiming(message, expected, duration);
       break;
     } catch (AssertionFailedError e) {
       if (attempts == 0) throw e;
       System.gc();
       System.gc();
       System.gc();
       String s = "Another epic fail (remaining attempts: " + attempts + "): " + e.getMessage();
       TeamCityLogger.warning(s, null);
       System.err.println(s);
     }
   }
 }
 @NotNull
 private String[] getRecentFiles() {
   final String[] recent = PropertiesComponent.getInstance().getValues(RECENT_FILES_KEY);
   if (recent != null) {
     if (recent.length > 0
         && myPathTextField.getField().getText().replace('\\', '/').equals(recent[0])) {
       final String[] pathes = new String[recent.length - 1];
       System.arraycopy(recent, 1, pathes, 0, recent.length - 1);
       return pathes;
     }
     return recent;
   }
   return ArrayUtil.EMPTY_STRING_ARRAY;
 }
  private static int readInt(Scanner s, Process process) throws ExecutionException {
    long started = System.currentTimeMillis();

    while (System.currentTimeMillis() - started < PORTS_WAITING_TIMEOUT) {
      if (s.hasNextLine()) {
        String line = s.nextLine();
        try {
          return Integer.parseInt(line);
        } catch (NumberFormatException ignored) {
          continue;
        }
      }

      try {

        Thread.sleep(200);
      } catch (InterruptedException ignored) {
      }

      if (process.exitValue() != 0) {
        String error;
        try {
          error =
              "Console process terminated with error:\n"
                  + StreamUtil.readText(process.getErrorStream());
        } catch (Exception ignored) {
          error = "Console process terminated with exit code " + process.exitValue();
        }
        throw new ExecutionException(error);
      } else {
        break;
      }
    }

    throw new ExecutionException("Couldn't read integer value from stream");
  }
  IdeRootPane(
      ActionManagerEx actionManager,
      UISettings uiSettings,
      DataManager dataManager,
      final Application application,
      final String[] commandLineArgs,
      IdeFrame frame) {
    myActionManager = actionManager;
    myUISettings = uiSettings;

    updateToolbar();
    myContentPane.add(myNorthPanel, BorderLayout.NORTH);

    myStatusBarCustomComponentFactories =
        application.getExtensions(StatusBarCustomComponentFactory.EP_NAME);
    myApplication = application;

    createStatusBar(frame);

    updateStatusBarVisibility();

    myContentPane.add(myStatusBar, BorderLayout.SOUTH);

    myUISettingsListener = new MyUISettingsListenerImpl();
    setJMenuBar(new IdeMenuBar(actionManager, dataManager));

    final Ref<Boolean> willOpenProject = new Ref<Boolean>(Boolean.FALSE);
    final AppLifecycleListener lifecyclePublisher =
        application.getMessageBus().syncPublisher(AppLifecycleListener.TOPIC);
    lifecyclePublisher.appFrameCreated(commandLineArgs, willOpenProject);
    LOG.info(
        "App initialization took "
            + (System.nanoTime() - PluginManager.startupStart) / 1000000
            + " ms");
    PluginManager.dumpPluginClassStatistics();
    if (!willOpenProject.get()) {
      showWelcomeScreen();
      lifecyclePublisher.welcomeScreenDisplayed();
    }

    myGlassPane = new IdeGlassPaneImpl(this);
    setGlassPane(myGlassPane);
    myGlassPaneInitialized = true;

    myGlassPane.setVisible(false);
    Disposer.register(application, myDisposable);
  }
Exemple #11
0
  public XDebuggerTree(
      final @NotNull Project project,
      final @NotNull XDebuggerEditorsProvider editorsProvider,
      final @Nullable XSourcePosition sourcePosition,
      final @NotNull String popupActionGroupId,
      @Nullable XValueMarkers<?, ?> valueMarkers) {
    myValueMarkers = valueMarkers;
    myProject = project;
    myEditorsProvider = editorsProvider;
    mySourcePosition = sourcePosition;
    myTreeModel = new DefaultTreeModel(null);
    setModel(myTreeModel);
    setCellRenderer(new XDebuggerTreeRenderer());
    new TreeLinkMouseListener(new XDebuggerTreeRenderer()) {
      @Override
      protected boolean doCacheLastNode() {
        return false;
      }

      @Override
      protected void handleTagClick(@Nullable Object tag, @NotNull MouseEvent event) {
        if (tag instanceof XDebuggerTreeNodeHyperlink) {
          ((XDebuggerTreeNodeHyperlink) tag).onClick(event);
        }
      }
    }.installOn(this);
    setRootVisible(false);
    setShowsRootHandles(true);

    new DoubleClickListener() {
      @Override
      protected boolean onDoubleClick(MouseEvent e) {
        return expandIfEllipsis();
      }
    }.installOn(this);

    addKeyListener(
        new KeyAdapter() {
          @Override
          public void keyPressed(KeyEvent e) {
            int key = e.getKeyCode();
            if (key == KeyEvent.VK_ENTER || key == KeyEvent.VK_SPACE || key == KeyEvent.VK_RIGHT) {
              expandIfEllipsis();
            }
          }
        });

    if (Boolean.valueOf(System.getProperty("xdebugger.variablesView.rss"))) {
      new XDebuggerTreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
    } else {
      new TreeSpeedSearch(this, SPEED_SEARCH_CONVERTER);
    }

    final ActionManager actionManager = ActionManager.getInstance();
    addMouseListener(
        new PopupHandler() {
          @Override
          public void invokePopup(final Component comp, final int x, final int y) {
            ActionGroup group = (ActionGroup) actionManager.getAction(popupActionGroupId);
            actionManager
                .createActionPopupMenu(ActionPlaces.UNKNOWN, group)
                .getComponent()
                .show(comp, x, y);
          }
        });
    registerShortcuts();

    setTransferHandler(DEFAULT_TRANSFER_HANDLER);

    addComponentListener(myMoveListener);
  }
    public void showPreview(@Nullable ResourceItem element) {
      CardLayout layout = (CardLayout) myPreviewPanel.getLayout();

      if (element == null || element.getGroup().getType() == ResourceType.ID) {
        layout.show(myPreviewPanel, NONE);
        return;
      }

      try {
        VirtualFile file = element.getFile();
        if (file == null) {
          String value = element.getPreviewString();
          if (value == null) {
            java.util.List<ResourceElement> resources = element.getPreviewResources();

            if (resources == null) {
              long time = System.currentTimeMillis();
              resources =
                  myManager.findValueResources(
                      element.getGroup().getType().getName(), element.toString());
              if (ApplicationManagerEx.getApplicationEx().isInternal()) {
                System.out.println("Time: " + (System.currentTimeMillis() - time)); // XXX
              }

              int size = resources.size();
              if (size == 1) {
                value = getResourceElementValue(resources.get(0));
                element.setPreviewString(value);
              } else if (size > 1) {
                resources = new ArrayList<ResourceElement>(resources);
                Collections.sort(
                    resources,
                    new Comparator<ResourceElement>() {
                      @Override
                      public int compare(ResourceElement element1, ResourceElement element2) {
                        PsiDirectory directory1 =
                            element1.getXmlTag().getContainingFile().getParent();
                        PsiDirectory directory2 =
                            element2.getXmlTag().getContainingFile().getParent();

                        if (directory1 == null && directory2 == null) {
                          return 0;
                        }
                        if (directory2 == null) {
                          return 1;
                        }
                        if (directory1 == null) {
                          return -1;
                        }

                        return directory1.getName().compareTo(directory2.getName());
                      }
                    });

                DefaultComboBoxModel model = new DefaultComboBoxModel();
                String defaultSelection = null;
                for (int i = 0; i < size; i++) {
                  ResourceElement resource = resources.get(i);
                  PsiDirectory directory = resource.getXmlTag().getContainingFile().getParent();
                  String name = directory == null ? "unknown-" + i : directory.getName();
                  model.addElement(name);
                  if (defaultSelection == null && "values".equalsIgnoreCase(name)) {
                    defaultSelection = name;
                  }
                }
                element.setPreviewResources(resources, model, defaultSelection);

                showComboPreview(element);
                return;
              } else {
                layout.show(myPreviewPanel, NONE);
                return;
              }
            } else {
              showComboPreview(element);
              return;
            }
          }
          if (value == null) {
            layout.show(myPreviewPanel, NONE);
            return;
          }

          myTextArea.setText(value);
          layout.show(myPreviewPanel, TEXT);
        } else if (ImageFileTypeManager.getInstance().isImage(file)) {
          Icon icon = element.getPreviewIcon();
          if (icon == null) {
            icon = new SizedIcon(100, 100, new ImageIcon(file.getPath()));
            element.setPreviewIcon(icon);
          }
          myImageComponent.setIcon(icon);
          layout.show(myPreviewPanel, IMAGE);
        } else if (file.getFileType() == XmlFileType.INSTANCE) {
          String value = element.getPreviewString();
          if (value == null) {
            value = new String(file.contentsToByteArray());
            element.setPreviewString(value);
          }
          myTextArea.setText(value);
          myTextArea.setEditable(false);
          layout.show(myPreviewPanel, TEXT);
        } else {
          layout.show(myPreviewPanel, NONE);
        }
      } catch (IOException e) {
        layout.show(myPreviewPanel, NONE);
      }
    }
/** @author yole */
@SuppressWarnings("UseOfSystemOutOrSystemErr")
public class PlatformTestUtil {
  public static final boolean COVERAGE_ENABLED_BUILD =
      "true".equals(System.getProperty("idea.coverage.enabled.build"));
  public static final byte[] EMPTY_JAR_BYTES = {
    0x50, 0x4b, 0x05, 0x06, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
  };

  public static <T> void registerExtension(
      final ExtensionPointName<T> name, final T t, final Disposable parentDisposable) {
    registerExtension(Extensions.getRootArea(), name, t, parentDisposable);
  }

  public static <T> void registerExtension(
      final ExtensionsArea area,
      final ExtensionPointName<T> name,
      final T t,
      final Disposable parentDisposable) {
    final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(name.getName());
    extensionPoint.registerExtension(t);
    Disposer.register(
        parentDisposable,
        new Disposable() {
          @Override
          public void dispose() {
            extensionPoint.unregisterExtension(t);
          }
        });
  }

  @Nullable
  protected static String toString(@Nullable Object node, @Nullable Queryable.PrintInfo printInfo) {
    if (node instanceof AbstractTreeNode) {
      if (printInfo != null) {
        return ((AbstractTreeNode) node).toTestString(printInfo);
      } else {
        @SuppressWarnings({"deprecation", "UnnecessaryLocalVariable"})
        final String presentation = ((AbstractTreeNode) node).getTestPresentation();
        return presentation;
      }
    }
    if (node == null) {
      return "NULL";
    }
    return node.toString();
  }

  public static String print(JTree tree, boolean withSelection) {
    return print(tree, withSelection, null);
  }

  public static String print(
      JTree tree, boolean withSelection, @Nullable Condition<String> nodePrintCondition) {
    StringBuilder buffer = new StringBuilder();
    final Collection<String> strings = printAsList(tree, withSelection, nodePrintCondition);
    for (String string : strings) {
      buffer.append(string).append("\n");
    }
    return buffer.toString();
  }

  public static Collection<String> printAsList(
      JTree tree, boolean withSelection, @Nullable Condition<String> nodePrintCondition) {
    Collection<String> strings = new ArrayList<String>();
    Object root = tree.getModel().getRoot();
    printImpl(tree, root, strings, 0, withSelection, nodePrintCondition);
    return strings;
  }

  private static void printImpl(
      JTree tree,
      Object root,
      Collection<String> strings,
      int level,
      boolean withSelection,
      @Nullable Condition<String> nodePrintCondition) {
    DefaultMutableTreeNode defaultMutableTreeNode = (DefaultMutableTreeNode) root;

    final Object userObject = defaultMutableTreeNode.getUserObject();
    String nodeText;
    if (userObject != null) {
      nodeText = toString(userObject, null);
    } else {
      nodeText = "null";
    }

    if (nodePrintCondition != null && !nodePrintCondition.value(nodeText)) return;

    final StringBuilder buff = new StringBuilder();
    StringUtil.repeatSymbol(buff, ' ', level);

    final boolean expanded = tree.isExpanded(new TreePath(defaultMutableTreeNode.getPath()));
    if (!defaultMutableTreeNode.isLeaf()) {
      buff.append(expanded ? "-" : "+");
    }

    final boolean selected =
        tree.getSelectionModel().isPathSelected(new TreePath(defaultMutableTreeNode.getPath()));
    if (withSelection && selected) {
      buff.append("[");
    }

    buff.append(nodeText);

    if (withSelection && selected) {
      buff.append("]");
    }

    strings.add(buff.toString());

    int childCount = tree.getModel().getChildCount(root);
    if (expanded) {
      for (int i = 0; i < childCount; i++) {
        printImpl(
            tree,
            tree.getModel().getChild(root, i),
            strings,
            level + 1,
            withSelection,
            nodePrintCondition);
      }
    }
  }

  public static void assertTreeEqual(JTree tree, @NonNls String expected) {
    assertTreeEqual(tree, expected, false);
  }

  public static void assertTreeEqualIgnoringNodesOrder(JTree tree, @NonNls String expected) {
    assertTreeEqualIgnoringNodesOrder(tree, expected, false);
  }

  public static void assertTreeEqual(JTree tree, String expected, boolean checkSelected) {
    String treeStringPresentation = print(tree, checkSelected);
    assertEquals(expected, treeStringPresentation);
  }

  public static void assertTreeEqualIgnoringNodesOrder(
      JTree tree, String expected, boolean checkSelected) {
    final Collection<String> actualNodesPresentation = printAsList(tree, checkSelected, null);
    final List<String> expectedNodes = StringUtil.split(expected, "\n");
    UsefulTestCase.assertSameElements(actualNodesPresentation, expectedNodes);
  }

  @TestOnly
  public static void waitForAlarm(final int delay) throws InterruptedException {
    assert !ApplicationManager.getApplication().isWriteAccessAllowed()
        : "It's a bad idea to wait for an alarm under the write action. Somebody creates an alarm which requires read action and you are deadlocked.";
    assert ApplicationManager.getApplication().isDispatchThread();

    final AtomicBoolean invoked = new AtomicBoolean();
    final Alarm alarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD);
    alarm.addRequest(
        new Runnable() {
          @Override
          public void run() {
            ApplicationManager.getApplication()
                .invokeLater(
                    new Runnable() {
                      @Override
                      public void run() {
                        alarm.addRequest(
                            new Runnable() {
                              @Override
                              public void run() {
                                invoked.set(true);
                              }
                            },
                            delay);
                      }
                    });
          }
        },
        delay);

    UIUtil.dispatchAllInvocationEvents();

    boolean sleptAlready = false;
    while (!invoked.get()) {
      UIUtil.dispatchAllInvocationEvents();
      //noinspection BusyWait
      Thread.sleep(sleptAlready ? 10 : delay);
      sleptAlready = true;
    }
    UIUtil.dispatchAllInvocationEvents();
  }

  @TestOnly
  public static void dispatchAllInvocationEventsInIdeEventQueue() throws InterruptedException {
    assert SwingUtilities.isEventDispatchThread() : Thread.currentThread();
    final EventQueue eventQueue = Toolkit.getDefaultToolkit().getSystemEventQueue();
    while (true) {
      AWTEvent event = eventQueue.peekEvent();
      if (event == null) break;
      AWTEvent event1 = eventQueue.getNextEvent();
      if (event1 instanceof InvocationEvent) {
        IdeEventQueue.getInstance().dispatchEvent(event1);
      }
    }
  }

  private static Date raidDate(Bombed bombed) {
    final Calendar instance = Calendar.getInstance();
    instance.set(Calendar.YEAR, bombed.year());
    instance.set(Calendar.MONTH, bombed.month());
    instance.set(Calendar.DAY_OF_MONTH, bombed.day());
    instance.set(Calendar.HOUR_OF_DAY, bombed.time());
    instance.set(Calendar.MINUTE, 0);

    return instance.getTime();
  }

  public static boolean bombExplodes(Bombed bombedAnnotation) {
    Date now = new Date();
    return now.after(raidDate(bombedAnnotation));
  }

  public static boolean isRotten(Bombed bomb) {
    long bombRotPeriod = 30L * 24 * 60 * 60 * 1000; // month
    return new Date().after(new Date(raidDate(bomb).getTime() + bombRotPeriod));
  }

  public static StringBuilder print(
      AbstractTreeStructure structure,
      Object node,
      int currentLevel,
      @Nullable Comparator comparator,
      int maxRowCount,
      char paddingChar,
      @Nullable Queryable.PrintInfo printInfo) {
    StringBuilder buffer = new StringBuilder();
    doPrint(
        buffer, currentLevel, node, structure, comparator, maxRowCount, 0, paddingChar, printInfo);
    return buffer;
  }

  private static int doPrint(
      StringBuilder buffer,
      int currentLevel,
      Object node,
      AbstractTreeStructure structure,
      @Nullable Comparator comparator,
      int maxRowCount,
      int currentLine,
      char paddingChar,
      @Nullable Queryable.PrintInfo printInfo) {
    if (currentLine >= maxRowCount && maxRowCount != -1) return currentLine;

    StringUtil.repeatSymbol(buffer, paddingChar, currentLevel);
    buffer.append(toString(node, printInfo)).append("\n");
    currentLine++;
    Object[] children = structure.getChildElements(node);

    if (comparator != null) {
      ArrayList<?> list = new ArrayList<Object>(Arrays.asList(children));
      @SuppressWarnings({"UnnecessaryLocalVariable", "unchecked"})
      Comparator<Object> c = comparator;
      Collections.sort(list, c);
      children = ArrayUtil.toObjectArray(list);
    }
    for (Object child : children) {
      currentLine =
          doPrint(
              buffer,
              currentLevel + 1,
              child,
              structure,
              comparator,
              maxRowCount,
              currentLine,
              paddingChar,
              printInfo);
    }

    return currentLine;
  }

  public static String print(Object[] objects) {
    return print(Arrays.asList(objects));
  }

  public static String print(Collection c) {
    StringBuilder result = new StringBuilder();
    for (Iterator iterator = c.iterator(); iterator.hasNext(); ) {
      Object each = iterator.next();
      result.append(toString(each, null));
      if (iterator.hasNext()) {
        result.append("\n");
      }
    }

    return result.toString();
  }

  public static String print(ListModel model) {
    StringBuilder result = new StringBuilder();
    for (int i = 0; i < model.getSize(); i++) {
      result.append(toString(model.getElementAt(i), null));
      result.append("\n");
    }
    return result.toString();
  }

  public static String print(JTree tree) {
    return print(tree, false);
  }

  public static void assertTreeStructureEquals(
      final AbstractTreeStructure treeStructure, final String expected) {
    assertEquals(
        expected,
        print(treeStructure, treeStructure.getRootElement(), 0, null, -1, ' ', null).toString());
  }

  public static void invokeNamedAction(final String actionId) {
    final AnAction action = ActionManager.getInstance().getAction(actionId);
    assertNotNull(action);
    final Presentation presentation = new Presentation();
    @SuppressWarnings("deprecation")
    final DataContext context = DataManager.getInstance().getDataContext();
    final AnActionEvent event =
        new AnActionEvent(null, context, "", presentation, ActionManager.getInstance(), 0);
    action.update(event);
    Assert.assertTrue(presentation.isEnabled());
    action.actionPerformed(event);
  }

  public static void assertTiming(final String message, final long expectedMs, final long actual) {
    if (COVERAGE_ENABLED_BUILD) return;

    final long expectedOnMyMachine =
        Math.max(1, expectedMs * Timings.MACHINE_TIMING / Timings.ETALON_TIMING);

    // Allow 10% more in case of test machine is busy.
    String logMessage = message;
    if (actual > expectedOnMyMachine) {
      int percentage = (int) (100.0 * (actual - expectedOnMyMachine) / expectedOnMyMachine);
      logMessage += ". Operation took " + percentage + "% longer than expected";
    }
    logMessage +=
        ". Expected on my machine: "
            + expectedOnMyMachine
            + "."
            + " Actual: "
            + actual
            + "."
            + " Expected on Standard machine: "
            + expectedMs
            + ";"
            + " Actual on Standard: "
            + actual * Timings.ETALON_TIMING / Timings.MACHINE_TIMING
            + ";"
            + " Timings: CPU="
            + Timings.CPU_TIMING
            + ", I/O="
            + Timings.IO_TIMING
            + "."
            + " ("
            + (int) (Timings.MACHINE_TIMING * 1.0 / Timings.ETALON_TIMING * 100)
            + "% of the Standard)"
            + ".";
    final double acceptableChangeFactor = 1.1;
    if (actual < expectedOnMyMachine) {
      System.out.println(logMessage);
      TeamCityLogger.info(logMessage);
    } else if (actual < expectedOnMyMachine * acceptableChangeFactor) {
      TeamCityLogger.warning(logMessage, null);
    } else {
      // throw AssertionFailedError to try one more time
      throw new AssertionFailedError(logMessage);
    }
  }

  /**
   * example usage: startPerformanceTest("calculating pi",100,
   * testRunnable).cpuBound().assertTiming();
   */
  public static TestInfo startPerformanceTest(
      @NonNls @NotNull String message, int expectedMs, @NotNull ThrowableRunnable test) {
    return new TestInfo(test, expectedMs, message);
  }

  // calculates average of the median values in the selected part of the array. E.g. for part=3
  // returns average in the middle third.
  public static long averageAmongMedians(@NotNull long[] time, int part) {
    assert part >= 1;
    int n = time.length;
    Arrays.sort(time);
    long total = 0;
    for (int i = n / 2 - n / part / 2; i < n / 2 + n / part / 2; i++) {
      total += time[i];
    }
    return total / (n / part);
  }

  public static boolean canRunTest(@NotNull Class testCaseClass) {
    if (GraphicsEnvironment.isHeadless()) {
      for (Class<?> clazz = testCaseClass; clazz != null; clazz = clazz.getSuperclass()) {
        if (clazz.getAnnotation(SkipInHeadlessEnvironment.class) != null) {
          System.out.println(
              "Class '"
                  + testCaseClass.getName()
                  + "' is skipped because it requires working UI environment");
          return false;
        }
      }
    }
    return true;
  }

  public static void assertPathsEqual(@Nullable String expected, @Nullable String actual) {
    if (expected != null) expected = FileUtil.toSystemIndependentName(expected);
    if (actual != null) actual = FileUtil.toSystemIndependentName(actual);
    assertEquals(expected, actual);
  }

  public static class TestInfo {
    private final ThrowableRunnable test; // runnable to measure
    private final int expectedMs; // millis the test is expected to run
    private ThrowableRunnable setup; // to run before each test
    private boolean usesAllCPUCores; // true if the test runs faster on multi-core
    private int attempts = 4; // number of retries if performance failed
    private final String message; // to print on fail
    private boolean adjustForIO =
        true; // true if test uses IO, timings need to be re-calibrated according to this agent disk
              // performance
    private boolean adjustForCPU =
        true; // true if test uses CPU, timings need to be re-calibrated according to this agent CPU
              // speed

    private TestInfo(@NotNull ThrowableRunnable test, int expectedMs, String message) {
      this.test = test;
      this.expectedMs = expectedMs;
      assert expectedMs > 0 : "Expected must be > 0. Was: " + expectedMs;
      this.message = message;
    }

    public TestInfo setup(@NotNull ThrowableRunnable setup) {
      assert this.setup == null;
      this.setup = setup;
      return this;
    }

    public TestInfo usesAllCPUCores() {
      assert adjustForCPU : "This test configured to be io-bound, it cannot use all cores";
      usesAllCPUCores = true;
      return this;
    }

    public TestInfo cpuBound() {
      adjustForIO = false;
      adjustForCPU = true;
      return this;
    }

    public TestInfo ioBound() {
      adjustForIO = true;
      adjustForCPU = false;
      return this;
    }

    public TestInfo attempts(int attempts) {
      this.attempts = attempts;
      return this;
    }

    public void assertTiming() {
      assert expectedMs != 0 : "Must call .expect() before run test";
      if (COVERAGE_ENABLED_BUILD) return;

      while (true) {
        attempts--;
        long start;
        try {
          if (setup != null) setup.run();
          start = System.currentTimeMillis();
          test.run();
        } catch (Throwable throwable) {
          throw new RuntimeException(throwable);
        }
        long finish = System.currentTimeMillis();
        long duration = finish - start;

        int expectedOnMyMachine = expectedMs;
        if (adjustForCPU) {
          expectedOnMyMachine =
              adjust(expectedOnMyMachine, Timings.CPU_TIMING, Timings.ETALON_CPU_TIMING);

          expectedOnMyMachine =
              usesAllCPUCores
                  ? expectedOnMyMachine * 8 / JobSchedulerImpl.CORES_COUNT
                  : expectedOnMyMachine;
        }
        if (adjustForIO) {
          expectedOnMyMachine =
              adjust(expectedOnMyMachine, Timings.IO_TIMING, Timings.ETALON_IO_TIMING);
        }

        // Allow 10% more in case of test machine is busy.
        String logMessage = message;
        if (duration > expectedOnMyMachine) {
          int percentage = (int) (100.0 * (duration - expectedOnMyMachine) / expectedOnMyMachine);
          logMessage += ": " + percentage + "% longer";
        }
        logMessage +=
            ". Expected: "
                + formatTime(expectedOnMyMachine)
                + ". Actual: "
                + formatTime(duration)
                + "."
                + Timings.getStatistics();
        final double acceptableChangeFactor = 1.1;
        if (duration < expectedOnMyMachine) {
          int percentage = (int) (100.0 * (expectedOnMyMachine - duration) / expectedOnMyMachine);
          logMessage = percentage + "% faster. " + logMessage;

          TeamCityLogger.info(logMessage);
          System.out.println("SUCCESS: " + logMessage);
        } else if (duration < expectedOnMyMachine * acceptableChangeFactor) {
          TeamCityLogger.warning(logMessage, null);
          System.out.println("WARNING: " + logMessage);
        } else {
          // try one more time
          if (attempts == 0) {
            // try {
            //  Object result =
            // Class.forName("com.intellij.util.ProfilingUtil").getMethod("captureCPUSnapshot").invoke(null);
            //  System.err.println("CPU snapshot captured in '"+result+"'");
            // }
            // catch (Exception e) {
            // }

            throw new AssertionFailedError(logMessage);
          }
          System.gc();
          System.gc();
          System.gc();
          String s = "Another epic fail (remaining attempts: " + attempts + "): " + logMessage;
          TeamCityLogger.warning(s, null);
          System.err.println(s);
          // if (attempts == 1) {
          //  try {
          //
          // Class.forName("com.intellij.util.ProfilingUtil").getMethod("startCPUProfiling").invoke(null);
          //  }
          //  catch (Exception e) {
          //  }
          // }
          continue;
        }
        break;
      }
    }

    private static String formatTime(long millis) {
      String hint = "";
      DecimalFormat format = new DecimalFormat("#.0", DecimalFormatSymbols.getInstance(Locale.US));
      if (millis >= 60 * 1000) hint = format.format(millis / 60 / 1000.f) + "m";
      if (millis >= 1000)
        hint += (hint.isEmpty() ? "" : " ") + format.format(millis / 1000.f) + "s";
      String result = millis + "ms";
      if (!hint.isEmpty()) {
        result = result + " (" + hint + ")";
      }
      return result;
    }

    private static int adjust(int expectedOnMyMachine, long thisTiming, long ethanolTiming) {
      // most of our algorithms are quadratic. sad but true.
      double speed = 1.0 * thisTiming / ethanolTiming;
      double delta = speed < 1 ? 0.9 + Math.pow(speed - 0.7, 2) : 0.45 + Math.pow(speed - 0.25, 2);
      expectedOnMyMachine *= delta;
      return expectedOnMyMachine;
    }
  }

  public static void assertTiming(
      String message, long expected, @NotNull Runnable actionToMeasure) {
    assertTiming(message, expected, 4, actionToMeasure);
  }

  public static long measure(@NotNull Runnable actionToMeasure) {
    long start = System.currentTimeMillis();
    actionToMeasure.run();
    long finish = System.currentTimeMillis();
    return finish - start;
  }

  public static void assertTiming(
      String message, long expected, int attempts, @NotNull Runnable actionToMeasure) {
    while (true) {
      attempts--;
      long duration = measure(actionToMeasure);
      try {
        assertTiming(message, expected, duration);
        break;
      } catch (AssertionFailedError e) {
        if (attempts == 0) throw e;
        System.gc();
        System.gc();
        System.gc();
        String s = "Another epic fail (remaining attempts: " + attempts + "): " + e.getMessage();
        TeamCityLogger.warning(s, null);
        System.err.println(s);
      }
    }
  }

  private static HashMap<String, VirtualFile> buildNameToFileMap(
      VirtualFile[] files, @Nullable VirtualFileFilter filter) {
    HashMap<String, VirtualFile> map = new HashMap<String, VirtualFile>();
    for (VirtualFile file : files) {
      if (filter != null && !filter.accept(file)) continue;
      map.put(file.getName(), file);
    }
    return map;
  }

  public static void assertDirectoriesEqual(VirtualFile dirAfter, VirtualFile dirBefore)
      throws IOException {
    assertDirectoriesEqual(dirAfter, dirBefore, null);
  }

  @SuppressWarnings("UnsafeVfsRecursion")
  public static void assertDirectoriesEqual(
      VirtualFile dirAfter, VirtualFile dirBefore, @Nullable VirtualFileFilter fileFilter)
      throws IOException {
    FileDocumentManager.getInstance().saveAllDocuments();

    VirtualFile[] childrenAfter = dirAfter.getChildren();

    if (dirAfter.isInLocalFileSystem()
        && dirAfter.getFileSystem() != TempFileSystem.getInstance()) {
      File[] ioAfter = new File(dirAfter.getPath()).listFiles();
      shallowCompare(childrenAfter, ioAfter);
    }

    VirtualFile[] childrenBefore = dirBefore.getChildren();
    if (dirBefore.isInLocalFileSystem()
        && dirBefore.getFileSystem() != TempFileSystem.getInstance()) {
      File[] ioBefore = new File(dirBefore.getPath()).listFiles();
      shallowCompare(childrenBefore, ioBefore);
    }

    HashMap<String, VirtualFile> mapAfter = buildNameToFileMap(childrenAfter, fileFilter);
    HashMap<String, VirtualFile> mapBefore = buildNameToFileMap(childrenBefore, fileFilter);

    Set<String> keySetAfter = mapAfter.keySet();
    Set<String> keySetBefore = mapBefore.keySet();
    assertEquals(dirAfter.getPath(), keySetAfter, keySetBefore);

    for (String name : keySetAfter) {
      VirtualFile fileAfter = mapAfter.get(name);
      VirtualFile fileBefore = mapBefore.get(name);
      if (fileAfter.isDirectory()) {
        assertDirectoriesEqual(fileAfter, fileBefore, fileFilter);
      } else {
        assertFilesEqual(fileAfter, fileBefore);
      }
    }
  }

  private static void shallowCompare(VirtualFile[] vfs, @Nullable File[] io) {
    List<String> vfsPaths = new ArrayList<String>();
    for (VirtualFile file : vfs) {
      vfsPaths.add(file.getPath());
    }

    List<String> ioPaths = new ArrayList<String>();
    if (io != null) {
      for (File file : io) {
        ioPaths.add(file.getPath().replace(File.separatorChar, '/'));
      }
    }

    assertEquals(sortAndJoin(vfsPaths), sortAndJoin(ioPaths));
  }

  private static String sortAndJoin(List<String> strings) {
    Collections.sort(strings);
    StringBuilder buf = new StringBuilder();
    for (String string : strings) {
      buf.append(string);
      buf.append('\n');
    }
    return buf.toString();
  }

  public static void assertFilesEqual(VirtualFile fileAfter, VirtualFile fileBefore)
      throws IOException {
    try {
      assertJarFilesEqual(
          VfsUtilCore.virtualToIoFile(fileAfter), VfsUtilCore.virtualToIoFile(fileBefore));
    } catch (IOException e) {
      FileDocumentManager manager = FileDocumentManager.getInstance();

      Document docBefore = manager.getDocument(fileBefore);
      boolean canLoadBeforeText =
          !fileBefore.getFileType().isBinary() || fileBefore.getFileType() == FileTypes.UNKNOWN;
      String textB =
          docBefore != null
              ? docBefore.getText()
              : !canLoadBeforeText
                  ? null
                  : LoadTextUtil.getTextByBinaryPresentation(
                          fileBefore.contentsToByteArray(false), fileBefore)
                      .toString();

      Document docAfter = manager.getDocument(fileAfter);
      boolean canLoadAfterText =
          !fileBefore.getFileType().isBinary() || fileBefore.getFileType() == FileTypes.UNKNOWN;
      String textA =
          docAfter != null
              ? docAfter.getText()
              : !canLoadAfterText
                  ? null
                  : LoadTextUtil.getTextByBinaryPresentation(
                          fileAfter.contentsToByteArray(false), fileAfter)
                      .toString();

      if (textA != null && textB != null) {
        assertEquals(fileAfter.getPath(), textA, textB);
      } else {
        Assert.assertArrayEquals(
            fileAfter.getPath(), fileAfter.contentsToByteArray(), fileBefore.contentsToByteArray());
      }
    }
  }

  public static void assertJarFilesEqual(File file1, File file2) throws IOException {
    final File tempDirectory1;
    final File tempDirectory2;

    final JarFile jarFile1 = new JarFile(file1);
    try {
      final JarFile jarFile2 = new JarFile(file2);
      try {
        tempDirectory1 = PlatformTestCase.createTempDir("tmp1");
        tempDirectory2 = PlatformTestCase.createTempDir("tmp2");
        ZipUtil.extract(jarFile1, tempDirectory1, null);
        ZipUtil.extract(jarFile2, tempDirectory2, null);
      } finally {
        jarFile2.close();
      }
    } finally {
      jarFile1.close();
    }

    final VirtualFile dirAfter =
        LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory1);
    assertNotNull(tempDirectory1.toString(), dirAfter);
    final VirtualFile dirBefore =
        LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory2);
    assertNotNull(tempDirectory2.toString(), dirBefore);
    ApplicationManager.getApplication()
        .runWriteAction(
            new Runnable() {
              @Override
              public void run() {
                dirAfter.refresh(false, true);
                dirBefore.refresh(false, true);
              }
            });
    assertDirectoriesEqual(dirAfter, dirBefore);
  }

  public static void assertElementsEqual(final Element expected, final Element actual)
      throws IOException {
    if (!JDOMUtil.areElementsEqual(expected, actual)) {
      junit.framework.Assert.assertEquals(printElement(expected), printElement(actual));
    }
  }

  public static String printElement(final Element element) throws IOException {
    final StringWriter writer = new StringWriter();
    JDOMUtil.writeElement(element, writer, "\n");
    return writer.getBuffer().toString();
  }

  public static String getCommunityPath() {
    final String homePath = PathManager.getHomePath();
    if (new File(homePath, "community").exists()) {
      return homePath + File.separatorChar + "community";
    }
    return homePath;
  }

  public static Comparator<AbstractTreeNode> createComparator(final Queryable.PrintInfo printInfo) {
    return new Comparator<AbstractTreeNode>() {
      @Override
      public int compare(final AbstractTreeNode o1, final AbstractTreeNode o2) {
        String displayText1 = o1.toTestString(printInfo);
        String displayText2 = o2.toTestString(printInfo);
        return Comparing.compare(displayText1, displayText2);
      }
    };
  }

  @NotNull
  public static <T> T notNull(@Nullable T t) {
    assertNotNull(t);
    return t;
  }

  @NotNull
  public static String loadFileText(@NotNull String fileName) throws IOException {
    return StringUtil.convertLineSeparators(FileUtil.loadFile(new File(fileName)));
  }

  public static void tryGcSoftlyReachableObjects() {
    List<Object> list = ContainerUtil.newArrayList();
    for (int i = 0; i < 100; i++) {
      list.add(new SoftReference<byte[]>(new byte[(int) Runtime.getRuntime().freeMemory() / 2]));
    }
  }

  public static void withEncoding(@NotNull String encoding, @NotNull final Runnable r) {
    withEncoding(
        encoding,
        new ThrowableRunnable() {
          @Override
          public void run() throws Throwable {
            r.run();
          }
        });
  }

  public static void withEncoding(@NotNull String encoding, @NotNull ThrowableRunnable r) {
    Charset oldCharset = Charset.defaultCharset();
    try {
      try {
        patchSystemFileEncoding(encoding);
        r.run();
      } finally {
        patchSystemFileEncoding(oldCharset.name());
      }
    } catch (Throwable t) {
      throw new RuntimeException(t);
    }
  }

  private static void patchSystemFileEncoding(String encoding)
      throws NoSuchFieldException, IllegalAccessException {
    Field charset = Charset.class.getDeclaredField("defaultCharset");
    charset.setAccessible(true);
    charset.set(Charset.class, null);
    System.setProperty("file.encoding", encoding);
  }
}
 public static long measure(@NotNull Runnable actionToMeasure) {
   long start = System.currentTimeMillis();
   actionToMeasure.run();
   long finish = System.currentTimeMillis();
   return finish - start;
 }
    public void assertTiming() {
      assert expectedMs != 0 : "Must call .expect() before run test";
      if (COVERAGE_ENABLED_BUILD) return;

      while (true) {
        attempts--;
        long start;
        try {
          if (setup != null) setup.run();
          start = System.currentTimeMillis();
          test.run();
        } catch (Throwable throwable) {
          throw new RuntimeException(throwable);
        }
        long finish = System.currentTimeMillis();
        long duration = finish - start;

        int expectedOnMyMachine = expectedMs;
        if (adjustForCPU) {
          expectedOnMyMachine =
              adjust(expectedOnMyMachine, Timings.CPU_TIMING, Timings.ETALON_CPU_TIMING);

          expectedOnMyMachine =
              usesAllCPUCores
                  ? expectedOnMyMachine * 8 / JobSchedulerImpl.CORES_COUNT
                  : expectedOnMyMachine;
        }
        if (adjustForIO) {
          expectedOnMyMachine =
              adjust(expectedOnMyMachine, Timings.IO_TIMING, Timings.ETALON_IO_TIMING);
        }

        // Allow 10% more in case of test machine is busy.
        String logMessage = message;
        if (duration > expectedOnMyMachine) {
          int percentage = (int) (100.0 * (duration - expectedOnMyMachine) / expectedOnMyMachine);
          logMessage += ": " + percentage + "% longer";
        }
        logMessage +=
            ". Expected: "
                + formatTime(expectedOnMyMachine)
                + ". Actual: "
                + formatTime(duration)
                + "."
                + Timings.getStatistics();
        final double acceptableChangeFactor = 1.1;
        if (duration < expectedOnMyMachine) {
          int percentage = (int) (100.0 * (expectedOnMyMachine - duration) / expectedOnMyMachine);
          logMessage = percentage + "% faster. " + logMessage;

          TeamCityLogger.info(logMessage);
          System.out.println("SUCCESS: " + logMessage);
        } else if (duration < expectedOnMyMachine * acceptableChangeFactor) {
          TeamCityLogger.warning(logMessage, null);
          System.out.println("WARNING: " + logMessage);
        } else {
          // try one more time
          if (attempts == 0) {
            // try {
            //  Object result =
            // Class.forName("com.intellij.util.ProfilingUtil").getMethod("captureCPUSnapshot").invoke(null);
            //  System.err.println("CPU snapshot captured in '"+result+"'");
            // }
            // catch (Exception e) {
            // }

            throw new AssertionFailedError(logMessage);
          }
          System.gc();
          System.gc();
          System.gc();
          String s = "Another epic fail (remaining attempts: " + attempts + "): " + logMessage;
          TeamCityLogger.warning(s, null);
          System.err.println(s);
          // if (attempts == 1) {
          //  try {
          //
          // Class.forName("com.intellij.util.ProfilingUtil").getMethod("startCPUProfiling").invoke(null);
          //  }
          //  catch (Exception e) {
          //  }
          // }
          continue;
        }
        break;
      }
    }