Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/java-runtime/src/FormPreviewFrame.java b/java/java-runtime/src/FormPreviewFrame.java
new file mode 100644
index 0000000..939c468
--- /dev/null
+++ b/java/java-runtime/src/FormPreviewFrame.java
@@ -0,0 +1,113 @@
+
+/*
+ * Copyright 2000-2009 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.
+ */
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.text.MessageFormat;
+import java.util.ResourceBundle;
+
+public class FormPreviewFrame {
+  private JComponent myComponent;
+  private static final ResourceBundle ourBundle = ResourceBundle.getBundle("RuntimeBundle");
+
+  // Note: this class should not be obfuscated
+
+  public static void main(String[] args) {
+    FormPreviewFrame f = new FormPreviewFrame();
+
+    JFrame frame = new JFrame(ourBundle.getString("form.preview.title"));
+    frame.setContentPane(f.myComponent);
+    frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
+
+    // Add menu bar
+    final JMenuBar menuBar = new JMenuBar();
+    frame.setJMenuBar(menuBar);
+
+    final JMenu menuFile = new JMenu(ourBundle.getString("form.menu.preview"));
+    menuFile.setMnemonic(ourBundle.getString("form.menu.preview.mnemonic").charAt(0));
+    menuFile.add(new JMenuItem(new MyPackAction(frame)));
+    menuFile.add(new JMenuItem(new MyExitAction()));
+    menuBar.add(menuFile);
+
+    final JMenu viewMenu = new JMenu(ourBundle.getString("form.menu.laf"));
+    viewMenu.setMnemonic(ourBundle.getString("form.menu.laf.mnemonic").charAt(0));
+    menuBar.add(viewMenu);
+
+    final UIManager.LookAndFeelInfo[] lafs = UIManager.getInstalledLookAndFeels();
+    for(int i = 0; i < lafs.length; i++){
+      viewMenu.add(new MySetLafAction(frame, lafs[i]));
+    }
+
+    frame.pack();
+    Dimension screenSize = Toolkit.getDefaultToolkit().getScreenSize();
+    frame.setLocation((screenSize.width - frame.getWidth())/2, (screenSize.height - frame.getHeight())/2);
+    frame.setVisible(true);
+  }
+
+  private static final class MyExitAction extends AbstractAction{
+    public MyExitAction() {
+      super(ourBundle.getString("form.menu.file.exit"));
+    }
+
+    public void actionPerformed(final ActionEvent e) {
+      System.exit(0);
+    }
+  }
+
+  private static final class MyPackAction extends AbstractAction{
+    private final JFrame myFrame;
+
+    public MyPackAction(final JFrame frame) {
+      super(ourBundle.getString("form.menu.view.pack"));
+      myFrame = frame;
+    }
+
+    public void actionPerformed(final ActionEvent e) {
+      myFrame.pack();
+    }
+  }
+
+  private static final class MySetLafAction extends AbstractAction{
+    private final JFrame myFrame;
+    private final UIManager.LookAndFeelInfo myInfo;
+
+    public MySetLafAction(final JFrame frame, final UIManager.LookAndFeelInfo info) {
+      super(info.getName());
+      myFrame = frame;
+      myInfo = info;
+    }
+
+    public void actionPerformed(ActionEvent e) {
+      try{
+        UIManager.setLookAndFeel(myInfo.getClassName());
+        SwingUtilities.updateComponentTreeUI(myFrame);
+        Dimension prefSize = myFrame.getPreferredSize();
+        if(prefSize.width > myFrame.getWidth() || prefSize.height > myFrame.getHeight()){
+          myFrame.pack();
+        }
+      }
+      catch(Exception exc){
+        JOptionPane.showMessageDialog(
+          myFrame,
+          MessageFormat.format(ourBundle.getString("error.cannot.change.look.feel"), new Object[] {exc.getMessage()}),
+          ourBundle.getString("error.title"),
+          JOptionPane.ERROR_MESSAGE
+        );
+      }
+    }
+  }
+}
diff --git a/java/java-runtime/src/RuntimeBundle.properties b/java/java-runtime/src/RuntimeBundle.properties
new file mode 100644
index 0000000..337fa12
--- /dev/null
+++ b/java/java-runtime/src/RuntimeBundle.properties
@@ -0,0 +1,17 @@
+form.preview.title=Form Preview
+form.menu.preview=Preview
+form.menu.preview.mnemonic=P
+form.menu.file.exit=Exit
+form.menu.laf=Look and Feel
+form.menu.laf.mnemonic=L
+form.menu.view.pack=Pack
+error.cannot.change.look.feel=Cannot change LookAndFeel.\nReason: {0}
+error.title=Error
+junit.runner.error=Error: {0}
+junit.class.not.found=Class not found: "{0}"
+junit.cannot.instantiate.tests=Cannot instantiate test(s): {0}
+junit.class.not.derived={0} is not derived from TestCase. Do not provide method name.
+junit.suite.must.be.static=''{0}.suite()'' method must be static
+junit.failed.to.invoke.suite=Failed to invoke suite(): {0}
+junit.method.not.found=Method ''{0}'' not found
+tests.found.in.package={0} test {0, choice, 1#class|2#classes} found in package ''{1}''
\ No newline at end of file
diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/AntMain2.java b/java/java-runtime/src/com/intellij/rt/ant/execution/AntMain2.java
new file mode 100644
index 0000000..8b45dca
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/ant/execution/AntMain2.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.rt.ant.execution;
+
+import java.lang.reflect.InvocationTargetException;
+
+public final class AntMain2 {
+
+  public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, InvocationTargetException {
+    IdeaAntLogger2.guardStreams();
+
+    // first try to use the new way of launching ant
+    try {
+      final Class antLauncher = Class.forName("org.apache.tools.ant.launch.Launcher");
+      //noinspection HardCodedStringLiteral
+      antLauncher.getMethod("main", new Class[]{args.getClass()}).invoke(null, new Object[]{args});
+      return;
+    }
+    catch (ClassNotFoundException e) {
+      // ignore and try older variant
+    }
+
+    final Class antMain = Class.forName("org.apache.tools.ant.Main");
+    //noinspection HardCodedStringLiteral
+    antMain.getMethod("main", new Class[]{args.getClass()}).invoke(null, new Object[]{args});
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java
new file mode 100644
index 0000000..f30025e
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaAntLogger2.java
@@ -0,0 +1,198 @@
+/*
+ * Copyright 2000-2009 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.rt.ant.execution;
+
+import com.intellij.rt.execution.junit.segments.PacketWriter;
+import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
+import org.apache.tools.ant.BuildEvent;
+import org.apache.tools.ant.DefaultLogger;
+import org.apache.tools.ant.Project;
+
+import java.io.PrintStream;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+
+public final class IdeaAntLogger2 extends DefaultLogger {
+  static SegmentedOutputStream ourErr;
+  public static final char MESSAGE_CONTENT = 'M';
+  public static final char EXCEPTION_CONTENT = 'X';
+  public static final char INPUT_REQUEST = 'I';
+  public static final char BUILD_END = 'b';
+  public static final char BUILD = 'B';
+  public static final char TARGET = 'G';
+  public static final char TARGET_END = 'g';
+  public static final char TASK = 'T';
+  public static final char TASK_END = 't';
+  public static final char MESSAGE = 'M';
+  public static final char ERROR = 'E';
+  public static final char EXCEPTION = 'X';
+  public static final char EXCEPTION_LINE_SEPARATOR = 0;
+
+  /**
+   * @noinspection HardCodedStringLiteral
+   */
+  public static final String OUTPUT_PREFIX = "IDEA_ANT_INTEGRATION";
+
+  private final Priority myMessagePriority = new MessagePriority();
+  private final Priority myTargetPriority = new StatePriority(Project.MSG_INFO);
+  private final Priority myTaskPriority = new StatePriority(Project.MSG_INFO);
+  private final Priority myAlwaysSend = new Priority() {
+    public void setPriority(int level) {}
+
+    protected boolean shouldSend(int priority) {
+      return true;
+    }
+  };
+
+  public IdeaAntLogger2() {
+    guardStreams();
+  }
+
+  public synchronized void setMessageOutputLevel(int level) {
+    super.setMessageOutputLevel(level);
+    myMessagePriority.setPriority(level);
+    myTargetPriority.setPriority(level);
+    myTaskPriority.setPriority(level);
+    myAlwaysSend.setPriority(level);
+  }
+
+  public synchronized void buildStarted(BuildEvent event) {
+    myAlwaysSend.sendMessage(BUILD, event.getPriority(), "");
+  }
+
+  public synchronized void buildFinished(BuildEvent event) {
+    myAlwaysSend.sendMessage(BUILD_END, event.getPriority(), event.getException());
+  }
+
+  public synchronized void targetStarted(BuildEvent event) {
+    myTargetPriority.sendMessage(TARGET, event.getPriority(), event.getTarget().getName());
+  }
+
+  public synchronized void targetFinished(BuildEvent event) {
+    sendException(event);
+    myTargetPriority.sendMessage(TARGET_END, event.getPriority(), event.getException());
+  }
+
+  public synchronized void taskStarted(BuildEvent event) {
+    myTaskPriority.sendMessage(TASK, event.getPriority(), event.getTask().getTaskName());
+  }
+
+  public synchronized void taskFinished(BuildEvent event) {
+    sendException(event);
+    myTaskPriority.sendMessage(TASK_END, event.getPriority(), event.getException());
+  }
+
+  public synchronized void messageLogged(BuildEvent event) {
+    if (sendException(event)) return;
+    int priority = event.getPriority();
+    String message = event.getMessage();
+    if (priority == Project.MSG_ERR)
+      myMessagePriority.sendMessage(ERROR, priority, message);
+    else
+      myMessagePriority.sendMessage(MESSAGE, priority, message);
+  }
+
+  private boolean sendException(BuildEvent event) {
+    Throwable exception = event.getException();
+    if (exception != null) {
+      myAlwaysSend.sendMessage(EXCEPTION, event.getPriority(), exception);
+      return true;
+    }
+    return false;
+  }
+
+  public static void guardStreams() {
+    if (ourErr != null) {
+      return;
+    }
+    PrintStream err = System.err;
+    ourErr = new SegmentedOutputStream(err);
+    System.setErr(new PrintStream(ourErr));
+    ourErr.sendStart();
+  }
+
+  private void send(PacketWriter packet) {
+    packet.sendThrough(ourErr);
+  }
+
+  private PacketWriter createPacket(char id, int priority) {
+    PacketWriter packet = PacketFactory.ourInstance.createPacket(id);
+    packet.appendLong(priority);
+    return packet;
+  }
+
+  private abstract class Priority {
+    protected void peformSendMessage(char id, int priority, String text) {
+      PacketWriter packet = createPacket(id, priority);
+      packet.appendChar(MESSAGE_CONTENT);
+      packet.appendLimitedString(text);
+      send(packet);
+    }
+
+    protected void peformSendMessage(char id, int priority, Throwable throwable) {
+      if (throwable != null) {
+        PacketWriter packet = createPacket(id, priority);
+        StringWriter stackTrace = new StringWriter();
+        throwable.printStackTrace(new PrintWriter(stackTrace));
+        packet.appendChar(EXCEPTION_CONTENT);
+        packet.appendLimitedString(stackTrace.toString());
+        send(packet);
+      } else {
+        peformSendMessage(id, priority, "");
+      }
+    }
+
+    public void sendMessage(char id, int priority, String text) {
+      if (shouldSend(priority)) peformSendMessage(id, priority, text);
+    }
+
+    public void sendMessage(char id, int priority, Throwable throwable) {
+      if (shouldSend(priority)) peformSendMessage(id, priority, throwable);
+    }
+
+    public abstract void setPriority(int level);
+    protected abstract boolean shouldSend(int priority);
+  }
+
+  private class MessagePriority extends Priority {
+    private int myPriority = Project.MSG_ERR;
+
+    public void setPriority(int level) {
+      myPriority = level;
+    }
+
+    protected boolean shouldSend(int priority) {
+      return priority <= myPriority;
+    }
+  }
+
+  private class StatePriority extends Priority {
+    private boolean myEnabled = true;
+    private final int myMinLevel;
+
+    public StatePriority(int minLevel) {
+      myMinLevel = minLevel;
+    }
+
+    public void setPriority(int level) {
+      myEnabled = myMinLevel <= level;
+    }
+
+    protected boolean shouldSend(int priority) {
+      return myEnabled;
+    }
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java
new file mode 100644
index 0000000..3a1120a
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/ant/execution/IdeaInputHandler.java
@@ -0,0 +1,81 @@
+/*
+ * Copyright 2000-2009 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.rt.ant.execution;
+
+import com.intellij.rt.execution.junit.segments.PacketWriter;
+import com.intellij.rt.execution.junit.segments.SegmentedOutputStream;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.input.InputHandler;
+import org.apache.tools.ant.input.InputRequest;
+import org.apache.tools.ant.input.MultipleChoiceInputRequest;
+
+import java.io.IOException;
+import java.util.Vector;
+
+/**
+ * @author dyoma
+ */
+public class IdeaInputHandler implements InputHandler {
+  public void handleInput(InputRequest request) throws BuildException {
+    final String prompt = request.getPrompt();
+    if (prompt == null) {
+      throw new BuildException("Prompt is null");
+    }
+    final SegmentedOutputStream err = IdeaAntLogger2.ourErr;
+    if (err == null) {
+      throw new BuildException("Selected InputHandler should be used by Intellij IDEA");
+    }
+    final PacketWriter packet = PacketFactory.ourInstance.createPacket(IdeaAntLogger2.INPUT_REQUEST);
+    packet.appendLimitedString(prompt);
+    if (request instanceof MultipleChoiceInputRequest) {
+      Vector choices = ((MultipleChoiceInputRequest)request).getChoices();
+      if (choices != null && choices.size() > 0) {
+        int count = choices.size();
+        packet.appendLong(count);
+        for (int i = 0; i < count; i++) {
+          packet.appendLimitedString((String)choices.elementAt(i));
+        }
+      }
+      else {
+        packet.appendLong(0);
+      }
+    }
+    else {
+      packet.appendLong(0);
+    }
+    packet.sendThrough(err);
+    try {
+      final byte[] replayLength = readBytes(4);
+      final int length = ((int)replayLength[0] << 24) | ((int)replayLength[1] << 16) | ((int)replayLength[2] << 8) | replayLength[3];
+      final byte[] replay = readBytes(length);
+      final String input = new String(replay);
+      request.setInput(input);
+      if (!request.isInputValid()) {
+        throw new BuildException("Invalid input: " + input);
+      }
+    }
+    catch (IOException e) {
+      throw new BuildException(e);
+    }
+  }
+
+  private byte[] readBytes(int count) throws IOException {
+    byte[] replayLength = new byte[count];
+    int read = System.in.read(replayLength);
+    if (read != count) throw new IOException("End of input stream");
+    return replayLength;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/ant/execution/PacketFactory.java b/java/java-runtime/src/com/intellij/rt/ant/execution/PacketFactory.java
new file mode 100644
index 0000000..2768b63
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/ant/execution/PacketFactory.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 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.rt.ant.execution;
+
+import com.intellij.rt.execution.junit.segments.PacketWriter;
+
+/**
+ * @author dyoma
+ */
+class PacketFactory {
+  private int myLastMessageId = -1;
+  public static final PacketFactory ourInstance = new PacketFactory();
+
+  public synchronized PacketWriter createPacket(char id) {
+    PacketWriter writer = new PacketWriter();
+    myLastMessageId++;
+    writer.appendLong(myLastMessageId);
+    writer.appendChar(id);
+    return writer;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/compiler/JavacResourcesReader.java b/java/java-runtime/src/com/intellij/rt/compiler/JavacResourcesReader.java
new file mode 100644
index 0000000..0a1a3d4
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/compiler/JavacResourcesReader.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2000-2009 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.rt.compiler;
+
+import java.text.MessageFormat;
+import java.util.MissingResourceException;
+import java.util.ResourceBundle;
+
+/**
+  * MUST BE COMPILED WITH JDK 1.1 IN ORDER TO SUPPORT JAVAC LAUNCHING FOR ALL JDKs
+  * @author Eugene Zhuravlev
+  *         Date: Oct 10, 2005
+  */
+public class JavacResourcesReader {
+  public static final String MSG_PATTERNS_START = "__patterns_start";
+  public static final String MSG_PATTERNS_END = "__patterns_end";
+  public static final String MSG_PARSING_STARTED = "MSG_PARSING_STARTED";
+  public static final String MSG_PARSING_COMPLETED = "MSG_PARSING_COMPLETED";
+  public static final String MSG_LOADING = "MSG_LOADING";
+  public static final String MSG_CHECKING = "MSG_CHECKING";
+  public static final String MSG_WROTE = "MSG_WROTE";
+  public static final String MSG_WARNING = "MSG_WARNING";
+  public static final String MSG_NOTE = "MSG_NOTE";
+  public static final String MSG_STATISTICS = "MSG_STATISTICS";
+  public static final String MSG_IGNORED = "MSG_IGNORED";
+
+  private static final String[] BUNDLE_NAMES = new String[] {
+    "com.sun.tools.javac.resources.compiler",    // v1.5
+    "com.sun.tools.javac.v8.resources.compiler", // v1.3-1.4
+    "sun.tools.javac.resources.javac"            // v1.1-1.2
+  };
+
+  private static final BundleKey[] MSG_NAME_KEY_PAIRS = new BundleKey[] {
+    new BundleKey(MSG_PARSING_STARTED, "compiler.misc.verbose.parsing.started"),
+    new BundleKey(MSG_PARSING_COMPLETED, "compiler.misc.verbose.parsing.done"),
+    new BundleKey(MSG_PARSING_COMPLETED, "benv.parsed_in"), // jdk 1.1-1.2
+    new BundleKey(MSG_LOADING, "compiler.misc.verbose.loading"),
+    new BundleKey(MSG_LOADING, "benv.loaded_in"), // jdk 1.1-1.2
+    new BundleKey(MSG_CHECKING, "compiler.misc.verbose.checking.attribution"),
+    new BundleKey(MSG_WROTE,"compiler.misc.verbose.wrote.file"),
+    new BundleKey(MSG_WROTE,"main.wrote"), // jdk 1.1-1.2
+    new BundleKey(MSG_WARNING,"compiler.warn.warning"),
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.deprecated.filename"}),  // jdk 1.5
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.deprecated.plural"}),  // jdk 1.5
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.deprecated.recompile"}),  // jdk 1.5
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.unchecked.filename"}),  // jdk 1.5
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.unchecked.plural"}),  // jdk 1.5
+    new BundleKey(MSG_NOTE,new String[] {"compiler.note.note", "compiler.note.unchecked.recompile"}),  // jdk 1.5
+    new BundleKey(MSG_STATISTICS,"compiler.misc.count.error"),
+    new BundleKey(MSG_STATISTICS,"compiler.misc.count.error.plural"),
+    new BundleKey(MSG_STATISTICS,"compiler.misc.count.warn"),
+    new BundleKey(MSG_STATISTICS,"compiler.misc.count.warn.plural"),
+    new BundleKey(MSG_STATISTICS,"main.errors"), //jdk 1.1 - 1.2
+    new BundleKey(MSG_STATISTICS,"main.warnings"), //jdk 1.1 - 1.2
+    new BundleKey(MSG_STATISTICS,"main.1error"), //jdk 1.1 - 1.2
+    new BundleKey(MSG_STATISTICS,"main.1warning"), //jdk 1.1 - 1.2
+    new IgnoredWarningBundleKey("compiler.warn.dir.path.element.not.found"), //jdk 1.5
+    new IgnoredWarningBundleKey("compiler.warn.path.element.not.found"), //jdk 1.5
+  };
+
+  public static final String CATEGORY_VALUE_DIVIDER = "=";
+
+  public static void main(String[] args) {
+    dumpPatterns();
+  }
+
+  // for debug purposes
+  /*
+  public static void printPatterns() {
+    final ResourceBundle messagesBundle = getMessagesBundle();
+    if (messagesBundle == null) {
+      System.out.println("No bundles found");
+      return;
+    }
+    final Enumeration keys = messagesBundle.getKeys();
+    while (keys.hasMoreElements()) {
+      final Object key = keys.nextElement();
+      System.out.println(key + "->" + messagesBundle.getObject((String)key));
+    }
+  }
+  */
+  
+  public static boolean dumpPatterns() {
+    final ResourceBundle messagesBundle = getMessagesBundle();
+    if (messagesBundle == null) {
+      return false;
+    }
+    System.err.println(MSG_PATTERNS_START);
+    for (int idx = 0; idx < MSG_NAME_KEY_PAIRS.length; idx++) {
+      BundleKey bundleKey = MSG_NAME_KEY_PAIRS[idx];
+      try {
+        System.err.println(bundleKey.category + CATEGORY_VALUE_DIVIDER + bundleKey.getCategoryValue(messagesBundle));
+      }
+      catch (MissingResourceException ignored) {
+      }
+    }
+    System.err.println(MSG_PATTERNS_END);
+    return true;
+  }
+
+  private static ResourceBundle getMessagesBundle() {
+    for (int i = 0; i < BUNDLE_NAMES.length; i++) {
+      try {
+        return ResourceBundle.getBundle(BUNDLE_NAMES[i]);
+      }
+      catch (MissingResourceException ignored) {
+        continue;
+      }
+    }
+    return null;
+  }
+
+  private static class BundleKey {
+    public final String category;
+    public final String[] keys;
+
+    public BundleKey(final String category, final String key) {
+      this(category, new String[] {key});
+    }
+
+    public BundleKey(final String category, final String[] composite) {
+      this.category = category;
+      this.keys = composite;
+    }
+
+    public String getCategoryValue(ResourceBundle messagesBundle) {
+      if (keys.length == 1) {
+        return messagesBundle.getString(keys[0]);
+      }
+      final StringBuffer buf = new StringBuffer();
+      for (int idx = 0; idx < keys.length; idx++) {
+        buf.append(messagesBundle.getString(keys[idx]));
+      }
+      return buf.toString();
+    }
+  }
+
+  private static class IgnoredWarningBundleKey extends BundleKey {
+    public IgnoredWarningBundleKey(final String messageKey) {
+      super(JavacResourcesReader.MSG_IGNORED, new String[]{"compiler.warn.warning", messageKey});
+    }
+
+    public String getCategoryValue(ResourceBundle messagesBundle) {
+      return messagesBundle.getString(keys[0]) + MessageFormat.format(messagesBundle.getString(keys[1]), new Object[] {""});
+    }
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/compiler/JavacRunner.java b/java/java-runtime/src/com/intellij/rt/compiler/JavacRunner.java
new file mode 100644
index 0000000..a454146
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/compiler/JavacRunner.java
@@ -0,0 +1,132 @@
+/*
+ * Copyright 2000-2009 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.rt.compiler;
+
+import java.io.*;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.util.Vector;
+
+/**
+ * MUST BE COMPILED WITH JDK 1.1 IN ORDER TO SUPPORT JAVAC LAUNCHING FOR ALL JDKs
+ */
+public class JavacRunner {
+
+  /**
+   * @param args - params
+   *  0. jdk version string
+   *  1. javac main class
+   *  2. javac parameters
+   */
+  public static void main(String[] args) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException, ClassNotFoundException, IOException {
+
+    if (!JavacResourcesReader.dumpPatterns()) {
+      return;
+    }
+
+    final String versionString = args[0];
+    final Class aClass = Class.forName(args[1]);
+    //noinspection HardCodedStringLiteral
+    final Method mainMethod = aClass.getMethod("main", new Class[] {String[].class});
+    String[] newArgs;
+    if (versionString.indexOf("1.1") > -1) {
+      // expand the file
+      final Vector arguments = new Vector();
+      boolean isClasspath = false;
+      for (int idx = 3; idx < args.length; idx++) {
+        final String arg = args[idx];
+        if (arg.startsWith("@") && !isClasspath) {
+          String path = arg.substring(1);
+          addFilesToCompile(arguments, path);
+        }
+        else {
+          isClasspath = "-classpath".equals(arg) || "-cp".equals(arg) || "-bootclasspath".equals(arg);
+          arguments.addElement(arg);
+        }
+      }
+      newArgs = new String[arguments.size()];
+      for (int idx = 0; idx < newArgs.length; idx++) {
+        newArgs[idx] = (String)arguments.elementAt(idx);
+      }
+    }
+    else {
+      newArgs = new String[args.length - 2];
+      System.arraycopy(args, 2, newArgs, 0, newArgs.length);
+    }
+    expandClasspath(newArgs);
+    try {
+      mainMethod.invoke(null, new Object[] {newArgs});
+    }
+    catch (Throwable e) {
+      System.err.print(e.getMessage());
+      e.printStackTrace(System.err);
+    }
+  }
+
+  private static void addFilesToCompile(Vector arguments, String path) throws IOException {
+    BufferedReader reader = null;
+    try {
+      reader = new BufferedReader(new FileReader(new File(path)));
+      for (String filePath = reader.readLine(); filePath != null; filePath = reader.readLine()) {
+        arguments.addElement(filePath.replace('/', File.separatorChar));
+      }
+    }
+    finally {
+      if (reader != null) {
+        reader.close();
+      }
+    }
+  }
+
+  private static void expandClasspath(String[] args) throws IOException {
+    for (int idx = 0; idx < args.length; idx++) {
+      final String arg = args[idx];
+      //noinspection HardCodedStringLiteral
+      if ("-classpath".equals(arg) || "-cp".equals(arg) || "-bootclasspath".equals(arg)) {
+        final String cpValue = args[idx + 1];
+        if (cpValue.startsWith("@")) {
+          args[idx + 1] = readClasspath(cpValue.substring(1));
+        }
+      }
+    }
+  }
+
+  public static String readClasspath(String filePath) throws IOException {
+    final DataInputStream in = new DataInputStream(new BufferedInputStream(new FileInputStream(new File(filePath))));
+    try {
+      return readString(in);
+    }
+    finally {
+      in.close();
+    }
+  }
+
+  private static String readString(DataInput stream) throws IOException {
+    int length = stream.readInt();
+    if (length == -1) return null;
+
+    char[] chars = new char[length];
+    byte[] bytes = new byte[length*2];
+    stream.readFully(bytes);
+
+    for (int i = 0, i2 = 0; i < length; i++, i2+=2) {
+      chars[i] = (char)((bytes[i2] << 8) + (bytes[i2 + 1] & 0xFF));
+    }
+
+    return new String(chars);
+  }
+
+}
diff --git a/java/java-runtime/src/com/intellij/rt/debugger/BatchEvaluatorServer.java b/java/java-runtime/src/com/intellij/rt/debugger/BatchEvaluatorServer.java
new file mode 100644
index 0000000..6895f02
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/debugger/BatchEvaluatorServer.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 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.
+ */
+
+/*
+ * @author: Eugene Zhuravlev
+ * Date: Sep 16, 2002
+ * Time: 10:56:58 PM
+ */
+package com.intellij.rt.debugger;
+
+public class BatchEvaluatorServer {
+  Object[] myObjects;
+
+  public Object[] evaluate(Object[] objects) {
+    myObjects = objects;
+    Object[] result = new Object[objects.length];
+    for (int idx = 0; idx < objects.length; idx++) {
+      try {
+        result[idx] = objects[idx].toString();
+      }
+      catch (Throwable e) {
+        result[idx] = e;
+      }
+    }
+    return result;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java
new file mode 100644
index 0000000..b5cfc47
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/CommandLineWrapper.java
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2000-2012 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.rt.execution;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.FileReader;
+import java.io.IOException;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author anna
+ * @since 12-Aug-2008
+ */
+public class CommandLineWrapper {
+  private static final String PREFIX = "-D";
+
+  public static void main(String[] args) throws ClassNotFoundException, NoSuchMethodException, InvocationTargetException,
+                                                IllegalAccessException, IOException, InstantiationException {
+    final List urls = new ArrayList();
+    final File file = new File(args[0]);
+    final BufferedReader reader = new BufferedReader(new FileReader(file));
+    try {
+      while(reader.ready()) {
+        final String fileName = reader.readLine();
+        try {
+          //noinspection Since15
+          urls.add(new File(fileName).toURI().toURL());
+        }
+        catch (NoSuchMethodError e) {
+          //noinspection deprecation
+          urls.add(new File(fileName).toURL());
+        }
+      }
+    }
+    finally {
+      reader.close();
+    }
+    if (!file.delete()) file.deleteOnExit();
+
+    int startArgsIdx = 2;
+    if (args[1].equals("@vm_params")) {
+      startArgsIdx = 4;
+      final File vmParamsFile = new File(args[2]);
+      final BufferedReader vmParamsReader = new BufferedReader(new FileReader(vmParamsFile));
+      try {
+        while (vmParamsReader.ready()) {
+          final String vmParam = vmParamsReader.readLine().trim();
+          final int eqIdx = vmParam.indexOf("=");
+          String vmParamName;
+          String vmParamValue;
+          
+          if (eqIdx > -1 && eqIdx < vmParam.length() - 1) {
+            vmParamName = vmParam.substring(0, eqIdx);
+            vmParamValue = vmParam.substring(eqIdx + 1);
+          } else {
+            vmParamName = vmParam;
+            vmParamValue = "";
+          }
+          vmParamName = vmParamName.trim();
+          if (vmParamName.startsWith(PREFIX)) {
+            vmParamName = vmParamName.substring(PREFIX.length());
+            System.setProperty(vmParamName, vmParamValue);
+          }
+        }
+      }
+      finally {
+        vmParamsReader.close();
+      }
+      if (!vmParamsFile.delete()) vmParamsFile.deleteOnExit();
+    }
+
+    String mainClassName = args[startArgsIdx - 1];
+    String[] mainArgs = new String[args.length - startArgsIdx];
+    System.arraycopy(args, startArgsIdx, mainArgs, 0, mainArgs.length);
+
+    ClassLoader loader = new URLClassLoader((URL[])urls.toArray(new URL[urls.size()]), null);
+    final String classLoader = System.getProperty("java.system.class.loader");
+    if (classLoader != null) {
+      try {
+        loader = (ClassLoader)Class.forName(classLoader).getConstructor(new Class[]{ClassLoader.class}).newInstance(new Object[]{loader});
+      }
+      catch (Exception e) {
+        //leave URL class loader
+      }
+    }
+
+    Class mainClass = loader.loadClass(mainClassName);
+    Thread.currentThread().setContextClassLoader(loader);
+    //noinspection SSBasedInspection
+    Class mainArgType = (new String[0]).getClass();
+    Method main = mainClass.getMethod("main", new Class[]{mainArgType});
+    ensureAccess(main);
+    main.invoke(null, new Object[]{mainArgs});
+  }
+
+   private static void ensureAccess(Object reflectionObject) {
+    // need to call setAccessible here in order to be able to launch package-local classes
+    // calling setAccessible() via reflection because the method is missing from java version 1.1.x
+    final Class aClass = reflectionObject.getClass();
+    try {
+      final Method setAccessibleMethod = aClass.getMethod("setAccessible", new Class[] {boolean.class});
+      setAccessibleMethod.invoke(reflectionObject, new Object[] {Boolean.TRUE});
+    }
+    catch (Exception e) {
+      // the method not found
+    }
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java
new file mode 100644
index 0000000..1319956
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/application/AppMain.java
@@ -0,0 +1,138 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.application;
+
+import java.io.BufferedReader;
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStreamReader;
+import java.lang.reflect.InvocationTargetException;
+import java.lang.reflect.Method;
+import java.lang.reflect.Modifier;
+import java.net.ServerSocket;
+import java.net.Socket;
+
+/**
+ * @author ven
+ * @noinspection HardCodedStringLiteral
+ */
+public class AppMain {
+  private static final String PROPERTY_PORT_NUMBER = "idea.launcher.port";
+  private static final String PROPERTY_BINPATH = "idea.launcher.bin.path";
+
+  private static native void triggerControlBreak();
+
+  static {
+    String binPath = System.getProperty(PROPERTY_BINPATH) + File.separator;
+    final String osName = System.getProperty("os.name").toLowerCase();
+    String arch = System.getProperty("os.arch").toLowerCase();
+    String libPath = null;
+    if (osName.startsWith("windows")) {
+      if (arch.equals("amd64")) {
+        libPath = binPath + "breakgen64.dll";
+      }
+      else {
+        libPath = binPath + "breakgen.dll";
+      }
+    } else if (osName.startsWith("linux")) {
+      if (arch.equals("amd64")) {
+        libPath = binPath + "libbreakgen64.so";
+      } else {
+        libPath = binPath + "libbreakgen.so";
+      }
+    } else if (osName.startsWith("mac")) {
+      if (arch.endsWith("64")) {
+        libPath = binPath + "libbreakgen64.jnilib";
+      } else {
+        libPath = binPath + "libbreakgen.jnilib";
+      }
+    }
+
+    try {
+      if (libPath != null) {
+        System.load(libPath);
+      }
+    }
+    catch (UnsatisfiedLinkError e) {
+      //Do nothing, unknown os or some other error => no ctrl-break is available
+    }
+  }
+
+  public static void main(String[] args) throws Throwable {
+
+    final int portNumber = Integer.getInteger(PROPERTY_PORT_NUMBER).intValue();
+    Thread t = new Thread(
+      new Runnable() {
+        public void run() {
+          try {
+            ServerSocket socket = new ServerSocket(portNumber);
+            Socket client = socket.accept();
+            BufferedReader reader = new BufferedReader(new InputStreamReader(client.getInputStream()));
+            while (true) {
+              String msg = reader.readLine();
+
+              if ("TERM".equals(msg)){
+                return;
+              }
+              else if ("BREAK".equals(msg)) {
+                triggerControlBreak();
+              }
+              else if ("STOP".equals(msg)) {
+                System.exit(1);
+              }
+            }
+          } catch (IOException ignored) {
+          } catch (IllegalArgumentException ignored) {
+          } catch (SecurityException ignored) {
+          }
+        }
+      }, "Monitor Ctrl-Break");
+    try {
+      t.setDaemon(true);
+      t.start();
+    } catch (Exception ignored) {}
+
+    String mainClass = args[0];
+    String[] parms = new String[args.length - 1];
+    for (int j = 1; j < args.length; j++) {
+      parms[j - 1] = args[j];
+    }
+    Method m = Class.forName(mainClass).getMethod("main", new Class[]{parms.getClass()});
+    if (!Modifier.isStatic(m.getModifiers())) {
+      System.err.println("main method should be static");
+      return;
+    }
+    try {
+      ensureAccess(m);
+      m.invoke(null, new Object[]{parms});
+    } catch (InvocationTargetException ite) {
+      throw ite.getTargetException();
+    }
+  }
+
+  private static void ensureAccess(Object reflectionObject) {
+    // need to call setAccessible here in order to be able to launch package-local classes
+    // calling setAccessible() via reflection because the method is missing from java version 1.1.x
+    final Class aClass = reflectionObject.getClass();
+    try {
+      final Method setAccessibleMethod = aClass.getMethod("setAccessible", new Class[] {boolean.class});
+      setAccessibleMethod.invoke(reflectionObject, new Object[] {Boolean.TRUE});
+    }
+    catch (Exception e) {
+      // the method not found
+    }
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/application/MainAppClassLoader.java b/java/java-runtime/src/com/intellij/rt/execution/application/MainAppClassLoader.java
new file mode 100644
index 0000000..402c1d6
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/application/MainAppClassLoader.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.application;
+
+import java.io.File;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * @author ven
+ */
+public class MainAppClassLoader  extends URLClassLoader {
+  /**
+   * @noinspection HardCodedStringLiteral
+   */
+  private static final String USER_CLASSPATH = "idea.user.classpath";
+  private final Class myAppMainClass;
+
+  private static URL[] makeUrls() {
+    List classpath = new ArrayList();
+    try {
+      String userClassPath = System.getProperty(USER_CLASSPATH, "");
+      StringTokenizer tokenizer = new StringTokenizer(userClassPath, File.pathSeparator, false);
+      while (tokenizer.hasMoreTokens()) {
+        String pathItem = tokenizer.nextToken();
+        classpath.add(new File(pathItem).toURL());
+      }
+    } catch (MalformedURLException e) {
+      e.printStackTrace();
+    }
+    return (URL[]) classpath.toArray(new URL[classpath.size()]);
+  }
+
+  public MainAppClassLoader(ClassLoader loader) {
+    super(makeUrls(), null);
+    myAppMainClass = AppMain.class;
+  }
+
+  protected synchronized Class loadClass(String name, boolean resolve) throws ClassNotFoundException {
+    if (name.equals(myAppMainClass.getName())) {
+      return myAppMainClass;
+    }
+    return super.loadClass(name, resolve);
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonDetailsExtractor.java b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonDetailsExtractor.java
new file mode 100644
index 0000000..78ce51b
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonDetailsExtractor.java
@@ -0,0 +1,103 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit;
+
+import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
+import com.intellij.rt.execution.junit.segments.Packet;
+import com.intellij.rt.execution.junit.states.PoolOfTestStates;
+import junit.framework.ComparisonFailure;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @noinspection HardCodedStringLiteral
+ */
+public class ComparisonDetailsExtractor extends ExceptionPacketFactory {
+  private static Map EXPECTED = new HashMap();
+  private static Map ACTUAL = new HashMap();
+  protected String myActual = "";
+  protected String myExpected = "";
+
+  static {
+    try {
+      init(ComparisonFailure.class);
+      init(org.junit.ComparisonFailure.class);
+    } catch (Throwable e) {}
+  }
+
+  private static void init(Class exceptionClass) throws NoSuchFieldException {
+    final Field expectedField = exceptionClass.getDeclaredField("fExpected");
+    expectedField.setAccessible(true);
+    EXPECTED.put(exceptionClass, expectedField);
+
+    final Field actualField = exceptionClass.getDeclaredField("fActual");
+    actualField.setAccessible(true);
+    ACTUAL.put(exceptionClass, actualField);
+  }
+
+  public ComparisonDetailsExtractor(Throwable assertion, String expected, String actual) {
+    super(PoolOfTestStates.COMPARISON_FAILURE, assertion);
+    myActual = actual;
+    myExpected = expected;
+  }
+
+  public static ExceptionPacketFactory create(Throwable assertion) {
+    try {
+      return create(assertion, getExpected(assertion), getActual(assertion));
+    }
+    catch (Throwable e) {
+      return new ExceptionPacketFactory(PoolOfTestStates.FAILED_INDEX, assertion);
+    }
+  }
+
+  public static String getActual(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+    return get(assertion, ACTUAL, "fActual");
+  }
+
+  public static String getExpected(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+    return get(assertion, EXPECTED, "fExpected");
+  }
+
+  private static String get(final Throwable assertion, final Map staticMap, final String fieldName) throws IllegalAccessException, NoSuchFieldException {
+    String actual;
+    if (assertion instanceof ComparisonFailure) {
+      actual = (String)((Field)staticMap.get(ComparisonFailure.class)).get(assertion);
+    }
+    else if (assertion instanceof org.junit.ComparisonFailure) {
+      actual = (String)((Field)staticMap.get(org.junit.ComparisonFailure.class)).get(assertion);
+    }
+    else {
+      Field field = assertion.getClass().getDeclaredField(fieldName);
+      field.setAccessible(true);
+      actual = (String)field.get(assertion);
+    }
+    return actual;
+  }
+
+  public static ExceptionPacketFactory create(Throwable assertion, final String expected, String actual) {
+    return new ComparisonDetailsExtractor(assertion, expected, actual);
+  }
+
+  public Packet createPacket(OutputObjectRegistry registry, Object test) {
+    Packet packet = super.createPacket(registry, test);
+    packet.
+        addLimitedString(myExpected).
+        addLimitedString(myActual);
+    return packet;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/ExceptionPacketFactory.java b/java/java-runtime/src/com/intellij/rt/execution/junit/ExceptionPacketFactory.java
new file mode 100644
index 0000000..0d577cb
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/ExceptionPacketFactory.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit;
+
+import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
+import com.intellij.rt.execution.junit.segments.Packet;
+
+public class ExceptionPacketFactory implements PacketFactory {
+  private final Throwable myAssertion;
+  private int myState;
+
+  public ExceptionPacketFactory(int state, Throwable assertion) {
+    myState = state;
+    myAssertion = assertion;
+  }
+
+  public Packet createPacket(OutputObjectRegistry registry, Object test) {
+    return registry.createPacket().
+        setTestState(test, myState).
+        addThrowable(myAssertion);
+  }
+
+  protected void setState(int state) { myState = state; }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
new file mode 100644
index 0000000..0a66a53
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit;
+
+import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
+import com.intellij.rt.execution.junit.segments.Packet;
+import junit.framework.ComparisonFailure;
+
+public class FileComparisonFailure extends ComparisonFailure implements KnownException {
+  private final String myExpected;
+  private final String myActual;
+  private final String myFilePath;
+
+  public FileComparisonFailure(String message, String expected, String actual, String filePath) {
+    super(message, expected, actual);
+    myExpected = expected;
+    myActual = actual;
+    myFilePath = filePath;
+  }
+
+  public PacketFactory getPacketFactory() {
+    return new MyPacketFactory(this, myExpected, myActual, myFilePath);
+  }
+
+  private static class MyPacketFactory extends ComparisonDetailsExtractor {
+    private final String myFilePath;
+
+    public MyPacketFactory(ComparisonFailure assertion, String expected, String actual, String filePath) {
+      super(assertion, expected, actual);
+      myFilePath = filePath;
+    }
+
+    public Packet createPacket(OutputObjectRegistry registry, Object test) {
+      Packet packet = super.createPacket(registry, test);
+      packet.addLimitedString(myFilePath);
+      return packet;
+    }
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/KnownException.java b/java/java-runtime/src/com/intellij/rt/execution/junit/KnownException.java
new file mode 100644
index 0000000..b5d35bd
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/KnownException.java
@@ -0,0 +1,20 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit;
+
+public interface KnownException {
+  PacketFactory getPacketFactory();
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/PacketFactory.java b/java/java-runtime/src/com/intellij/rt/execution/junit/PacketFactory.java
new file mode 100644
index 0000000..25f536e
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/PacketFactory.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit;
+
+import com.intellij.rt.execution.junit.segments.OutputObjectRegistry;
+import com.intellij.rt.execution.junit.segments.Packet;
+
+public interface PacketFactory {
+  Packet createPacket(OutputObjectRegistry registry, Object test);
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java
new file mode 100644
index 0000000..ec194dc
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/OutputObjectRegistry.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+import java.util.Collection;
+import java.util.Hashtable;
+
+public abstract class OutputObjectRegistry  {
+  private final Hashtable myKnownKeys = new Hashtable();
+  private int myLastIndex = 0;
+  private PacketProcessor myMainTransport;
+
+  protected OutputObjectRegistry(PacketProcessor mainTransport, int lastIndex) {
+    myLastIndex = lastIndex;
+    myMainTransport = mainTransport;
+  }
+
+  public String referenceTo(Object test) {
+    if (containsKey(test)) return getKey(test);
+    return sendObject(test);
+  }
+
+  public String referenceTo(Object test, Collection packets) {
+    if (containsKey(test)) return getKey(test);
+    return sendObject(test, packets);
+  }
+
+  private boolean containsKey(Object test) {
+    return myKnownKeys.containsKey(createObjectWrapper(test));
+  }
+
+  private String getKey(Object test) {
+    return (String)myKnownKeys.get(createObjectWrapper(test));
+  }
+
+  private void putKey(Object test, String key) {
+    myKnownKeys.put(createObjectWrapper(test), key);
+  }
+
+  public void forget(Object test) {
+    myKnownKeys.remove(createObjectWrapper(test));
+  }
+
+  private String sendObject(Object test, Collection packets) {
+    final String key = String.valueOf(myLastIndex++);
+    putKey(test, key);
+    final Packet packet = createPacket();
+    packet.addString(PoolOfDelimiters.OBJECT_PREFIX).addReference(key);
+    addStringRepresentation(test, packet);
+    packet.addLong(getTestCont(test));
+    packet.addString(PoolOfDelimiters.REFERENCE_END_STR);
+    packets.add(packet);
+    return key;
+  }
+
+  public Packet createPacket() {
+    return new Packet(myMainTransport, this);
+  }
+
+  private String sendObject(Object test) {
+    final String key = String.valueOf(myLastIndex++);
+    putKey(test, key);
+    Packet packet = createPacket().addString(PoolOfDelimiters.OBJECT_PREFIX).addReference(key);
+    addStringRepresentation(test, packet);
+    packet.addLong(getTestCont(test));
+    packet.send();
+    return key;
+  }
+
+  protected abstract int getTestCont(Object test);
+  protected abstract void addStringRepresentation(Object test, Packet packet);
+
+  protected static void addTestClass(Packet packet, String className) {
+    packet.
+        addLimitedString(PoolOfTestTypes.TEST_CLASS).
+        addLimitedString(className);
+  }
+
+  protected void addUnknownTest(Packet packet, Object test) {
+    packet.
+        addLimitedString(PoolOfTestTypes.UNKNOWN).
+        addLong(getTestCont(test)).
+        addLimitedString(test.getClass().getName());
+  }
+
+  protected static void addAllInPackage(Packet packet, String name) {
+    packet.
+        addLimitedString(PoolOfTestTypes.ALL_IN_PACKAGE).
+        addLimitedString(name);
+  }
+
+  protected static void addTestMethod(Packet packet, String methodName, String className) {
+    packet.
+        addLimitedString(PoolOfTestTypes.TEST_METHOD).
+        addLimitedString(methodName).
+        addLimitedString(className);
+  }
+
+  public int getKnownObject(Object description) {
+    final Object o = getKey(description);
+    if (o instanceof String) {
+      return Integer.parseInt((String)o);
+    }
+    return 0;
+  }
+
+  protected Object createObjectWrapper(Object object) {
+    return object;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/Packet.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/Packet.java
new file mode 100644
index 0000000..30e9dae
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/Packet.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+import junit.runner.BaseTestRunner;
+
+import java.io.*;
+import java.util.Collection;
+import java.util.Vector;
+
+public class Packet extends PacketWriter {
+  private final OutputObjectRegistry myRegistry;
+  private final PacketProcessor myTransport;
+  public static final char ourSpecialSymbol = '$';
+  public static final char[] ourSymbolsToEncode = new char[] {'\n', '\r', SegmentedStream.SPECIAL_SYMBOL};
+  public static final int CODE_LENGTH = 2;
+
+  public Packet(PacketProcessor transport, OutputObjectRegistry registry) {
+    myTransport = transport;
+    myRegistry = registry;
+  }
+
+  public Packet addObject(Object test) {
+    return addReference(myRegistry.referenceTo(test));
+  }
+
+  public Packet addObject(Object test, Collection packet) {
+    return addReference(myRegistry.referenceTo(test, packet));
+  }
+
+  public Packet addReference(String reference) {
+    appendString(reference + PoolOfDelimiters.REFERENCE_END);
+    return this;
+  }
+
+  public Packet switchInputTo(Object test) {
+    appendString(PoolOfDelimiters.INPUT_COSUMER);
+    return addObject(test);
+  }
+
+  public Packet addString(String string) {
+    appendString(string);
+    return this;
+  }
+
+  public void send() {
+    sendThrough(myTransport);
+  }
+
+  public Packet addLong(long integer) {
+    appendLong(integer);
+    return this;
+  }
+
+  public Packet setTestState(Object test, int state) {
+    return addString(PoolOfDelimiters.CHANGE_STATE).addObject(test).addLong(state);
+  }
+
+  public Packet addLimitedString(String message) {
+    appendLimitedString(message);
+    return this;
+  }
+
+  public Packet addThrowable(Throwable throwable) {
+    String filteredTrace;
+    try {
+      filteredTrace = BaseTestRunner.getFilteredTrace(throwable);
+    }
+    catch (Throwable e) {
+      filteredTrace = BaseTestRunner.getFilteredTrace(e);
+    }
+
+    String message;
+    try {
+      message = BaseTestRunner.getPreference("filterstack").equals("true") ? makeNewLinesCompatibleWithJUnit(throwableToString(throwable)) : throwableToString(throwable);
+    }
+    catch (Throwable e) {
+      message = throwableToString(e);
+    }
+
+    addLimitedString(message);
+    if (filteredTrace.startsWith(message))
+      filteredTrace = filteredTrace.substring(message.length());
+    addLimitedString(new TraceFilter(filteredTrace).execute());
+    return this;
+  }
+
+  private static String throwableToString(final Throwable throwable) {
+    final String tostring = throwable.toString();
+    return tostring == null ? throwable.getClass().getName() : tostring;
+  }
+
+  private static String makeNewLinesCompatibleWithJUnit(String string) {
+    try {
+      StringWriter buffer = new StringWriter();
+      PrintWriter writer = new PrintWriter(buffer);
+      BufferedReader reader = new BufferedReader(new StringReader(string));
+      String line;
+      while ((line = reader.readLine()) != null)
+        writer.println(line);
+      return buffer.getBuffer().toString();
+    } catch (IOException e) {return null;}
+  }
+
+  public static String encode(String packet) {
+    StringBuffer buffer = new StringBuffer(packet.length());
+    for (int i = 0; i < packet.length(); i++) {
+      char chr = packet.charAt(i);
+      if (chr == ourSpecialSymbol) {
+        buffer.append(chr);
+        buffer.append(chr);
+        continue;
+      }
+      boolean appendChar = true;
+      for (int j = 0; j < ourSymbolsToEncode.length; j++) {
+        if (ourSymbolsToEncode[j] == chr) {
+          buffer.append(ourSpecialSymbol);
+          final String code = String.valueOf((int)chr);
+          for (int count = CODE_LENGTH - code.length(); count > 0; count--) {
+            buffer.append("0");
+          }
+          buffer.append(code);
+          appendChar = false;
+          break;
+        }
+      }
+      if (appendChar) {
+        buffer.append(chr);
+      }
+    }
+    return buffer.toString();
+  }
+
+  public Packet addStrings(Vector vector) {
+    int size = vector.size();
+    addLong(size);
+    for (int i = 0; i < size; i++) {
+      addLimitedString((String)vector.elementAt(i));
+    }
+    return this;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketProcessor.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketProcessor.java
new file mode 100644
index 0000000..e214a0e
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketProcessor.java
@@ -0,0 +1,21 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+public interface PacketProcessor {
+
+  void processPacket(String packet);
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketWriter.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketWriter.java
new file mode 100644
index 0000000..5ae08b6
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PacketWriter.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+public class PacketWriter {
+  private final StringBuffer myBody = new StringBuffer();
+
+  public void appendString(String string) {
+    myBody.append(string);
+  }
+
+  public void appendLong(long integer) {
+    myBody.append(integer);
+    myBody.append(PoolOfDelimiters.INTEGER_DELIMITER);
+  }
+
+  public void appendLimitedString(String message) {
+    if (message == null)
+      appendLimitedString("");
+    else {
+      appendLong(message.length());
+      appendString(message);
+    }
+  }
+
+  public String getString() {
+    return myBody.toString();
+  }
+
+  public void sendThrough(PacketProcessor transport) {
+    transport.processPacket(getString());
+  }
+
+  public void appendChar(char aChar) {
+    myBody.append(aChar);
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfDelimiters.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfDelimiters.java
new file mode 100644
index 0000000..6f87e8c
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfDelimiters.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+/**
+ * @noinspection HardCodedStringLiteral
+ */
+public interface PoolOfDelimiters {
+  char REFERENCE_END = ':';
+  String REFERENCE_END_STR = ":";
+  char INTEGER_DELIMITER = ' ';
+
+  String OBJECT_PREFIX = "O";
+  String TREE_PREFIX = "T";
+  String INPUT_COSUMER = "I";
+  String CHANGE_STATE = "S";
+  String TESTS_DONE = "D";
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfTestTypes.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfTestTypes.java
new file mode 100644
index 0000000..773413d
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/PoolOfTestTypes.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+/**
+ * @noinspection HardCodedStringLiteral
+ */
+public interface PoolOfTestTypes {
+  String TEST_METHOD = "TM";
+  String TEST_CLASS = "TC";
+  String ALL_IN_PACKAGE = "TN";
+
+  String UNKNOWN = "TU";
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java
new file mode 100644
index 0000000..f6f8127
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedOutputStream.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+import java.io.IOException;
+import java.io.OutputStream;
+import java.io.PrintStream;
+
+public class SegmentedOutputStream extends OutputStream implements PacketProcessor {
+  private final PrintStream myPrintStream;
+  private boolean myStarted = false;
+
+  public SegmentedOutputStream(PrintStream transportStream) {
+    this(transportStream, false);
+  }
+
+  public SegmentedOutputStream(PrintStream transportStream, boolean started) {
+    myPrintStream = transportStream;
+    myStarted = started;
+    try {
+      flush();
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e.getLocalizedMessage());
+    }
+  }
+
+  public synchronized void write(int b) throws IOException {
+    if (b == SegmentedStream.SPECIAL_SYMBOL && myStarted) writeNext(b);
+    writeNext(b);
+    flush();
+  }
+
+  public synchronized void flush() throws IOException {
+    myPrintStream.flush();
+  }
+
+  public synchronized void close() throws IOException {
+    myPrintStream.close();
+  }
+
+  private void writeNext(int b) {
+    myPrintStream.write(b);
+  }
+
+  public synchronized void processPacket(String packet) {
+    if (!myStarted)
+      sendStart();
+    writeNext(SegmentedStream.MARKER_PREFIX);
+    String encodedPacket = Packet.encode(packet);
+    writeNext(String.valueOf(encodedPacket.length())+SegmentedStream.LENGTH_DELIMITER+encodedPacket);
+  }
+
+  private void writeNext(String string) {
+    try {
+      myPrintStream.write(string.getBytes());
+    } catch (IOException e) {
+      throw new RuntimeException(e.getMessage());
+    }
+  }
+
+  public void sendStart() {
+    writeNext(SegmentedStream.STARTUP_MESSAGE);
+    myStarted = true;
+  }
+
+  public PrintStream getPrintStream() {
+    return myPrintStream;
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedStream.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedStream.java
new file mode 100644
index 0000000..0248402
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/SegmentedStream.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+/**
+ * @noinspection HardCodedStringLiteral
+ */
+public interface SegmentedStream {
+  char SPECIAL_SYMBOL = '/';
+  String SPECIAL_SYMBOL_STRING = String.valueOf(SPECIAL_SYMBOL);
+  String MARKER_PREFIX = SPECIAL_SYMBOL_STRING + '\u0001';
+  String LENGTH_DELIMITER = " ";
+  String STARTUP_MESSAGE = "@#IJIDEA#JUnitSupport#@";
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/segments/TraceFilter.java b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/TraceFilter.java
new file mode 100644
index 0000000..95fdb5b
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/segments/TraceFilter.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.segments;
+
+import java.io.*;
+import java.util.Vector;
+
+class TraceFilter {
+  private final String myTrace;
+  private final Vector myLines = new Vector();
+
+  public TraceFilter(String trace) {
+    myTrace = trace;
+  }
+
+  public String execute() {
+    try {
+      readLines();
+    } catch (IOException e) {
+      return myTrace;
+    }
+    int traceLastLine = firstJUnitLine(myLines.size() - 1, true);
+    if (traceLastLine < 0) return "";
+    int traceFirstLine = firstJUnitLine(traceLastLine, false);
+    StringWriter buffer = new StringWriter();
+    PrintWriter writer = new PrintWriter(buffer);
+    for (int i = 0; i < traceFirstLine; i++) writer.println(myLines.elementAt(i));
+    for (int i = traceLastLine; i < myLines.size(); i++) writer.println(myLines.elementAt(i));
+    writer.flush();
+    return buffer.toString();
+  }
+
+  private int firstJUnitLine(int startFrom, boolean searchForJUnitLines) {
+    for (int i = startFrom; i >= 0; i--) {
+      String line = (String) myLines.elementAt(i);
+      if (isIdeaJUnit(line) == searchForJUnitLines) return i;
+    }
+    return startFrom;
+  }
+
+  /**
+   * @noinspection HardCodedStringLiteral
+   */
+  private boolean isIdeaJUnit(String line) {
+    return line.indexOf("com.intellij.rt") >= 0;
+  }
+
+  private void readLines() throws IOException {
+    BufferedReader reader = new BufferedReader(new StringReader(myTrace));
+    String line;
+    while ((line = reader.readLine()) != null) { myLines.addElement(line); }
+    reader.close();
+  }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/states/PoolOfTestStates.java b/java/java-runtime/src/com/intellij/rt/execution/junit/states/PoolOfTestStates.java
new file mode 100644
index 0000000..f4f931c
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/states/PoolOfTestStates.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2009 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.rt.execution.junit.states;
+
+public interface PoolOfTestStates {
+  int SKIPPED_INDEX = 0;
+  int COMPLETE_INDEX = 1;
+  int NOT_RUN_INDEX = 2;
+  int RUNNING_INDEX = 3;
+  int TERMINATED_INDEX = 4;
+  int IGNORED_INDEX = 5;
+  int FAILED_INDEX = 6;
+  int COMPARISON_FAILURE = 7;
+  int ERROR_INDEX = 8;
+  int PASSED_INDEX = COMPLETE_INDEX;
+}