diff --git a/java/compiler/forms-compiler/forms-compiler.iml b/java/compiler/forms-compiler/forms-compiler.iml
new file mode 100644
index 0000000..1a851bf
--- /dev/null
+++ b/java/compiler/forms-compiler/forms-compiler.iml
@@ -0,0 +1,19 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_4" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="JDOM" level="project" />
+    <orderEntry type="module" module-name="forms_rt" />
+    <orderEntry type="library" name="asm4" level="project" />
+    <orderEntry type="library" scope="TEST" name="JUnit3" level="project" />
+    <orderEntry type="library" name="jgoodies-forms" level="project" />
+    <orderEntry type="module" module-name="instrumentation-util" exported="" />
+  </component>
+</module>
+
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AlienFormFileException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AlienFormFileException.java
new file mode 100644
index 0000000..f3b2eed
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AlienFormFileException.java
@@ -0,0 +1,22 @@
+/*
+ * 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.uiDesigner.compiler;
+
+public final class AlienFormFileException extends UIDesignerException{
+  public AlienFormFileException(){
+    super("Not IntelliJ IDEA GUI Designer form file");
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java
new file mode 100644
index 0000000..6b782b4
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/AsmCodeGenerator.java
@@ -0,0 +1,988 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.lw.*;
+import com.intellij.uiDesigner.shared.BorderType;
+import org.jetbrains.asm4.*;
+import org.jetbrains.asm4.Label;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import java.awt.*;
+import java.io.*;
+import java.lang.reflect.Modifier;
+import java.util.*;
+
+/**
+ * @author yole
+ */
+public class AsmCodeGenerator {
+  private final LwRootContainer myRootContainer;
+  private final InstrumentationClassFinder myFinder;
+  private final ArrayList myErrors;
+  private final ArrayList myWarnings;
+
+  private final Map myIdToLocalMap = new HashMap();
+
+  private static final String CONSTRUCTOR_NAME = "<init>";
+  private String myClassToBind;
+  private byte[] myPatchedData;
+
+  private static final Map myContainerLayoutCodeGenerators = new HashMap();
+  private static final Map myComponentLayoutCodeGenerators = new HashMap();
+  private static final Map myPropertyCodeGenerators = new LinkedHashMap();  // need LinkedHashMap for deterministic iteration
+  public static final String SETUP_METHOD_NAME = "$$$setupUI$$$";
+  public static final String GET_ROOT_COMPONENT_METHOD_NAME = "$$$getRootComponent$$$";
+  public static final String CREATE_COMPONENTS_METHOD_NAME = "createUIComponents";
+  public static final String LOAD_LABEL_TEXT_METHOD = "$$$loadLabelText$$$";
+  public static final String LOAD_BUTTON_TEXT_METHOD = "$$$loadButtonText$$$";
+
+  private static final Type ourButtonGroupType = Type.getType(ButtonGroup.class);
+  private static final Type ourBorderFactoryType = Type.getType(BorderFactory.class);
+  private static final Type ourBorderType = Type.getType(Border.class);
+  private static final Method ourCreateTitledBorderMethod = Method.getMethod(
+    "javax.swing.border.TitledBorder createTitledBorder(javax.swing.border.Border,java.lang.String,int,int,java.awt.Font,java.awt.Color)");
+
+  private static final String ourBorderFactoryClientProperty = "BorderFactoryClass";
+
+  private final NestedFormLoader myFormLoader;
+  private final boolean myIgnoreCustomCreation;
+  private final ClassWriter myClassWriter;
+
+  static {
+    myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_INTELLIJ, new GridLayoutCodeGenerator());
+    myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_GRIDBAG, new GridBagLayoutCodeGenerator());
+    myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_BORDER, new SimpleLayoutCodeGenerator(Type.getType(BorderLayout.class)));
+    myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_CARD, new CardLayoutCodeGenerator());
+    myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_FLOW, new FlowLayoutCodeGenerator());
+
+    myComponentLayoutCodeGenerators.put(LwSplitPane.class, new SplitPaneLayoutCodeGenerator());
+    myComponentLayoutCodeGenerators.put(LwTabbedPane.class, new TabbedPaneLayoutCodeGenerator());
+    myComponentLayoutCodeGenerators.put(LwScrollPane.class, new ScrollPaneLayoutCodeGenerator());
+    myComponentLayoutCodeGenerators.put(LwToolBar.class, new ToolBarLayoutCodeGenerator());
+
+    myPropertyCodeGenerators.put(String.class.getName(), new StringPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Dimension.class.getName(), new DimensionPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Insets.class.getName(), new InsetsPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Rectangle.class.getName(), new RectanglePropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Color.class.getName(), new ColorPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Font.class.getName(), new FontPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(Icon.class.getName(), new IconPropertyCodeGenerator());
+    myPropertyCodeGenerators.put(ListModel.class.getName(), new ListModelPropertyCodeGenerator(DefaultListModel.class));
+    myPropertyCodeGenerators.put(ComboBoxModel.class.getName(), new ListModelPropertyCodeGenerator(DefaultComboBoxModel.class));
+    myPropertyCodeGenerators.put("java.lang.Enum", new EnumPropertyCodeGenerator());
+  }
+
+  public AsmCodeGenerator(LwRootContainer rootContainer,
+                          InstrumentationClassFinder finder,
+                          NestedFormLoader formLoader,
+                          final boolean ignoreCustomCreation,
+                          final ClassWriter classWriter) {
+    myFormLoader = formLoader;
+    myIgnoreCustomCreation = ignoreCustomCreation;
+    if (finder == null){
+      throw new IllegalArgumentException("loader cannot be null");
+    }
+    if (rootContainer == null){
+      throw new IllegalArgumentException("rootContainer cannot be null");
+    }
+    myRootContainer = rootContainer;
+    myFinder = finder;
+
+    myErrors = new ArrayList();
+    myWarnings = new ArrayList();
+    myClassWriter = classWriter;
+  }
+
+  public void patchFile(final File classFile) {
+    if (!classFile.exists()) {
+      myErrors.add(new FormErrorInfo(null, "Class to bind does not exist: " + myRootContainer.getClassToBind()));
+      return;
+    }
+
+    FileInputStream fis;
+    try {
+      byte[] patchedData;
+      fis = new FileInputStream(classFile);
+      try {
+        patchedData = patchClass(fis);
+        if (patchedData == null) {
+          return;
+        }
+      }
+      finally {
+        fis.close();
+      }
+
+      FileOutputStream fos = new FileOutputStream(classFile);
+      try {
+        fos.write(patchedData);
+      }
+      finally {
+        fos.close();
+      }
+    }
+    catch (IOException e) {
+      myErrors.add(new FormErrorInfo(null, "Cannot read or write class file " + classFile.getPath() + ": " + e.toString()));
+    }
+    catch(IllegalStateException e) {
+      myErrors.add(new FormErrorInfo(null, "Unexpected data in form file when patching class " + classFile.getPath() + ": " + e.toString()));
+    }
+  }
+
+  public byte[] patchClass(InputStream classStream) {
+    try {
+      final ClassReader reader = new ClassReader(classStream);
+      return patchClass(reader);
+    }
+    catch (IOException e) {
+      myErrors.add(new FormErrorInfo(null, "Error reading class data stream"));
+      return null;
+    }
+  }
+
+  public byte[] patchClass(ClassReader reader) {
+    myClassToBind = myRootContainer.getClassToBind();
+    if (myClassToBind == null){
+      myWarnings.add(new FormErrorInfo(null, "No class to bind specified"));
+      return null;
+    }
+
+    if (myRootContainer.getComponentCount() != 1) {
+      myErrors.add(new FormErrorInfo(null, "There should be only one component at the top level"));
+      return null;
+    }
+
+    String nonEmptyPanel = Utils.findNotEmptyPanelWithXYLayout(myRootContainer.getComponent(0));
+    if (nonEmptyPanel != null) {
+      myErrors.add(new FormErrorInfo(nonEmptyPanel,
+                                     "There are non empty panels with XY layout. Please lay them out in a grid."));
+      return null;
+    }
+
+    FirstPassClassVisitor visitor = new FirstPassClassVisitor();
+    reader.accept(visitor, 0);
+
+    reader.accept(new FormClassVisitor(myClassWriter, visitor.isExplicitSetupCall()), 0);
+    myPatchedData = myClassWriter.toByteArray();
+    return myPatchedData;
+  }
+
+  public FormErrorInfo[] getErrors() {
+    return (FormErrorInfo[])myErrors.toArray(new FormErrorInfo[myErrors.size()]);
+  }
+
+  public FormErrorInfo[] getWarnings() {
+    return (FormErrorInfo[])myWarnings.toArray(new FormErrorInfo[myWarnings.size()]);
+  }
+
+  public byte[] getPatchedData() {
+    return myPatchedData;
+  }
+
+  static void pushPropValue(GeneratorAdapter generator, String propertyClass, Object value) {
+    PropertyCodeGenerator codeGen = (PropertyCodeGenerator)myPropertyCodeGenerators.get(propertyClass);
+    if (codeGen == null) {
+      throw new RuntimeException("Unknown property class " + propertyClass);
+    }
+    codeGen.generatePushValue(generator, value);
+  }
+
+  static InstrumentationClassFinder.PseudoClass getComponentClass(String className, final InstrumentationClassFinder finder) throws CodeGenerationException {
+    try {
+      return finder.loadClass(className);
+    }
+    catch (ClassNotFoundException e) {
+      throw new CodeGenerationException(null, "Class not found: " + className);
+    }
+    catch(UnsupportedClassVersionError e) {
+      throw new CodeGenerationException(null, "Unsupported class version error: " + className);
+    }
+    catch (IOException e) {
+      throw new CodeGenerationException(null, e.getMessage(), e);
+    }
+  }
+
+  public static Type typeFromClassName(final String className) {
+    return Type.getType("L" + className.replace('.', '/') + ";");
+  }
+
+  class FormClassVisitor extends ClassVisitor {
+    private String myClassName;
+    private String mySuperName;
+    private final Map myFieldDescMap = new HashMap();
+    private final Map myFieldAccessMap = new HashMap();
+    private boolean myHaveCreateComponentsMethod = false;
+    private int myCreateComponentsAccess;
+    private final boolean myExplicitSetupCall;
+
+    public FormClassVisitor(final ClassVisitor cv, final boolean explicitSetupCall) {
+      super(Opcodes.ASM4, cv);
+      myExplicitSetupCall = explicitSetupCall;
+    }
+
+    public void visit(final int version,
+                      final int access,
+                      final String name,
+                      final String signature,
+                      final String superName,
+                      final String[] interfaces) {
+      super.visit(version, access, name, signature, superName, interfaces);
+      myClassName = name;
+      mySuperName = superName;
+
+      for (Iterator iterator = myPropertyCodeGenerators.values().iterator(); iterator.hasNext();) {
+        PropertyCodeGenerator propertyCodeGenerator = (PropertyCodeGenerator)iterator.next();
+        propertyCodeGenerator.generateClassStart(this, name, myFinder);
+      }
+    }
+
+    public String getClassName() {
+      return myClassName;
+    }
+
+    public MethodVisitor visitMethod(final int access,
+                                     final String name,
+                                     final String desc,
+                                     final String signature,
+                                     final String[] exceptions) {
+
+      if (name.equals(SETUP_METHOD_NAME) || name.equals(GET_ROOT_COMPONENT_METHOD_NAME) ||
+          name.equals(LOAD_BUTTON_TEXT_METHOD) || name.equals(LOAD_LABEL_TEXT_METHOD)) {
+        return null;
+      }
+      if (name.equals(CREATE_COMPONENTS_METHOD_NAME) && desc.equals("()V")) {
+        myHaveCreateComponentsMethod = true;
+        myCreateComponentsAccess = access;
+      }
+
+      final MethodVisitor methodVisitor = super.visitMethod(access, name, desc, signature, exceptions);
+      if (name.equals(CONSTRUCTOR_NAME) && !myExplicitSetupCall) {
+        return new FormConstructorVisitor(methodVisitor, myClassName, mySuperName);
+      }
+      return methodVisitor;
+    }
+
+    MethodVisitor visitNewMethod(final int access,
+                                 final String name,
+                                 final String desc,
+                                 final String signature,
+                                 final String[] exceptions) {
+      return super.visitMethod(access, name, desc, signature, exceptions);
+    }
+
+    public FieldVisitor visitField(final int access, final String name, final String desc, final String signature, final Object value) {
+      myFieldDescMap.put(name, desc);
+      myFieldAccessMap.put(name, new Integer(access));
+      return super.visitField(access, name, desc, signature, value);
+    }
+
+    public void visitEnd() {
+      final boolean haveCustomCreateComponents = Utils.getCustomCreateComponentCount(myRootContainer) > 0 &&
+                                                 !myIgnoreCustomCreation;
+      if (haveCustomCreateComponents && !myHaveCreateComponentsMethod) {
+        myErrors.add(new FormErrorInfo(null, "Form contains components with Custom Create option but no createUIComponents() method"));
+      }
+
+      Method method = Method.getMethod("void " + SETUP_METHOD_NAME + " ()");
+      GeneratorAdapter generator = new GeneratorAdapter(Opcodes.ACC_PRIVATE | Opcodes.ACC_SYNTHETIC, method, null, null, cv);
+      if (haveCustomCreateComponents && myHaveCreateComponentsMethod) {
+        generator.visitVarInsn(Opcodes.ALOAD, 0);
+        int opcode = myCreateComponentsAccess == Opcodes.ACC_PRIVATE ? Opcodes.INVOKESPECIAL : Opcodes.INVOKEVIRTUAL;
+        generator.visitMethodInsn(opcode, myClassName, CREATE_COMPONENTS_METHOD_NAME, "()V");
+      }
+      buildSetupMethod(generator);
+
+      final String rootBinding = myRootContainer.getComponent(0).getBinding();
+      if (rootBinding != null && myFieldDescMap.containsKey(rootBinding)) {
+        buildGetRootComponenMethod();
+      }
+
+      for (Iterator iterator = myPropertyCodeGenerators.values().iterator(); iterator.hasNext();) {
+        PropertyCodeGenerator propertyCodeGenerator = (PropertyCodeGenerator)iterator.next();
+        propertyCodeGenerator.generateClassEnd(this);
+      }
+
+      super.visitEnd();
+    }
+
+    private void buildGetRootComponenMethod() {
+      final Type componentType = Type.getType(JComponent.class);
+      final Method method = new Method(GET_ROOT_COMPONENT_METHOD_NAME, componentType, new Type[0]);
+      GeneratorAdapter generator = new GeneratorAdapter(Opcodes.ACC_PUBLIC | Opcodes.ACC_SYNTHETIC, method, null, null, cv);
+
+      final LwComponent topComponent = (LwComponent)myRootContainer.getComponent(0);
+      final String binding = topComponent.getBinding();
+
+      generator.loadThis();
+      generator.getField(typeFromClassName(myClassName), binding,
+                         Type.getType((String) myFieldDescMap.get(binding)));
+      generator.returnValue();
+      generator.endMethod();
+    }
+
+    private void buildSetupMethod(final GeneratorAdapter generator) {
+      try {
+        final LwComponent topComponent = (LwComponent)myRootContainer.getComponent(0);
+        generateSetupCodeForComponent(topComponent, generator, -1);
+        generateComponentReferenceProperties(topComponent, generator);
+        generateButtonGroups(myRootContainer, generator);
+      }
+      catch (CodeGenerationException e) {
+        myErrors.add(new FormErrorInfo(e.getComponentId(), e.getMessage()));
+      }
+      generator.returnValue();
+      generator.endMethod();
+    }
+
+    private void generateSetupCodeForComponent(final LwComponent lwComponent,
+                                               final GeneratorAdapter generator,
+                                               final int parentLocal) throws CodeGenerationException {
+
+      String className;
+      if (lwComponent instanceof LwNestedForm) {
+        LwRootContainer nestedFormContainer;
+        LwNestedForm nestedForm = (LwNestedForm) lwComponent;
+        if (myFormLoader == null) {
+          throw new CodeGenerationException(null, "Attempt to compile nested form with no nested form loader specified");
+        }
+        try {
+          nestedFormContainer = myFormLoader.loadForm(nestedForm.getFormFileName());
+        }
+        catch (Exception e) {
+          throw new CodeGenerationException(lwComponent.getId(), e.getMessage());
+        }
+        // if nested form is empty, ignore
+        if (nestedFormContainer.getComponentCount() == 0) {
+          return;
+        }
+        if (nestedFormContainer.getComponent(0).getBinding() == null) {
+          throw new CodeGenerationException(lwComponent.getId(), "No binding on root component of nested form " + nestedForm.getFormFileName());
+        }
+        try {
+          Utils.validateNestedFormLoop(nestedForm.getFormFileName(), myFormLoader);
+        }
+        catch (RecursiveFormNestingException e) {
+          throw new CodeGenerationException(lwComponent.getId(), "Recursive form nesting is not allowed");
+        }
+        className = myFormLoader.getClassToBindName(nestedFormContainer);
+      }
+      else {
+        className = getComponentCodeGenerator(lwComponent.getParent()).mapComponentClass(lwComponent.getComponentClassName());
+      }
+      Type componentType = typeFromClassName(className);
+      int componentLocal = generator.newLocal(componentType);
+
+      myIdToLocalMap.put(lwComponent.getId(), new Integer(componentLocal));
+
+      InstrumentationClassFinder.PseudoClass componentClass = getComponentClass(className, myFinder);
+      validateFieldBinding(lwComponent, componentClass);
+
+      if (myIgnoreCustomCreation) {
+        try {
+          boolean creatable = true;
+          if ((componentClass.getModifiers() & (Modifier.PRIVATE | Modifier.ABSTRACT)) != 0) {
+            creatable = false;
+          }
+          else {
+            if (!componentClass.hasDefaultPublicConstructor()) {
+              creatable = false;
+            }
+          }
+          if (!creatable) {
+            componentClass = Utils.suggestReplacementClass(componentClass);
+            componentType = Type.getType(componentClass.getDescriptor());
+          }
+        }
+        catch (ClassNotFoundException e) {
+          throw new CodeGenerationException(lwComponent.getId(), e.getMessage(), e);
+        }
+        catch (IOException e) {
+          throw new CodeGenerationException(lwComponent.getId(), e.getMessage(), e);
+        }
+      }
+
+      if (!lwComponent.isCustomCreate() || myIgnoreCustomCreation) {
+        generator.newInstance(componentType);
+        generator.dup();
+        generator.invokeConstructor(componentType, Method.getMethod("void <init>()"));
+        generator.storeLocal(componentLocal);
+
+        generateFieldBinding(lwComponent, generator, componentLocal);
+      }
+      else {
+        final String binding = lwComponent.getBinding();
+        if (binding == null) {
+          throw new CodeGenerationException(lwComponent.getId(),
+                                            "Only components bound to fields can have custom creation code");
+        }
+        generator.loadThis();
+        generator.getField(getMainClassType(), binding,
+                           Type.getType((String)myFieldDescMap.get(binding)));
+        generator.storeLocal(componentLocal);
+      }
+
+      if (lwComponent instanceof LwContainer) {
+        LwContainer lwContainer = (LwContainer) lwComponent;
+        if (!lwContainer.isCustomCreate() || lwContainer.getComponentCount() > 0) {
+          getComponentCodeGenerator(lwContainer).generateContainerLayout(lwContainer, generator, componentLocal);
+        }
+      }
+
+      generateComponentProperties(lwComponent, componentClass, generator, componentLocal);
+
+      // add component to parent
+      if (!(lwComponent.getParent() instanceof LwRootContainer)) {
+        final LayoutCodeGenerator parentCodeGenerator = getComponentCodeGenerator(lwComponent.getParent());
+        if (lwComponent instanceof LwNestedForm) {
+          componentLocal = getNestedFormComponent(generator, componentClass, componentLocal);
+        }
+        parentCodeGenerator.generateComponentLayout(lwComponent, generator, componentLocal, parentLocal);
+      }
+
+      if (lwComponent instanceof LwContainer) {
+        LwContainer container = (LwContainer) lwComponent;
+
+        generateBorder(container, generator, componentLocal);
+
+        for(int i=0; i<container.getComponentCount(); i++) {
+          generateSetupCodeForComponent((LwComponent) container.getComponent(i), generator, componentLocal);
+        }
+      }
+    }
+
+    private int getNestedFormComponent(GeneratorAdapter generator, InstrumentationClassFinder.PseudoClass componentClass, int formLocal) throws CodeGenerationException {
+      final Type componentType = Type.getType(JComponent.class);
+      int componentLocal = generator.newLocal(componentType);
+      generator.loadLocal(formLocal);
+      generator.invokeVirtual(Type.getType(componentClass.getDescriptor()), new Method(GET_ROOT_COMPONENT_METHOD_NAME, componentType, new Type[0]));
+      generator.storeLocal(componentLocal);
+      return componentLocal;
+    }
+
+    private LayoutCodeGenerator getComponentCodeGenerator(final LwContainer container) {
+      LayoutCodeGenerator generator = (LayoutCodeGenerator) myComponentLayoutCodeGenerators.get(container.getClass());
+      if (generator != null) {
+        return generator;
+      }
+      LwContainer parent = container;
+      while(parent != null) {
+        final String layoutManager = parent.getLayoutManager();
+        if (layoutManager != null && layoutManager.length() > 0) {
+          if (layoutManager.equals(UIFormXmlConstants.LAYOUT_FORM) &&
+              !myContainerLayoutCodeGenerators.containsKey(UIFormXmlConstants.LAYOUT_FORM)) {
+            myContainerLayoutCodeGenerators.put(UIFormXmlConstants.LAYOUT_FORM, new FormLayoutCodeGenerator());
+          }
+          generator = (LayoutCodeGenerator) myContainerLayoutCodeGenerators.get(layoutManager);
+          if (generator != null) {
+            return generator;
+          }
+        }
+        parent = parent.getParent();
+      }
+      return GridLayoutCodeGenerator.INSTANCE;
+    }
+
+    private void generateComponentProperties(final LwComponent lwComponent,
+                                             final InstrumentationClassFinder.PseudoClass componentClass,
+                                             final GeneratorAdapter generator,
+                                             final int componentLocal) throws CodeGenerationException {
+      // introspected properties
+      final LwIntrospectedProperty[] introspectedProperties = lwComponent.getAssignedIntrospectedProperties();
+      for (int i = 0; i < introspectedProperties.length; i++) {
+        final LwIntrospectedProperty property = introspectedProperties[i];
+        if (property instanceof LwIntroComponentProperty) {
+          continue;
+        }
+        final String propertyClass = property.getCodeGenPropertyClassName();
+        if (myIgnoreCustomCreation) {
+          try {
+            Class setterClass;
+            if (propertyClass.equals(Integer.class.getName())) {
+              setterClass = int.class;
+            }
+            else if (propertyClass.equals(Boolean.class.getName())) {
+              setterClass = boolean.class;
+            }
+            else if (propertyClass.equals(Double.class.getName())) {
+              setterClass = double.class;
+            }
+            else if (propertyClass.equals(Float.class.getName())) {
+              setterClass = float.class;
+            }
+            else if (propertyClass.equals(Long.class.getName())) {
+              setterClass = long.class;
+            }
+            else if (propertyClass.equals(Byte.class.getName())) {
+              setterClass = byte.class;
+            }
+            else if (propertyClass.equals(Short.class.getName())) {
+              setterClass = short.class;
+            }
+            else if (propertyClass.equals(Character.class.getName())) {
+              setterClass = char.class;
+            }
+            else {
+              setterClass = Class.forName(propertyClass);
+            }
+            //componentClass.getMethod(property.getWriteMethodName(), new Class[] { setterClass } );
+            final String descriptor = "(L"+setterClass.getName().replace('.', '/') + ";)V";
+            final InstrumentationClassFinder.PseudoMethod setter = componentClass.findMethod(property.getWriteMethodName(), descriptor);
+            if (setter == null) {
+              continue;
+            }
+          }
+          catch (Exception e) {
+            continue;
+          }
+        }
+        final PropertyCodeGenerator propGen = (PropertyCodeGenerator) myPropertyCodeGenerators.get(propertyClass);
+
+        try {
+          if (propGen != null && propGen.generateCustomSetValue(lwComponent, componentClass, property, generator, componentLocal, myClassName)) {
+            continue;
+          }
+        }
+        catch (IOException e) {
+          throw new CodeGenerationException(lwComponent.getId(), e.getMessage(), e);
+        }
+        catch (ClassNotFoundException e) {
+          throw new CodeGenerationException(lwComponent.getId(), e.getMessage(), e);
+        }
+
+        generator.loadLocal(componentLocal);
+
+        Object value = lwComponent.getPropertyValue(property);
+        Type setterArgType;
+        if (propertyClass.equals(Integer.class.getName())) {
+          generator.push(((Integer) value).intValue());
+          setterArgType = Type.INT_TYPE;
+        }
+        else if (propertyClass.equals(Boolean.class.getName())) {
+          generator.push(((Boolean) value).booleanValue());
+          setterArgType = Type.BOOLEAN_TYPE;
+        }
+        else if (propertyClass.equals(Double.class.getName())) {
+          generator.push(((Double) value).doubleValue());
+          setterArgType = Type.DOUBLE_TYPE;
+        }
+        else if (propertyClass.equals(Float.class.getName())) {
+          generator.push(((Float) value).floatValue());
+          setterArgType = Type.FLOAT_TYPE;
+        }
+        else if (propertyClass.equals(Long.class.getName())) {
+          generator.push(((Long) value).longValue());
+          setterArgType = Type.LONG_TYPE;
+        }
+        else if (propertyClass.equals(Short.class.getName())) {
+          generator.push(((Short) value).intValue());
+          setterArgType = Type.SHORT_TYPE;
+        }
+        else if (propertyClass.equals(Byte.class.getName())) {
+          generator.push(((Byte) value).intValue());
+          setterArgType = Type.BYTE_TYPE;
+        }
+        else if (propertyClass.equals(Character.class.getName())) {
+          generator.push(((Character) value).charValue());
+          setterArgType = Type.CHAR_TYPE;
+        }
+        else {
+          if (propGen == null) {
+            continue;
+          }
+          propGen.generatePushValue(generator, value);
+          setterArgType = typeFromClassName(property.getPropertyClassName());
+        }
+
+        Type declaringType = (property.getDeclaringClassName() != null)
+                             ? typeFromClassName(property.getDeclaringClassName())
+                             : Type.getType(componentClass.getDescriptor());
+        generator.invokeVirtual(declaringType, new Method(property.getWriteMethodName(),
+                                                          Type.VOID_TYPE, new Type[] { setterArgType } ));
+      }
+
+      generateClientProperties(lwComponent, componentClass, generator, componentLocal);
+    }
+
+    private void generateClientProperties(final LwComponent lwComponent,
+                                          final InstrumentationClassFinder.PseudoClass componentClass,
+                                          final GeneratorAdapter generator,
+                                          final int componentLocal) throws CodeGenerationException {
+      HashMap props = lwComponent.getDelegeeClientProperties();
+      for (Iterator iterator = props.entrySet().iterator(); iterator.hasNext();) {
+        Map.Entry e = (Map.Entry) iterator.next();
+        generator.loadLocal(componentLocal);
+
+        generator.push((String) e.getKey());
+
+        Object value = e.getValue();
+        if (value instanceof StringDescriptor) {
+          generator.push(((StringDescriptor) value).getValue());
+        }
+        else if (value instanceof Boolean) {
+          boolean boolValue = ((Boolean) value).booleanValue();
+          Type booleanType = Type.getType(Boolean.class);
+          if (boolValue) {
+            generator.getStatic(booleanType, "TRUE", booleanType);
+          }
+          else {
+            generator.getStatic(booleanType, "FALSE", booleanType);
+          }
+        }
+        else {
+          Type valueType = Type.getType(value.getClass());
+          generator.newInstance(valueType);
+          generator.dup();
+          if (value instanceof Integer) {
+            generator.push(((Integer)value).intValue());
+            generator.invokeConstructor(valueType, Method.getMethod("void <init>(int)"));
+          }
+          else if (value instanceof Double) {
+            generator.push(((Double)value).doubleValue());
+            generator.invokeConstructor(valueType, Method.getMethod("void <init>(double)"));
+          }
+          else {
+            throw new CodeGenerationException(lwComponent.getId(), "Unknown client property value type");
+          }
+        }
+
+        Type componentType = Type.getType(componentClass.getDescriptor());
+        Type objectType = Type.getType(Object.class);
+        generator.invokeVirtual(componentType, new Method("putClientProperty",
+                                                          Type.VOID_TYPE, new Type[] { objectType, objectType } ));
+      }
+    }
+
+    private void generateComponentReferenceProperties(final LwComponent component,
+                                                      final GeneratorAdapter generator) throws CodeGenerationException {
+      if (component instanceof LwNestedForm) return;
+      int componentLocal = ((Integer) myIdToLocalMap.get(component.getId())).intValue();
+      final LayoutCodeGenerator layoutCodeGenerator = getComponentCodeGenerator(component.getParent());
+      InstrumentationClassFinder.PseudoClass componentClass = getComponentClass(layoutCodeGenerator.mapComponentClass(component.getComponentClassName()), myFinder);
+
+      final LwIntrospectedProperty[] introspectedProperties = component.getAssignedIntrospectedProperties();
+      for (int i = 0; i < introspectedProperties.length; i++) {
+        final LwIntrospectedProperty property = introspectedProperties[i];
+        if (property instanceof LwIntroComponentProperty) {
+          String targetId = (String) component.getPropertyValue(property);
+          if (targetId != null && targetId.length() > 0) {
+            // we may have a reference property pointing to a component which is
+            // no longer valid
+            final Integer targetLocalInt = (Integer)myIdToLocalMap.get(targetId);
+            if (targetLocalInt != null) {
+              int targetLocal = targetLocalInt.intValue();
+              generator.loadLocal(componentLocal);
+              generator.loadLocal(targetLocal);
+              Type declaringType = (property.getDeclaringClassName() != null)
+                                   ? typeFromClassName(property.getDeclaringClassName())
+                                   : Type.getType(componentClass.getDescriptor());
+              generator.invokeVirtual(declaringType,
+                                      new Method(property.getWriteMethodName(),
+                                                 Type.VOID_TYPE, new Type[] { typeFromClassName(property.getPropertyClassName()) } ));
+            }
+          }
+        }
+      }
+
+      if (component instanceof LwContainer) {
+        LwContainer container = (LwContainer) component;
+
+        for(int i=0; i<container.getComponentCount(); i++) {
+          generateComponentReferenceProperties((LwComponent) container.getComponent(i), generator);
+        }
+      }
+    }
+
+    private void generateButtonGroups(final LwRootContainer rootContainer, final GeneratorAdapter generator) throws CodeGenerationException {
+      IButtonGroup[] groups = rootContainer.getButtonGroups();
+      if (groups.length > 0) {
+        try {
+          InstrumentationClassFinder.PseudoClass buttonGroupClass = null; // cached
+          int groupLocal = generator.newLocal(ourButtonGroupType);
+          for(int groupIndex=0; groupIndex<groups.length; groupIndex++) {
+            String[] ids = groups [groupIndex].getComponentIds();
+
+            if (ids.length > 0) {
+              generator.newInstance(ourButtonGroupType);
+              generator.dup();
+              generator.invokeConstructor(ourButtonGroupType, Method.getMethod("void <init>()"));
+              generator.storeLocal(groupLocal);
+
+              if (groups [groupIndex].isBound() && !myIgnoreCustomCreation) {
+                if (buttonGroupClass == null) {
+                  buttonGroupClass = myFinder.loadClass(ButtonGroup.class.getName());
+                }
+                validateFieldClass(groups [groupIndex].getName(), buttonGroupClass, null);
+                generator.loadThis();
+                generator.loadLocal(groupLocal);
+                generator.putField(getMainClassType(), groups [groupIndex].getName(), ourButtonGroupType);
+              }
+
+              for(int i = 0; i<ids.length; i++) {
+                Integer localInt = (Integer) myIdToLocalMap.get(ids [i]);
+                if (localInt != null) {
+                  generator.loadLocal(groupLocal);
+                  generator.loadLocal(localInt.intValue());
+                  generator.invokeVirtual(ourButtonGroupType, Method.getMethod("void add(javax.swing.AbstractButton)"));
+                }
+              }
+            }
+          }
+        }
+        catch (IOException e) {
+          throw new CodeGenerationException(rootContainer.getId(), e.getMessage(), e);
+        }
+        catch (ClassNotFoundException e) {
+          throw new CodeGenerationException(rootContainer.getId(), e.getMessage(), e);
+        }
+      }
+    }
+
+    private void generateFieldBinding(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal) throws CodeGenerationException {
+      final String binding = lwComponent.getBinding();
+      if (binding != null) {
+        Integer access = (Integer) myFieldAccessMap.get(binding);
+        if ((access.intValue() & Opcodes.ACC_STATIC) != 0) {
+          throw new CodeGenerationException(lwComponent.getId(), "Cannot bind: field is static: " + myClassToBind + "." + binding);
+        }
+        if ((access.intValue() & Opcodes.ACC_FINAL) != 0) {
+          throw new CodeGenerationException(lwComponent.getId(), "Cannot bind: field is final: " + myClassToBind + "." + binding);
+        }
+
+        generator.loadThis();
+        generator.loadLocal(componentLocal);
+        generator.putField(getMainClassType(), binding,
+                           Type.getType((String)myFieldDescMap.get(binding)));
+      }
+    }
+
+    private Type getMainClassType() {
+      return Type.getType("L" + myClassName + ";");
+    }
+
+    private void validateFieldBinding(LwComponent component, final InstrumentationClassFinder.PseudoClass componentClass) throws CodeGenerationException {
+      String binding = component.getBinding();
+      if (binding == null) return;
+
+      validateFieldClass(binding, componentClass, component.getId());
+    }
+
+    private void validateFieldClass(String binding, InstrumentationClassFinder.PseudoClass componentClass, String componentId) throws CodeGenerationException {
+      if (!myFieldDescMap.containsKey(binding)) {
+        throw new CodeGenerationException(componentId, "Cannot bind: field does not exist: " + myClassToBind + "." + binding);
+      }
+
+      final Type fieldType = Type.getType((String)myFieldDescMap.get(binding));
+      if (fieldType.getSort() != Type.OBJECT) {
+        throw new CodeGenerationException(componentId, "Cannot bind: field is of primitive type: " + myClassToBind + "." + binding);
+      }
+
+      try {
+        final InstrumentationClassFinder.PseudoClass fieldClass = myFinder.loadClass(fieldType.getClassName());
+        if (!fieldClass.isAssignableFrom(componentClass)) {
+          throw new CodeGenerationException(componentId, "Cannot bind: Incompatible types. Cannot assign " + componentClass.getName().replace('/', '.') + " to field " + myClassToBind + "." + binding);
+        }
+      }
+      catch (ClassNotFoundException e) {
+        throw new CodeGenerationException(componentId, "Class not found: " + fieldType.getClassName());
+      }
+      catch (IOException e) {
+        throw new CodeGenerationException(componentId, e.getMessage(), e);
+      }
+    }
+
+    private void generateBorder(final LwContainer container, final GeneratorAdapter generator, final int componentLocal) {
+      final BorderType borderType = container.getBorderType();
+      final StringDescriptor borderTitle = container.getBorderTitle();
+      final String borderFactoryMethodName = borderType.getBorderFactoryMethodName();
+
+      final boolean borderNone = borderType.equals(BorderType.NONE);
+      if (!borderNone || borderTitle != null) {
+        // object to invoke setBorder
+        generator.loadLocal(componentLocal);
+
+        if (!borderNone) {
+          if (borderType.equals(BorderType.LINE)) {
+            if (container.getBorderColor() == null) {
+              Type colorType = Type.getType(Color.class);
+              generator.getStatic(colorType, "black", colorType);
+            }
+            else {
+              pushPropValue(generator, Color.class.getName(), container.getBorderColor());
+            }
+            generator.invokeStatic(ourBorderFactoryType,
+                                   new Method(borderFactoryMethodName, ourBorderType,
+                                              new Type[] { Type.getType(Color.class) } ));
+          }
+          else if (borderType.equals(BorderType.EMPTY) && container.getBorderSize() != null) {
+            Insets size = container.getBorderSize();
+            generator.push(size.top);
+            generator.push(size.left);
+            generator.push(size.bottom);
+            generator.push(size.right);
+            generator.invokeStatic(ourBorderFactoryType,
+                                   new Method(borderFactoryMethodName, ourBorderType,
+                                              new Type[] { Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE, Type.INT_TYPE }));
+          }
+          else {
+            generator.invokeStatic(ourBorderFactoryType,
+                                   new Method(borderFactoryMethodName, ourBorderType, new Type[0]));
+          }
+        }
+        else {
+          generator.push((String) null);
+        }
+        pushBorderProperties(container, generator, borderTitle, componentLocal);
+
+
+        Type borderFactoryType = ourBorderFactoryType;
+        StringDescriptor borderFactoryValue = (StringDescriptor)container.getDelegeeClientProperties().get(ourBorderFactoryClientProperty);
+        if (borderFactoryValue == null && borderTitle != null && Boolean.valueOf(System.getProperty("idea.is.internal")).booleanValue()) {
+          borderFactoryValue = StringDescriptor.create("com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent");
+          container.getDelegeeClientProperties().put(ourBorderFactoryClientProperty, borderFactoryValue);
+        }
+        if (borderFactoryValue != null && borderFactoryValue.getValue().length() != 0) {
+          borderFactoryType = typeFromClassName(borderFactoryValue.getValue());
+        }
+
+        generator.invokeStatic(borderFactoryType, ourCreateTitledBorderMethod);
+
+        // set border
+        generator.invokeVirtual(Type.getType(JComponent.class),
+                                Method.getMethod("void setBorder(javax.swing.border.Border)"));
+      }
+    }
+
+    private void pushBorderProperties(final LwContainer container, final GeneratorAdapter generator, final StringDescriptor borderTitle,
+                                      final int componentLocal) {
+      pushPropValue(generator, "java.lang.String", borderTitle);
+      generator.push(container.getBorderTitleJustification());
+      generator.push(container.getBorderTitlePosition());
+      final FontDescriptor font = container.getBorderTitleFont();
+      if (font == null) {
+        generator.push((String) null);
+      }
+      else {
+        FontPropertyCodeGenerator.generatePushFont(generator, componentLocal, container, font, "getFont");
+      }
+      if (container.getBorderTitleColor() == null) {
+        generator.push((String) null);
+      }
+      else {
+        pushPropValue(generator, Color.class.getName(), container.getBorderTitleColor());
+      }
+    }
+  }
+
+  private class FormConstructorVisitor extends MethodVisitor {
+    private final String myClassName;
+    private final String mySuperName;
+    private boolean callsSelfConstructor = false;
+    private boolean mySetupCalled = false;
+    private boolean mySuperCalled = false;
+
+    public FormConstructorVisitor(final MethodVisitor mv, final String className, final String superName) {
+      super(Opcodes.ASM4, mv);
+      myClassName = className;
+      mySuperName = superName;
+    }
+
+    public void visitFieldInsn(final int opcode, final String owner, final String name, final String desc) {
+      if (opcode == Opcodes.GETFIELD && !mySetupCalled && !callsSelfConstructor && Utils.isBoundField(myRootContainer, name)) {
+        callSetupUI();
+      }
+      super.visitFieldInsn(opcode, owner, name, desc);
+    }
+
+    public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+      if (opcode == Opcodes.INVOKESPECIAL && name.equals(CONSTRUCTOR_NAME)) {
+        if (owner.equals(myClassName)) {
+          callsSelfConstructor = true;
+        }
+        else if (owner.equals(mySuperName)) {
+          mySuperCalled = true;
+        }
+        else if (mySuperCalled) {
+          callSetupUI();
+        }
+      }
+      else if (mySuperCalled) {
+        callSetupUI();
+      }
+      super.visitMethodInsn(opcode, owner, name, desc);
+    }
+
+    public void visitJumpInsn(final int opcode, final Label label) {
+      if (mySuperCalled) {
+        callSetupUI();
+      }
+      super.visitJumpInsn(opcode, label);
+    }
+
+    private void callSetupUI() {
+      if (!mySetupCalled) {
+        mv.visitVarInsn(Opcodes.ALOAD, 0);
+        mv.visitMethodInsn(Opcodes.INVOKESPECIAL, myClassName, SETUP_METHOD_NAME, "()V");
+        mySetupCalled = true;
+      }
+    }
+
+    public void visitInsn(final int opcode) {
+      if (opcode == Opcodes.RETURN && !mySetupCalled && !callsSelfConstructor) {
+        callSetupUI();
+      }
+      super.visitInsn(opcode);
+    }
+  }
+
+  private static class FirstPassClassVisitor extends ClassVisitor {
+    private boolean myExplicitSetupCall = false;
+
+    public FirstPassClassVisitor() {
+      super(Opcodes.ASM4, new ClassVisitor(Opcodes.ASM4){});
+    }
+
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+      if (name.equals(CONSTRUCTOR_NAME)) {
+        return new FirstPassConstructorVisitor();
+      }
+      return null;
+    }
+
+    public boolean isExplicitSetupCall() {
+      return myExplicitSetupCall;
+    }
+
+    private class FirstPassConstructorVisitor extends MethodVisitor {
+      public FirstPassConstructorVisitor() {
+        super(Opcodes.ASM4, new MethodVisitor(Opcodes.ASM4){});
+      }
+
+      public void visitMethodInsn(final int opcode, final String owner, final String name, final String desc) {
+        if (name.equals(SETUP_METHOD_NAME)) {
+          myExplicitSetupCall = true;
+        }
+      }
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java
new file mode 100644
index 0000000..86b6e42
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CardLayoutCodeGenerator.java
@@ -0,0 +1,53 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.lw.LwComponent;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author Alexander Lobas
+ */
+public class CardLayoutCodeGenerator extends SimpleLayoutCodeGenerator {
+  private static final Method ourGetLayoutMethod = Method.getMethod("java.awt.LayoutManager getLayout()");
+  private static final Method ourShowMethod = Method.getMethod("void show(java.awt.Container,java.lang.String)");
+
+  public CardLayoutCodeGenerator() {
+    super(Type.getType(CardLayout.class));
+  }
+
+  public void generateComponentLayout(LwComponent lwComponent,
+                                      GeneratorAdapter generator,
+                                      int componentLocal,
+                                      int parentLocal) {
+    super.generateComponentLayout(lwComponent, generator, componentLocal, parentLocal);
+
+    String defaultCard = (String)lwComponent.getParent().getClientProperty(UIFormXmlConstants.LAYOUT_CARD);
+    if (lwComponent.getId().equals(defaultCard)) {
+      generator.loadLocal(parentLocal);
+      generator.invokeVirtual(ourContainerType, ourGetLayoutMethod);
+      generator.checkCast(myLayoutType);
+      generator.loadLocal(parentLocal);
+      generator.push((String) lwComponent.getCustomLayoutConstraints());
+      generator.invokeVirtual(myLayoutType, ourShowMethod);
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ClassToBindNotFoundException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ClassToBindNotFoundException.java
new file mode 100644
index 0000000..9a0c87d
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ClassToBindNotFoundException.java
@@ -0,0 +1,22 @@
+/*
+ * 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.uiDesigner.compiler;
+
+public final class ClassToBindNotFoundException extends CodeGenerationException{
+  public ClassToBindNotFoundException(final String message) {
+    super(null, message);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CodeGenerationException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CodeGenerationException.java
new file mode 100644
index 0000000..3920479
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/CodeGenerationException.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.uiDesigner.compiler;
+
+public class CodeGenerationException extends UIDesignerException {
+  private final String myComponentId;
+
+  public CodeGenerationException(final String componentId, final String message) {
+    super(message);
+    myComponentId = componentId;
+  }
+
+  public CodeGenerationException(final String componentId, final String message, final Throwable cause) {
+    super(message, cause);
+    myComponentId = componentId;
+  }
+
+  public String getComponentId() {
+    return myComponentId;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java
new file mode 100644
index 0000000..8443020
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ColorPropertyCodeGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.ColorDescriptor;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ * @noinspection HardCodedStringLiteral
+ */
+public class ColorPropertyCodeGenerator extends PropertyCodeGenerator {
+  private static final Type ourColorType = Type.getType(Color.class);
+  private static final Type ourObjectType = Type.getType(Object.class);
+  private static final Type ourUIManagerType = Type.getType("Ljavax/swing/UIManager;");
+  private static final Type ourSystemColorType = Type.getType(SystemColor.class);
+
+  private static final Method ourInitMethod = Method.getMethod("void <init>(int)");
+  private static final Method ourGetColorMethod = new Method("getColor", ourColorType, new Type[] { ourObjectType } );
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    ColorDescriptor descriptor = (ColorDescriptor) value;
+    if (descriptor.getColor() != null) {
+      generator.newInstance(ourColorType);
+      generator.dup();
+      generator.push(descriptor.getColor().getRGB());
+      generator.invokeConstructor(ourColorType, ourInitMethod);
+    }
+    else if (descriptor.getSwingColor() != null) {
+      generator.push(descriptor.getSwingColor());
+      generator.invokeStatic(ourUIManagerType, ourGetColorMethod);
+    }
+    else if (descriptor.getSystemColor() != null) {
+      generator.getStatic(ourSystemColorType, descriptor.getSystemColor(), ourSystemColorType);
+    }
+    else if (descriptor.getAWTColor() != null) {
+      generator.getStatic(ourColorType, descriptor.getAWTColor(), ourColorType);
+    }
+    else if (descriptor.isColorSet()) {
+      throw new IllegalStateException("Unknown color type");
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.java
new file mode 100644
index 0000000..7a0fd4f
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/DimensionPropertyCodeGenerator.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.uiDesigner.compiler;
+
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ * @noinspection HardCodedStringLiteral
+ */
+public class DimensionPropertyCodeGenerator extends PropertyCodeGenerator {
+  private static final Type myDimensionType = Type.getType(Dimension.class);
+  private static final Method myInitMethod = Method.getMethod("void <init>(int,int)");
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    Dimension dimension = (Dimension) value;
+    generator.newInstance(myDimensionType);
+    generator.dup();
+    generator.push(dimension.width);
+    generator.push(dimension.height);
+    generator.invokeConstructor(myDimensionType, myInitMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java
new file mode 100644
index 0000000..720d4c0
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/EnumPropertyCodeGenerator.java
@@ -0,0 +1,30 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+
+/**
+ * @author yole
+ */
+public class EnumPropertyCodeGenerator extends PropertyCodeGenerator {
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    final Type enumType = Type.getType(value.getClass());
+    generator.getStatic(enumType, value.toString(), enumType);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java
new file mode 100644
index 0000000..34a41d8
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FlowLayoutCodeGenerator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class FlowLayoutCodeGenerator extends LayoutCodeGenerator {
+  private static final Type ourFlowLayoutType = Type.getType(FlowLayout.class);
+  private static final Method ourConstructor = Method.getMethod("void <init>(int,int,int)");
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+    generator.loadLocal(componentLocal);
+
+    FlowLayout flowLayout = (FlowLayout) lwContainer.getLayout();
+    generator.newInstance(ourFlowLayoutType);
+    generator.dup();
+    generator.push(flowLayout.getAlignment());
+    generator.push(flowLayout.getHgap());
+    generator.push(flowLayout.getVgap());
+    generator.invokeConstructor(ourFlowLayoutType, ourConstructor);
+
+    generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
+  }
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    generator.invokeVirtual(ourContainerType, ourAddNoConstraintMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java
new file mode 100644
index 0000000..f15a8d4
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FontPropertyCodeGenerator.java
@@ -0,0 +1,119 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.uiDesigner.lw.FontDescriptor;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ * @noinspection HardCodedStringLiteral
+ */
+public class FontPropertyCodeGenerator extends PropertyCodeGenerator {
+  private static final Type ourFontType = Type.getType(Font.class);
+  private static final Type ourUIManagerType = Type.getType("Ljavax/swing/UIManager;");
+  private static final Type ourObjectType = Type.getType(Object.class);
+  private static final Type ourStringType = Type.getType(String.class);
+
+  private static final Method ourInitMethod = Method.getMethod("void <init>(java.lang.String,int,int)");
+  private static final Method ourUIManagerGetFontMethod = new Method("getFont", ourFontType, new Type[] { ourObjectType } );
+  private static final Method ourGetNameMethod = new Method("getName", ourStringType, new Type[0] );
+  private static final Method ourGetSizeMethod = new Method("getSize", Type.INT_TYPE, new Type[0] );
+  private static final Method ourGetStyleMethod = new Method("getStyle", Type.INT_TYPE, new Type[0] );
+
+  public boolean generateCustomSetValue(final LwComponent lwComponent,
+                                        final InstrumentationClassFinder.PseudoClass componentClass,
+                                        final LwIntrospectedProperty property,
+                                        final GeneratorAdapter generator,
+                                        final int componentLocal, final String formClassName) {
+    FontDescriptor descriptor = (FontDescriptor) property.getPropertyValue(lwComponent);
+    if (descriptor.isFixedFont() && !descriptor.isFullyDefinedFont()) {
+      generator.loadLocal(componentLocal);
+      generatePushFont(generator, componentLocal, lwComponent, descriptor, property.getReadMethodName());
+
+      Method setFontMethod = new Method(property.getWriteMethodName(), Type.VOID_TYPE, new Type[] { ourFontType } );
+      Type componentType = AsmCodeGenerator.typeFromClassName(lwComponent.getComponentClassName());
+      generator.invokeVirtual(componentType, setFontMethod);
+      return true;
+    }
+    return false;
+  }
+
+  public static void generatePushFont(final GeneratorAdapter generator, final int componentLocal, final LwComponent lwComponent,
+                                      final FontDescriptor descriptor, final String readMethodName) {
+    final int fontLocal = generator.newLocal(ourFontType);
+
+    generator.loadLocal(componentLocal);
+    Type componentType = AsmCodeGenerator.typeFromClassName(lwComponent.getComponentClassName());
+    Method getFontMethod = new Method(readMethodName, ourFontType, new Type[0] );
+    generator.invokeVirtual(componentType, getFontMethod);
+    generator.storeLocal(fontLocal);
+
+    generator.newInstance(ourFontType);
+    generator.dup();
+    if (descriptor.getFontName() != null) {
+      generator.push(descriptor.getFontName());
+    }
+    else {
+      generator.loadLocal(fontLocal);
+      generator.invokeVirtual(ourFontType, ourGetNameMethod);
+    }
+
+    if (descriptor.getFontStyle() >= 0) {
+      generator.push(descriptor.getFontStyle());
+    }
+    else {
+      generator.loadLocal(fontLocal);
+      generator.invokeVirtual(ourFontType, ourGetStyleMethod);
+    }
+
+    if (descriptor.getFontSize() >= 0) {
+      generator.push(descriptor.getFontSize());
+    }
+    else {
+      generator.loadLocal(fontLocal);
+      generator.invokeVirtual(ourFontType, ourGetSizeMethod);
+    }
+    generator.invokeConstructor(ourFontType, ourInitMethod);
+  }
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    FontDescriptor descriptor = (FontDescriptor) value;
+    if (descriptor.isFixedFont()) {
+      if (!descriptor.isFullyDefinedFont()) throw new IllegalStateException("Unexpected font state");
+      generator.newInstance(ourFontType);
+      generator.dup();
+      generator.push(descriptor.getFontName());
+      generator.push(descriptor.getFontStyle());
+      generator.push(descriptor.getFontSize());
+      generator.invokeConstructor(ourFontType, ourInitMethod);
+    }
+    else if (descriptor.getSwingFont() != null) {
+      generator.push(descriptor.getSwingFont());
+      generator.invokeStatic(ourUIManagerType, ourUIManagerGetFontMethod);
+    }
+    else {
+      throw new IllegalStateException("Unknown font type");
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormErrorInfo.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormErrorInfo.java
new file mode 100644
index 0000000..133d94b
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormErrorInfo.java
@@ -0,0 +1,46 @@
+/*
+ * 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.uiDesigner.compiler;
+
+/**
+ * @author yole
+ */
+public class FormErrorInfo {
+  private String myComponentId;
+  private String myErrorMessage;
+
+  public FormErrorInfo(final String componentId, final String errorMessage) {
+    myComponentId = componentId;
+    myErrorMessage = errorMessage;
+  }
+
+  public String getComponentId() {
+    return myComponentId;
+  }
+
+  public void setComponentId(final String componentId) {
+    myComponentId = componentId;
+  }
+
+  public String getErrorMessage() {
+    return myErrorMessage;
+  }
+
+  public void setErrorMessage(final String errorMessage) {
+    myErrorMessage = errorMessage;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java
new file mode 100644
index 0000000..a30061f
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutCodeGenerator.java
@@ -0,0 +1,125 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.jgoodies.forms.layout.FormLayout;
+import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class FormLayoutCodeGenerator extends LayoutCodeGenerator {
+  private static final Type ourFormLayoutType = Type.getType(FormLayout.class);
+  private static final Type ourCellConstraintsType = Type.getType(CellConstraints.class);
+  private static final Type ourCellAlignmentType = Type.getType(CellConstraints.Alignment.class);
+  private static final Method ourFormLayoutConstructor = Method.getMethod("void <init>(java.lang.String,java.lang.String)");
+  private static final Method ourCellConstraintsConstructor = Method.getMethod("void <init>(int,int,int,int,com.jgoodies.forms.layout.CellConstraints$Alignment,com.jgoodies.forms.layout.CellConstraints$Alignment,java.awt.Insets)");
+  private static final Method ourSetRowGroupsMethod = Method.getMethod("void setRowGroups(int[][])");
+  private static final Method ourSetColumnGroupsMethod = Method.getMethod("void setColumnGroups(int[][])");
+
+  public static String[] HORZ_ALIGN_FIELDS = new String[] { "LEFT", "CENTER", "RIGHT", "FILL" };
+  public static String[] VERT_ALIGN_FIELDS = new String[] { "TOP", "CENTER", "BOTTOM", "FILL" };
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+    FormLayout formLayout = (FormLayout) lwContainer.getLayout();
+
+    generator.loadLocal(componentLocal);
+
+    generator.newInstance(ourFormLayoutType);
+    generator.dup();
+    generator.push(FormLayoutUtils.getEncodedColumnSpecs(formLayout));
+    generator.push(FormLayoutUtils.getEncodedRowSpecs(formLayout));
+
+    generator.invokeConstructor(ourFormLayoutType, ourFormLayoutConstructor);
+
+    generateGroups(generator, formLayout.getRowGroups(), ourSetRowGroupsMethod);
+    generateGroups(generator, formLayout.getColumnGroups(), ourSetColumnGroupsMethod);
+
+    generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
+  }
+
+  private static void generateGroups(final GeneratorAdapter generator, final int[][] groups, final Method setGroupsMethod) {
+    if (groups.length == 0) return;
+    int groupLocal = generator.newLocal(Type.getType("[I"));
+    generator.dup();   // duplicate FormLayout reference
+    generator.push(groups.length);
+    generator.newArray(Type.getType("[I"));
+    for(int i=0; i<groups.length; i++) {
+      generator.dup();
+      generator.push(groups [i].length);
+      generator.newArray(Type.INT_TYPE);
+      generator.storeLocal(groupLocal);
+      for(int j=0; j<groups [i].length; j++) {
+        generator.loadLocal(groupLocal);
+        generator.push(j);
+        generator.push(groups [i][j]);
+        generator.visitInsn(Opcodes.IASTORE);
+      }
+      generator.push(i);
+      generator.loadLocal(groupLocal);
+      generator.visitInsn(Opcodes.AASTORE);
+    }
+    generator.invokeVirtual(ourFormLayoutType, setGroupsMethod);
+  }
+
+  public void generateComponentLayout(final LwComponent lwComponent, final GeneratorAdapter generator, final int componentLocal, final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    addNewCellConstraints(generator, lwComponent);
+    generator.invokeVirtual(ourContainerType, ourAddMethod);
+  }
+
+  private static void addNewCellConstraints(final GeneratorAdapter generator, final LwComponent lwComponent) {
+    final GridConstraints constraints = lwComponent.getConstraints();
+    final CellConstraints cc = (CellConstraints) lwComponent.getCustomLayoutConstraints();
+
+    generator.newInstance(ourCellConstraintsType);
+    generator.dup();
+    generator.push(constraints.getColumn()+1);
+    generator.push(constraints.getRow()+1);
+    generator.push(constraints.getColSpan());
+    generator.push(constraints.getRowSpan());
+
+    if (cc.hAlign == CellConstraints.DEFAULT) {
+      generator.getStatic(ourCellConstraintsType, "DEFAULT", ourCellAlignmentType);
+    }
+    else {
+      int hAlign = Utils.alignFromConstraints(constraints, true);
+      generator.getStatic(ourCellConstraintsType, HORZ_ALIGN_FIELDS[hAlign], ourCellAlignmentType);
+    }
+    if (cc.vAlign == CellConstraints.DEFAULT) {
+      generator.getStatic(ourCellConstraintsType, "DEFAULT", ourCellAlignmentType);
+    }
+    else {
+      int vAlign = Utils.alignFromConstraints(constraints, false);
+      generator.getStatic(ourCellConstraintsType, VERT_ALIGN_FIELDS[vAlign], ourCellAlignmentType);
+    }
+
+    AsmCodeGenerator.pushPropValue(generator, Insets.class.getName(), cc.insets);
+
+    generator.invokeConstructor(ourCellConstraintsType, ourCellConstraintsConstructor);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutUtils.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutUtils.java
new file mode 100644
index 0000000..64099e9
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/FormLayoutUtils.java
@@ -0,0 +1,70 @@
+/*
+ * 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 25.07.2006
+ * Time: 18:27:54
+ */
+package com.intellij.uiDesigner.compiler;
+
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.layout.FormSpec;
+
+public class FormLayoutUtils {
+  private FormLayoutUtils() {
+  }
+
+  public static String getEncodedRowSpecs(final FormLayout formLayout) {
+    StringBuffer result = new StringBuffer();
+    for(int i=1; i<=formLayout.getRowCount(); i++) {
+      if (result.length() > 0) {
+        result.append(",");
+      }
+      result.append(getEncodedSpec(formLayout.getRowSpec(i)));
+    }
+    return result.toString();
+  }
+
+  public static String getEncodedColumnSpecs(final FormLayout formLayout) {
+    StringBuffer result = new StringBuffer();
+    for(int i=1; i<=formLayout.getColumnCount(); i++) {
+      if (result.length() > 0) {
+        result.append(",");
+      }
+      result.append(getEncodedSpec(formLayout.getColumnSpec(i)));
+    }
+    return result.toString();
+  }
+
+  public static String getEncodedSpec(final FormSpec formSpec) {
+    String result = formSpec.toString();
+    while(true) {
+      int pos = result.indexOf("dluX");
+      if (pos < 0) {
+        pos = result.indexOf("dluY");
+      }
+      if (pos < 0) {
+        break;
+      }
+      result = result.substring(0, pos+3) + result.substring(pos+4);
+    }
+
+
+    return result;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagConverter.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagConverter.java
new file mode 100644
index 0000000..6a971ff
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagConverter.java
@@ -0,0 +1,323 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.core.AbstractLayout;
+import com.intellij.uiDesigner.core.Util;
+import com.intellij.uiDesigner.lw.*;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.Map;
+
+/**
+ * @author yole
+ */
+public class GridBagConverter {
+  private final Insets myInsets;
+  private int myHGap;
+  private int myVGap;
+  private boolean mySameSizeHorz;
+  private boolean mySameSizeVert;
+  private final ArrayList myComponents = new ArrayList();
+  private final ArrayList myConstraints = new ArrayList();
+  private int myLastRow = -1;
+  private int myLastCol = -1;
+
+  public GridBagConverter() {
+    myInsets = new Insets(0, 0, 0, 0);
+  }
+
+  public GridBagConverter(final Insets insets, final int hgap, final int vgap, final boolean sameSizeHorz, final boolean sameSizeVert) {
+    myInsets = insets;
+    myHGap = hgap;
+    myVGap = vgap;
+    mySameSizeHorz = sameSizeHorz;
+    mySameSizeVert = sameSizeVert;
+  }
+
+  public void addComponent(final JComponent component, final GridConstraints constraints) {
+    myComponents.add(component);
+    myConstraints.add(constraints);
+  }
+
+  public static void prepareConstraints(final LwContainer container, final Map idToConstraintsMap) {
+    GridLayoutManager gridLayout = (GridLayoutManager) container.getLayout();
+    GridBagConverter converter = new GridBagConverter(gridLayout.getMargin(),
+                                                      getGap(container, true),
+                                                      getGap(container, false),
+                                                      gridLayout.isSameSizeHorizontally(),
+                                                      gridLayout.isSameSizeVertically());
+    for(int i=0; i<container.getComponentCount(); i++) {
+      final LwComponent component = (LwComponent)container.getComponent(i);
+      if (component instanceof LwHSpacer || component instanceof LwVSpacer) {
+        GridConstraints constraints = component.getConstraints().store();
+        constraints.setHSizePolicy(constraints.getHSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
+        constraints.setVSizePolicy(constraints.getVSizePolicy() & ~GridConstraints.SIZEPOLICY_WANT_GROW);
+        converter.addComponent(null, constraints);
+      }
+      else {
+        converter.addComponent(null, component.getConstraints());
+      }
+    }
+    Result[] results = converter.convert();
+    int componentIndex = 0;
+    for(int i=0; i<results.length; i++) {
+      if (!results [i].isFillerPanel) {
+        final LwComponent component = (LwComponent)container.getComponent(componentIndex++);
+        idToConstraintsMap.put(component.getId(), results [i]);
+      }
+      // else generateFillerPanel(generator, componentLocal, results [i]);
+    }
+  }
+
+  private static int getGap(LwContainer container, final boolean horizontal) {
+    while(container != null) {
+      final LayoutManager layout = container.getLayout();
+      if (layout instanceof AbstractLayout) {
+        AbstractLayout aLayout = (AbstractLayout) layout;
+        final int gap = horizontal ? aLayout.getHGap() : aLayout.getVGap();
+        if (gap >= 0) {
+          return gap;
+        }
+      }
+      container = container.getParent();
+    }
+    return horizontal ? AbstractLayout.DEFAULT_HGAP : AbstractLayout.DEFAULT_VGAP;
+  }
+
+  public static class Result {
+    public JComponent component;
+    public boolean isFillerPanel;
+    public GridBagConstraints constraints;
+    public Dimension preferredSize;
+    public Dimension minimumSize;
+    public Dimension maximumSize;
+
+    public Result(final JComponent component) {
+      this.component = component;
+      constraints = new GridBagConstraints();
+    }
+  }
+
+  public Result[] convert() {
+    ArrayList results = new ArrayList();
+    for(int i=0; i<myComponents.size(); i++) {
+      results.add(convert((JComponent) myComponents.get(i), (GridConstraints) myConstraints.get(i)));
+    }
+    //addFillerPanels(results);
+    final Result[] resultArray = (Result[])results.toArray(new Result[results.size()]);
+    if (myHGap > 0 || myVGap > 0) {
+      applyGaps(resultArray);
+    }
+    if (mySameSizeHorz) {
+      makeSameSizes(resultArray, true);
+    }
+    if (mySameSizeVert) {
+      makeSameSizes(resultArray, false);
+    }
+
+    return resultArray;
+  }
+
+  private void applyGaps(final Result[] resultArray) {
+    int leftGap = myHGap/2;
+    int rightGap = myHGap - myHGap/2;
+    int topGap = myVGap / 2;
+    int bottomGap = myVGap - myVGap/2;
+    for(int i=0; i<resultArray.length; i++) {
+      Result result = resultArray [i];
+      if (result.constraints.gridx > 0) {
+        result.constraints.insets.left += leftGap;
+      }
+      if (result.constraints.gridx + result.constraints.gridwidth-1 < myLastCol) {
+        result.constraints.insets.right += rightGap;
+      }
+      if (result.constraints.gridy > 0) {
+        result.constraints.insets.top += topGap;
+      }
+      if (result.constraints.gridy + result.constraints.gridheight-1 < myLastRow) {
+        result.constraints.insets.bottom += bottomGap;
+      }
+    }
+  }
+
+  private static void makeSameSizes(final Result[] resultArray, boolean horizontal) {
+    int minimum = -1;
+    int preferred = -1;
+    for(int i=0; i<resultArray.length; i++) {
+      Result result = resultArray [i];
+      Dimension minSize = result.minimumSize != null || result.component == null
+                          ? result.minimumSize
+                          : result.component.getMinimumSize();
+      Dimension prefSize = result.preferredSize != null || result.component == null
+                           ? result.preferredSize
+                           : result.component.getPreferredSize();
+      if (minSize != null) {
+        minimum = Math.max(minimum, horizontal ? minSize.width : minSize.height);
+      }
+      if (prefSize != null) {
+        preferred = Math.max(preferred, horizontal ? prefSize.width : prefSize.height);
+      }
+    }
+
+    if (minimum >= 0 || preferred >= 0) {
+      for(int i=0; i<resultArray.length; i++) {
+        Result result = resultArray [i];
+
+        if ((result.minimumSize != null || result.component != null) && minimum >= 0) {
+          if (result.minimumSize == null) {
+            result.minimumSize = result.component.getMinimumSize();
+          }
+          if (horizontal) {
+            result.minimumSize.width = minimum;
+          }
+          else {
+            result.minimumSize.height = minimum;
+          }
+        }
+
+        if ((result.preferredSize != null || result.component != null) && preferred >= 0) {
+          if (result.preferredSize == null) {
+            result.preferredSize = result.component.getPreferredSize();
+          }
+          if (horizontal) {
+            result.preferredSize.width = preferred;
+          }
+          else {
+            result.preferredSize.height = preferred;
+          }
+        }
+      }
+    }
+  }
+
+  private Result convert(final JComponent component, final GridConstraints constraints) {
+    final Result result = new Result(component);
+
+    int endRow = constraints.getRow() + constraints.getRowSpan()-1;
+    myLastRow = Math.max(myLastRow, endRow);
+    int endCol = constraints.getColumn() + constraints.getColSpan()-1;
+    myLastCol = Math.max(myLastCol, endCol);
+
+    int indent = Util.DEFAULT_INDENT * constraints.getIndent();
+
+    constraintsToGridBag(constraints, result.constraints);
+    result.constraints.weightx = getWeight(constraints, true);
+    result.constraints.weighty = getWeight(constraints, false);
+    result.constraints.insets = new Insets(myInsets.top, myInsets.left + indent, myInsets.bottom, myInsets.right);
+
+    Dimension minSize = constraints.myMinimumSize;
+    if (component != null && minSize.width <= 0 && minSize.height <= 0) {
+      minSize = component.getMinimumSize();
+    }
+
+    if ((constraints.getHSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
+      minSize.width = constraints.myPreferredSize.width > 0 || component == null
+                      ? constraints.myPreferredSize.width
+                      : component.getPreferredSize().width;
+    }
+    if ((constraints.getVSizePolicy() & GridConstraints.SIZEPOLICY_CAN_SHRINK) == 0) {
+      minSize.height = constraints.myPreferredSize.height > 0 || component == null
+                       ? constraints.myPreferredSize.height
+                       : component.getPreferredSize().height;
+    }
+
+    if (minSize.width != -1 || minSize.height != -1) {
+      result.minimumSize = minSize;
+    }
+
+    if (constraints.myPreferredSize.width > 0 && constraints.myPreferredSize.height > 0) {
+      result.preferredSize = constraints.myPreferredSize;
+    }
+    if (constraints.myMaximumSize.width > 0 && constraints.myMaximumSize.height > 0) {
+      result.maximumSize = constraints.myMaximumSize;
+    }
+
+    return result;
+  }
+
+  public static GridBagConstraints getGridBagConstraints(IComponent component) {
+    final GridBagConstraints gbc;
+    if (component.getCustomLayoutConstraints() instanceof GridBagConstraints) {
+      gbc = (GridBagConstraints) component.getCustomLayoutConstraints();
+    }
+    else {
+      gbc = new GridBagConstraints();
+    }
+    constraintsToGridBag(component.getConstraints(), gbc);
+    return gbc;
+  }
+
+  public static void constraintsToGridBag(final GridConstraints constraints, final GridBagConstraints result) {
+    result.gridx = constraints.getColumn();
+    result.gridy = constraints.getRow();
+    result.gridwidth = constraints.getColSpan();
+    result.gridheight = constraints.getRowSpan();
+    switch(constraints.getFill()) {
+      case GridConstraints.FILL_HORIZONTAL: result.fill = GridBagConstraints.HORIZONTAL; break;
+      case GridConstraints.FILL_VERTICAL:   result.fill = GridBagConstraints.VERTICAL; break;
+      case GridConstraints.FILL_BOTH:       result.fill = GridBagConstraints.BOTH; break;
+      default:                              result.fill = GridBagConstraints.NONE; break;
+    }
+    switch(constraints.getAnchor()) {
+      case GridConstraints.ANCHOR_NORTHWEST: result.anchor = GridBagConstraints.NORTHWEST; break;
+      case GridConstraints.ANCHOR_NORTH:     result.anchor = GridBagConstraints.NORTH; break;
+      case GridConstraints.ANCHOR_NORTHEAST: result.anchor = GridBagConstraints.NORTHEAST; break;
+      case GridConstraints.ANCHOR_EAST:      result.anchor = GridBagConstraints.EAST; break;
+      case GridConstraints.ANCHOR_SOUTHEAST: result.anchor = GridBagConstraints.SOUTHEAST; break;
+      case GridConstraints.ANCHOR_SOUTH:     result.anchor = GridBagConstraints.SOUTH; break;
+      case GridConstraints.ANCHOR_SOUTHWEST: result.anchor = GridBagConstraints.SOUTHWEST; break;
+      case GridConstraints.ANCHOR_WEST:      result.anchor = GridBagConstraints.WEST; break;
+    }
+  }
+
+  private double getWeight(final GridConstraints constraints, final boolean horizontal) {
+    int policy = horizontal ? constraints.getHSizePolicy() : constraints.getVSizePolicy();
+    if ((policy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
+      return 1.0;
+    }
+    boolean canGrow = ((policy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0);
+    for (Iterator iterator = myConstraints.iterator(); iterator.hasNext();) {
+      GridConstraints otherConstraints = (GridConstraints)iterator.next();
+
+      if (!constraintsIntersect(horizontal, constraints, otherConstraints)) {
+        int otherPolicy = horizontal ? otherConstraints.getHSizePolicy() : otherConstraints.getVSizePolicy();
+        if ((otherPolicy & GridConstraints.SIZEPOLICY_WANT_GROW) != 0) {
+          return 0.0;
+        }
+        if (!canGrow && ((otherPolicy & GridConstraints.SIZEPOLICY_CAN_GROW) != 0)) {
+          return 0.0;
+        }
+      }
+    }
+    return 1.0;
+  }
+
+  private boolean constraintsIntersect(final boolean horizontal,
+                                       final GridConstraints constraints,
+                                       final GridConstraints otherConstraints) {
+    int start = constraints.getCell(!horizontal);
+    int end = start + constraints.getSpan(!horizontal) - 1;
+    int otherStart = otherConstraints.getCell(!horizontal);
+    int otherEnd = otherStart + otherConstraints.getSpan(!horizontal) - 1;
+    return start <= otherEnd && otherStart <= end;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java
new file mode 100644
index 0000000..711d2c4
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridBagLayoutCodeGenerator.java
@@ -0,0 +1,166 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.core.Spacer;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class GridBagLayoutCodeGenerator extends LayoutCodeGenerator {
+  private static final Type ourGridBagLayoutType = Type.getType(GridBagLayout.class);
+  private static final Type ourGridBagConstraintsType = Type.getType(GridBagConstraints.class);
+  private static final Method ourDefaultConstructor = Method.getMethod("void <init> ()");
+
+  private static final Type myPanelType = Type.getType(JPanel.class);
+
+  public String mapComponentClass(final String componentClassName) {
+    if (componentClassName.equals(Spacer.class.getName())) {
+      return JPanel.class.getName();
+    }
+    return super.mapComponentClass(componentClassName);
+  }
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+    generator.loadLocal(componentLocal);
+
+    generator.newInstance(ourGridBagLayoutType);
+    generator.dup();
+    generator.invokeConstructor(ourGridBagLayoutType, ourDefaultConstructor);
+
+    generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
+  }
+
+  private void generateFillerPanel(final GeneratorAdapter generator, final int parentLocal, final GridBagConverter.Result result) {
+    int panelLocal = generator.newLocal(myPanelType);
+
+    generator.newInstance(myPanelType);
+    generator.dup();
+    generator.invokeConstructor(myPanelType, ourDefaultConstructor);
+    generator.storeLocal(panelLocal);
+
+    generateConversionResult(generator, result, panelLocal, parentLocal);
+
+  }
+
+  public void generateComponentLayout(final LwComponent component,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    GridBagConstraints gbc;
+    if (component.getCustomLayoutConstraints() instanceof GridBagConstraints) {
+      gbc = (GridBagConstraints) component.getCustomLayoutConstraints();
+    }
+    else {
+      gbc = new GridBagConstraints();
+    }
+
+    GridBagConverter.constraintsToGridBag(component.getConstraints(), gbc);
+
+    generateGridBagConstraints(generator, gbc, componentLocal, parentLocal);
+  }
+
+  private static void generateConversionResult(final GeneratorAdapter generator, final GridBagConverter.Result result,
+                                               final int componentLocal, final int parentLocal) {
+    checkSetSize(generator, componentLocal, "setMinimumSize", result.minimumSize);
+    checkSetSize(generator, componentLocal, "setPreferredSize", result.preferredSize);
+    checkSetSize(generator, componentLocal, "setMaximumSize", result.maximumSize);
+
+    generateGridBagConstraints(generator, result.constraints, componentLocal, parentLocal);
+  }
+
+  private static void generateGridBagConstraints(final GeneratorAdapter generator, GridBagConstraints constraints, final int componentLocal,
+                                                 final int parentLocal) {
+    int gbcLocal = generator.newLocal(ourGridBagConstraintsType);
+
+    generator.newInstance(ourGridBagConstraintsType);
+    generator.dup();
+    generator.invokeConstructor(ourGridBagConstraintsType, ourDefaultConstructor);
+    generator.storeLocal(gbcLocal);
+
+    GridBagConstraints defaults = new GridBagConstraints();
+    if (defaults.gridx != constraints.gridx) {
+      setIntField(generator, gbcLocal, "gridx", constraints.gridx);
+    }
+    if (defaults.gridy != constraints.gridy) {
+      setIntField(generator, gbcLocal, "gridy", constraints.gridy);
+    }
+    if (defaults.gridwidth != constraints.gridwidth) {
+      setIntField(generator, gbcLocal, "gridwidth", constraints.gridwidth);
+    }
+    if (defaults.gridheight != constraints.gridheight) {
+      setIntField(generator, gbcLocal, "gridheight", constraints.gridheight);
+    }
+    if (defaults.weightx != constraints.weightx) {
+      setDoubleField(generator, gbcLocal, "weightx", constraints.weightx);
+    }
+    if (defaults.weighty != constraints.weighty) {
+      setDoubleField(generator, gbcLocal, "weighty", constraints.weighty);
+    }
+    if (defaults.anchor != constraints.anchor) {
+      setIntField(generator, gbcLocal, "anchor", constraints.anchor);
+    }
+    if (defaults.fill != constraints.fill) {
+      setIntField(generator, gbcLocal, "fill", constraints.fill);
+    }
+    if (defaults.ipadx != constraints.ipadx) {
+      setIntField(generator, gbcLocal, "ipadx", constraints.ipadx);
+    }
+    if (defaults.ipady != constraints.ipady) {
+      setIntField(generator, gbcLocal, "ipady", constraints.ipady);
+    }
+    if (!defaults.insets.equals(constraints.insets)) {
+      generator.loadLocal(gbcLocal);
+      AsmCodeGenerator.pushPropValue(generator, Insets.class.getName(), constraints.insets);
+      generator.putField(ourGridBagConstraintsType, "insets", Type.getType(Insets.class));
+    }
+
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    generator.loadLocal(gbcLocal);
+
+    generator.invokeVirtual(ourContainerType, ourAddMethod);
+  }
+
+  private static void checkSetSize(final GeneratorAdapter generator, final int componentLocal, final String methodName, final Dimension dimension) {
+    if (dimension != null) {
+      generator.loadLocal(componentLocal);
+      AsmCodeGenerator.pushPropValue(generator, "java.awt.Dimension", dimension);
+      generator.invokeVirtual(Type.getType(Component.class),
+                              new Method(methodName, Type.VOID_TYPE, new Type[] { Type.getType(Dimension.class) }));
+    }
+  }
+
+  private static void setIntField(final GeneratorAdapter generator, final int local, final String fieldName, final int value) {
+    generator.loadLocal(local);
+    generator.push(value);
+    generator.putField(ourGridBagConstraintsType, fieldName, Type.INT_TYPE);
+  }
+
+  private static void setDoubleField(final GeneratorAdapter generator, final int local, final String fieldName, final double value) {
+    generator.loadLocal(local);
+    generator.push(value);
+    generator.putField(ourGridBagConstraintsType, fieldName, Type.DOUBLE_TYPE);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.java
new file mode 100644
index 0000000..954f166
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/GridLayoutCodeGenerator.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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+/**
+ * @author yole
+ * @noinspection HardCodedStringLiteral
+ */
+public class GridLayoutCodeGenerator extends LayoutCodeGenerator {
+  private static final Method myInitConstraintsMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension)");
+  private static final Method myInitConstraintsIndentMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension,int)");
+  private static final Method myInitConstraintsIndentParentMethod = Method.getMethod("void <init> (int,int,int,int,int,int,int,int,java.awt.Dimension,java.awt.Dimension,java.awt.Dimension,int,boolean)");
+  private static final Method ourGridLayoutManagerConstructor = Method.getMethod("void <init> (int,int,java.awt.Insets,int,int,boolean,boolean)");
+  private static final Type myGridLayoutManagerType = Type.getType(GridLayoutManager.class);
+  private static final Type myGridConstraintsType = Type.getType(GridConstraints.class);
+
+  public static GridLayoutCodeGenerator INSTANCE = new GridLayoutCodeGenerator();
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+    if (lwContainer.isGrid()) {
+      // arg 0: object
+      generator.loadLocal(componentLocal);
+
+      // arg 1: layout
+      final GridLayoutManager layout = (GridLayoutManager)lwContainer.getLayout();
+
+      generator.newInstance(myGridLayoutManagerType);
+      generator.dup();
+      generator.push(layout.getRowCount());
+      generator.push(layout.getColumnCount());
+      AsmCodeGenerator.pushPropValue(generator, "java.awt.Insets", layout.getMargin());
+      generator.push(layout.getHGap());
+      generator.push(layout.getVGap());
+      generator.push(layout.isSameSizeHorizontally());
+      generator.push(layout.isSameSizeVertically());
+      generator.invokeConstructor(myGridLayoutManagerType, ourGridLayoutManagerConstructor);
+
+      generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
+    }
+  }
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    addNewGridConstraints(generator, lwComponent);
+    generator.invokeVirtual(ourContainerType, ourAddMethod);
+  }
+
+  private static void addNewGridConstraints(final GeneratorAdapter generator, final LwComponent lwComponent) {
+    final GridConstraints constraints = lwComponent.getConstraints();
+
+    generator.newInstance(myGridConstraintsType);
+    generator.dup();
+    generator.push(constraints.getRow());
+    generator.push(constraints.getColumn());
+    generator.push(constraints.getRowSpan());
+    generator.push(constraints.getColSpan());
+    generator.push(constraints.getAnchor());
+    generator.push(constraints.getFill());
+    generator.push(constraints.getHSizePolicy());
+    generator.push(constraints.getVSizePolicy());
+    newDimensionOrNull(generator, constraints.myMinimumSize);
+    newDimensionOrNull(generator, constraints.myPreferredSize);
+    newDimensionOrNull(generator, constraints.myMaximumSize);
+
+    if (constraints.isUseParentLayout()) {
+      generator.push(constraints.getIndent());
+      generator.push(constraints.isUseParentLayout());
+      generator.invokeConstructor(myGridConstraintsType, myInitConstraintsIndentParentMethod);
+    }
+    else if (constraints.getIndent() != 0) {
+      generator.push(constraints.getIndent());
+      generator.invokeConstructor(myGridConstraintsType, myInitConstraintsIndentMethod);
+    }
+    else {
+      generator.invokeConstructor(myGridConstraintsType, myInitConstraintsMethod);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java
new file mode 100644
index 0000000..c435704
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/IconPropertyCodeGenerator.java
@@ -0,0 +1,48 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.IconDescriptor;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class IconPropertyCodeGenerator extends PropertyCodeGenerator {
+  private static final Type ourImageIconType = Type.getType(ImageIcon.class);
+  private static final Method ourInitMethod = Method.getMethod("void <init>(java.net.URL)");
+  private static final Method ourGetResourceMethod = Method.getMethod("java.net.URL getResource(java.lang.String)");
+  private static final Method ourGetClassMethod = new Method("getClass", "()Ljava/lang/Class;");
+  private static final Type ourObjectType = Type.getType(Object.class);
+  private static final Type ourClassType = Type.getType(Class.class);
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    IconDescriptor descriptor = (IconDescriptor) value;
+    generator.newInstance(ourImageIconType);
+    generator.dup();
+
+    generator.loadThis();
+    generator.invokeVirtual(ourObjectType, ourGetClassMethod);
+    generator.push("/" + descriptor.getIconPath());
+    generator.invokeVirtual(ourClassType, ourGetResourceMethod);
+
+    generator.invokeConstructor(ourImageIconType, ourInitMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.java
new file mode 100644
index 0000000..fb516ca
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/InsetsPropertyCodeGenerator.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.uiDesigner.compiler;
+
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class InsetsPropertyCodeGenerator extends PropertyCodeGenerator {
+  private final Type myInsetsType = Type.getType(Insets.class);
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    final Insets insets = (Insets)value;
+    generator.newInstance(myInsetsType);
+    generator.dup();
+    generator.push(insets.top);
+    generator.push(insets.left);
+    generator.push(insets.bottom);
+    generator.push(insets.right);
+    generator.invokeConstructor(myInsetsType, Method.getMethod("void <init>(int,int,int,int)"));
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java
new file mode 100644
index 0000000..f5d2594
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/LayoutCodeGenerator.java
@@ -0,0 +1,55 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ * @noinspection HardCodedStringLiteral
+ */
+public abstract class LayoutCodeGenerator {
+  protected static final Method ourSetLayoutMethod = Method.getMethod("void setLayout(java.awt.LayoutManager)");
+  protected static final Type ourContainerType = Type.getType(Container.class);
+  protected static final Method ourAddMethod = Method.getMethod("void add(java.awt.Component,java.lang.Object)");
+  protected static final Method ourAddNoConstraintMethod = Method.getMethod("java.awt.Component add(java.awt.Component)");
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+  }
+
+  public abstract void generateComponentLayout(final LwComponent lwComponent, final GeneratorAdapter generator, final int componentLocal,
+                                               final int parentLocal);
+
+  protected static void newDimensionOrNull(final GeneratorAdapter generator, final Dimension dimension) {
+    if (dimension.width == -1 && dimension.height == -1) {
+      generator.visitInsn(Opcodes.ACONST_NULL);
+    }
+    else {
+      AsmCodeGenerator.pushPropValue(generator, "java.awt.Dimension", dimension);
+    }
+  }
+
+  public String mapComponentClass(final String componentClassName) {
+    return componentClassName;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.java
new file mode 100644
index 0000000..93ed130
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ListModelPropertyCodeGenerator.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.uiDesigner.compiler;
+
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+/**
+ * @author yole
+ */
+public class ListModelPropertyCodeGenerator extends PropertyCodeGenerator {
+  private final Type myListModelType;
+  private static final Method ourInitMethod = Method.getMethod("void <init>()");
+  private static final Method ourAddElementMethod = Method.getMethod("void addElement(java.lang.Object)");
+
+  public ListModelPropertyCodeGenerator(final Class aClass) {
+    myListModelType = Type.getType(aClass);
+  }
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    String[] items = (String[]) value;
+    int listModelLocal = generator.newLocal(myListModelType);
+
+    generator.newInstance(myListModelType);
+    generator.dup();
+    generator.invokeConstructor(myListModelType, ourInitMethod);
+    generator.storeLocal(listModelLocal);
+
+    for(int i=0; i<items.length; i++) {
+      generator.loadLocal(listModelLocal);
+      generator.push(items [i]);
+      generator.invokeVirtual(myListModelType, ourAddElementMethod);
+    }
+
+    generator.loadLocal(listModelLocal);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/NestedFormLoader.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/NestedFormLoader.java
new file mode 100644
index 0000000..f3f0c23
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/NestedFormLoader.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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwRootContainer;
+
+/**
+ * @author yole
+ */
+public interface NestedFormLoader {
+  LwRootContainer loadForm(String formFileName) throws Exception;
+  String getClassToBindName(LwRootContainer container);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java
new file mode 100644
index 0000000..b3c1aeb
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/PropertyCodeGenerator.java
@@ -0,0 +1,43 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+
+import java.io.IOException;
+
+/**
+ * @author yole
+ */
+public abstract class PropertyCodeGenerator {
+  public abstract void generatePushValue(final GeneratorAdapter generator, final Object value);
+
+  public boolean generateCustomSetValue(final LwComponent lwComponent,
+                                        final InstrumentationClassFinder.PseudoClass componentClass, final LwIntrospectedProperty property,
+                                        final GeneratorAdapter generator,
+                                        final int componentLocal, final String formClassName) throws IOException, ClassNotFoundException {
+    return false;
+  }
+
+  public void generateClassStart(AsmCodeGenerator.FormClassVisitor visitor, final String name, final InstrumentationClassFinder classFinder) {
+  }
+
+  public void generateClassEnd(AsmCodeGenerator.FormClassVisitor visitor) {
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java
new file mode 100644
index 0000000..fb86b08
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RectanglePropertyCodeGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class RectanglePropertyCodeGenerator extends PropertyCodeGenerator {
+  private static final Type myRectangleType = Type.getType(Rectangle.class);
+  private static final Method myInitMethod = Method.getMethod("void <init>(int,int,int,int)");
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    final Rectangle rc = (Rectangle) value;
+    generator.newInstance(myRectangleType);
+    generator.dup();
+    generator.push(rc.x);
+    generator.push(rc.y);
+    generator.push(rc.width);
+    generator.push(rc.height);
+    generator.invokeConstructor(myRectangleType, myInitMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RecursiveFormNestingException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RecursiveFormNestingException.java
new file mode 100644
index 0000000..49450e0
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/RecursiveFormNestingException.java
@@ -0,0 +1,26 @@
+/*
+ * 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.uiDesigner.compiler;
+
+/**
+ * @author yole
+ */
+public class RecursiveFormNestingException extends UIDesignerException{
+  public RecursiveFormNestingException() {
+    super("Recursive form nesting is not allowed");
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java
new file mode 100644
index 0000000..6872500
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ScrollPaneLayoutCodeGenerator.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class ScrollPaneLayoutCodeGenerator extends LayoutCodeGenerator {
+  private final Type myScrollPaneType = Type.getType(JScrollPane.class);
+  private final Method mySetViewportViewMethod = Method.getMethod("void setViewportView(java.awt.Component)");
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    generator.invokeVirtual(myScrollPaneType, mySetViewportViewMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java
new file mode 100644
index 0000000..5836b6c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SimpleLayoutCodeGenerator.java
@@ -0,0 +1,60 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwContainer;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+/**
+ * Layout code generator shared between BorderLayout and CardLayout.
+ *
+ * @author yole
+ */
+public class SimpleLayoutCodeGenerator extends LayoutCodeGenerator {
+  protected final Type myLayoutType;
+  private static final Method ourConstructor = Method.getMethod("void <init>(int,int)");
+
+  public SimpleLayoutCodeGenerator(final Type layoutType) {
+    myLayoutType = layoutType;
+  }
+
+  public void generateContainerLayout(final LwContainer lwContainer, final GeneratorAdapter generator, final int componentLocal) {
+    generator.loadLocal(componentLocal);
+
+    generator.newInstance(myLayoutType);
+    generator.dup();
+    generator.push(Utils.getHGap(lwContainer.getLayout()));
+    generator.push(Utils.getVGap(lwContainer.getLayout()));
+
+    generator.invokeConstructor(myLayoutType, ourConstructor);
+
+    generator.invokeVirtual(ourContainerType, ourSetLayoutMethod);
+  }
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    generator.push((String) lwComponent.getCustomLayoutConstraints());
+    generator.invokeVirtual(ourContainerType, ourAddMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java
new file mode 100644
index 0000000..28533f4
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/SplitPaneLayoutCodeGenerator.java
@@ -0,0 +1,47 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwSplitPane;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class SplitPaneLayoutCodeGenerator extends LayoutCodeGenerator {
+  private final Type mySplitPaneType = Type.getType(JSplitPane.class);
+  private final Method mySetLeftMethod = Method.getMethod("void setLeftComponent(java.awt.Component)");
+  private final Method mySetRightMethod = Method.getMethod("void setRightComponent(java.awt.Component)");
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    if (LwSplitPane.POSITION_LEFT.equals(lwComponent.getCustomLayoutConstraints())) {
+      generator.invokeVirtual(mySplitPaneType, mySetLeftMethod);
+    }
+    else {
+      generator.invokeVirtual(mySplitPaneType, mySetRightMethod);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java
new file mode 100644
index 0000000..4438fd0
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/StringPropertyCodeGenerator.java
@@ -0,0 +1,244 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.uiDesigner.core.SupportCode;
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwIntrospectedProperty;
+import com.intellij.uiDesigner.lw.StringDescriptor;
+import org.jetbrains.asm4.Label;
+import org.jetbrains.asm4.MethodVisitor;
+import org.jetbrains.asm4.Opcodes;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.ResourceBundle;
+import java.util.Set;
+
+/**
+ * @author yole
+ */
+public class StringPropertyCodeGenerator extends PropertyCodeGenerator implements Opcodes {
+  private static final Type myResourceBundleType = Type.getType(ResourceBundle.class);
+  private final Method myGetBundleMethod = Method.getMethod("java.util.ResourceBundle getBundle(java.lang.String)");
+  private final Method myGetStringMethod = Method.getMethod("java.lang.String getString(java.lang.String)");
+  private static final Method myLoadLabelTextMethod = new Method(AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD, Type.VOID_TYPE,
+                                                                 new Type[] { Type.getType(JLabel.class), Type.getType(String.class) } );
+  private static final Method myLoadButtonTextMethod = new Method(AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD, Type.VOID_TYPE,
+                                                                 new Type[] { Type.getType(AbstractButton.class), Type.getType(String.class) } );
+
+  private final Set myClassesRequiringLoadLabelText = new HashSet();
+  private final Set myClassesRequiringLoadButtonText = new HashSet();
+  private boolean myHaveSetDisplayedMnemonicIndex = false;
+
+  public void generateClassStart(AsmCodeGenerator.FormClassVisitor visitor, final String name, final InstrumentationClassFinder classFinder) {
+    myClassesRequiringLoadLabelText.remove(name);
+    myClassesRequiringLoadButtonText.remove(name);
+    try {
+      InstrumentationClassFinder.PseudoClass pseudo = classFinder.loadClass(AbstractButton.class.getName());
+      if (!pseudo.findMethods("getDisplayedMnemonicIndex").isEmpty()) {
+        myHaveSetDisplayedMnemonicIndex = true;
+      }
+    }
+    catch (Exception e) {
+      // ignore
+    }
+  }
+
+  public boolean generateCustomSetValue(final LwComponent lwComponent,
+                                        final InstrumentationClassFinder.PseudoClass componentClass,
+                                        final LwIntrospectedProperty property,
+                                        final GeneratorAdapter generator,
+                                        final int componentLocal,
+                                        final String formClassName) throws IOException, ClassNotFoundException {
+    final InstrumentationClassFinder.PseudoClass abstractButtonClass = componentClass.getFinder().loadClass(AbstractButton.class.getName());
+    final InstrumentationClassFinder.PseudoClass jLabelClass = componentClass.getFinder().loadClass(JLabel.class.getName());
+    if ("text".equals(property.getName()) &&
+        (abstractButtonClass.isAssignableFrom(componentClass) || jLabelClass.isAssignableFrom(componentClass))) {
+      final StringDescriptor propertyValue = (StringDescriptor)lwComponent.getPropertyValue(property);
+      if (propertyValue.getValue() != null) {
+        final SupportCode.TextWithMnemonic textWithMnemonic = SupportCode.parseText(propertyValue.getValue());
+        if (textWithMnemonic.myMnemonicIndex >= 0) {
+          generator.loadLocal(componentLocal);
+          generator.push(textWithMnemonic.myText);
+          generator.invokeVirtual(Type.getType(componentClass.getDescriptor()),
+                                  new Method(property.getWriteMethodName(),
+                                             Type.VOID_TYPE, new Type[] { Type.getType(String.class) } ));
+
+          String setMnemonicMethodName;
+          if (abstractButtonClass.isAssignableFrom(componentClass)) {
+            setMnemonicMethodName = "setMnemonic";
+          }
+          else {
+            setMnemonicMethodName = "setDisplayedMnemonic";
+          }
+
+          generator.loadLocal(componentLocal);
+          generator.push(textWithMnemonic.getMnemonicChar());
+          generator.invokeVirtual(Type.getType(componentClass.getDescriptor()),
+                                  new Method(setMnemonicMethodName,
+                                             Type.VOID_TYPE, new Type[] { Type.CHAR_TYPE } ));
+
+          if (myHaveSetDisplayedMnemonicIndex) {
+            generator.loadLocal(componentLocal);
+            generator.push(textWithMnemonic.myMnemonicIndex);
+            generator.invokeVirtual(Type.getType(componentClass.getDescriptor()),
+                                    new Method("setDisplayedMnemonicIndex",
+                                               Type.VOID_TYPE, new Type[] { Type.INT_TYPE } ));
+          }
+          return true;
+        }
+      }
+      else {
+        Method method;
+        if (abstractButtonClass.isAssignableFrom(componentClass)) {
+          myClassesRequiringLoadButtonText.add(formClassName);
+          method = myLoadButtonTextMethod;
+        }
+        else {
+          myClassesRequiringLoadLabelText.add(formClassName);
+          method = myLoadLabelTextMethod;
+        }
+
+        generator.loadThis();
+        generator.loadLocal(componentLocal);
+        generator.push(propertyValue.getBundleName());
+        generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
+        generator.push(propertyValue.getKey());
+        generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
+        generator.invokeVirtual(Type.getType("L" + formClassName + ";"), method);
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public void generatePushValue(final GeneratorAdapter generator, final Object value) {
+    StringDescriptor descriptor = (StringDescriptor) value;
+    if (descriptor == null) {
+      generator.push((String)null);
+    }
+    else if (descriptor.getValue() !=null) {
+      generator.push(descriptor.getValue());
+    }
+    else {
+      generator.push(descriptor.getBundleName());
+      generator.invokeStatic(myResourceBundleType, myGetBundleMethod);
+      generator.push(descriptor.getKey());
+      generator.invokeVirtual(myResourceBundleType, myGetStringMethod);
+    }
+  }
+
+  public void generateClassEnd(AsmCodeGenerator.FormClassVisitor visitor) {
+    if (myClassesRequiringLoadLabelText.contains(visitor.getClassName())) {
+      generateLoadTextMethod(visitor, AsmCodeGenerator.LOAD_LABEL_TEXT_METHOD, "javax/swing/JLabel", "setDisplayedMnemonic");
+      myClassesRequiringLoadLabelText.remove(visitor.getClassName());
+    }
+    if (myClassesRequiringLoadButtonText.contains(visitor.getClassName())) {
+      generateLoadTextMethod(visitor, AsmCodeGenerator.LOAD_BUTTON_TEXT_METHOD, "javax/swing/AbstractButton", "setMnemonic");
+      myClassesRequiringLoadButtonText.remove(visitor.getClassName());
+    }
+  }
+
+  private void generateLoadTextMethod(final AsmCodeGenerator.FormClassVisitor visitor, final String methodName, final String componentClass,
+                                      final String setMnemonicMethodName) {
+    MethodVisitor mv = visitor.visitNewMethod(ACC_PRIVATE | ACC_SYNTHETIC, methodName, "(L" + componentClass + ";Ljava/lang/String;)V", null, null);
+    mv.visitCode();
+    mv.visitTypeInsn(NEW, "java/lang/StringBuffer");
+    mv.visitInsn(DUP);
+    mv.visitMethodInsn(INVOKESPECIAL, "java/lang/StringBuffer", "<init>", "()V");
+    mv.visitVarInsn(ASTORE, 3);
+    mv.visitInsn(ICONST_0);
+    mv.visitVarInsn(ISTORE, 4);
+    mv.visitInsn(ICONST_0);
+    mv.visitVarInsn(ISTORE, 5);
+    mv.visitInsn(ICONST_M1);
+    mv.visitVarInsn(ISTORE, 6);
+    mv.visitInsn(ICONST_0);
+    mv.visitVarInsn(ISTORE, 7);
+    Label l0 = new Label();
+    mv.visitLabel(l0);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
+    Label l1 = new Label();
+    mv.visitJumpInsn(IF_ICMPGE, l1);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+    mv.visitIntInsn(BIPUSH, 38);
+    Label l2 = new Label();
+    mv.visitJumpInsn(IF_ICMPNE, l2);
+    mv.visitIincInsn(7, 1);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "length", "()I");
+    Label l3 = new Label();
+    mv.visitJumpInsn(IF_ICMPNE, l3);
+    mv.visitJumpInsn(GOTO, l1);
+    mv.visitLabel(l3);
+    mv.visitVarInsn(ILOAD, 4);
+    mv.visitJumpInsn(IFNE, l2);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+    mv.visitIntInsn(BIPUSH, 38);
+    mv.visitJumpInsn(IF_ICMPEQ, l2);
+    mv.visitInsn(ICONST_1);
+    mv.visitVarInsn(ISTORE, 4);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+    mv.visitVarInsn(ISTORE, 5);
+    mv.visitVarInsn(ALOAD, 3);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "length", "()I");
+    mv.visitVarInsn(ISTORE, 6);
+    mv.visitLabel(l2);
+    mv.visitVarInsn(ALOAD, 3);
+    mv.visitVarInsn(ALOAD, 2);
+    mv.visitVarInsn(ILOAD, 7);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/String", "charAt", "(I)C");
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "append", "(C)Ljava/lang/StringBuffer;");
+    mv.visitInsn(POP);
+    mv.visitIincInsn(7, 1);
+    mv.visitJumpInsn(GOTO, l0);
+    mv.visitLabel(l1);
+    mv.visitVarInsn(ALOAD, 1);
+    mv.visitVarInsn(ALOAD, 3);
+    mv.visitMethodInsn(INVOKEVIRTUAL, "java/lang/StringBuffer", "toString", "()Ljava/lang/String;");
+    mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setText", "(Ljava/lang/String;)V");
+    mv.visitVarInsn(ILOAD, 4);
+    Label l4 = new Label();
+    mv.visitJumpInsn(IFEQ, l4);
+    mv.visitVarInsn(ALOAD, 1);
+    mv.visitVarInsn(ILOAD, 5);
+    mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, setMnemonicMethodName, "(C)V");
+    if (myHaveSetDisplayedMnemonicIndex) {
+      mv.visitVarInsn(ALOAD, 1);
+      mv.visitVarInsn(ILOAD, 6);
+      mv.visitMethodInsn(INVOKEVIRTUAL, componentClass, "setDisplayedMnemonicIndex", "(I)V");
+    }
+    mv.visitLabel(l4);
+    mv.visitInsn(RETURN);
+    mv.visitMaxs(3, 8);
+    mv.visitEnd();
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java
new file mode 100644
index 0000000..ee867bf
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/TabbedPaneLayoutCodeGenerator.java
@@ -0,0 +1,74 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import com.intellij.uiDesigner.lw.LwTabbedPane;
+import org.jetbrains.asm4.Type;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class TabbedPaneLayoutCodeGenerator extends LayoutCodeGenerator {
+  private final Type myTabbedPaneType = Type.getType(JTabbedPane.class);
+  private final Method myAddTabMethod = Method.getMethod("void addTab(java.lang.String,javax.swing.Icon,java.awt.Component,java.lang.String)");
+  private final Method mySetDisabledIconAtMethod = Method.getMethod("void setDisabledIconAt(int,javax.swing.Icon)");
+  private final Method mySetEnabledAtMethod = Method.getMethod("void setEnabledAt(int,boolean)");
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    final LwTabbedPane.Constraints tabConstraints = (LwTabbedPane.Constraints)lwComponent.getCustomLayoutConstraints();
+    if (tabConstraints == null){
+      throw new IllegalArgumentException("tab constraints cannot be null: " + lwComponent.getId());
+    }
+    AsmCodeGenerator.pushPropValue(generator, String.class.getName(), tabConstraints.myTitle);
+    if (tabConstraints.myIcon == null) {
+      generator.push((String) null);
+    }
+    else {
+      AsmCodeGenerator.pushPropValue(generator, Icon.class.getName(), tabConstraints.myIcon);
+    }
+    generator.loadLocal(componentLocal);
+    if (tabConstraints.myToolTip == null) {
+      generator.push((String) null);
+    }
+    else {
+      AsmCodeGenerator.pushPropValue(generator, String.class.getName(), tabConstraints.myToolTip);
+    }
+    generator.invokeVirtual(myTabbedPaneType, myAddTabMethod);
+
+    int index = lwComponent.getParent().indexOfComponent(lwComponent);
+    if (tabConstraints.myDisabledIcon != null) {
+      generator.loadLocal(parentLocal);
+      generator.push(index);
+      AsmCodeGenerator.pushPropValue(generator, Icon.class.getName(), tabConstraints.myDisabledIcon);
+      generator.invokeVirtual(myTabbedPaneType, mySetDisabledIconAtMethod);
+    }
+    if (!tabConstraints.myEnabled) {
+      generator.loadLocal(parentLocal);
+      generator.push(index);
+      generator.push(tabConstraints.myEnabled);
+      generator.invokeVirtual(myTabbedPaneType, mySetEnabledAtMethod);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.java
new file mode 100644
index 0000000..b90a778
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/ToolBarLayoutCodeGenerator.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.uiDesigner.compiler;
+
+import com.intellij.uiDesigner.lw.LwComponent;
+import org.jetbrains.asm4.commons.GeneratorAdapter;
+import org.jetbrains.asm4.commons.Method;
+
+/**
+ * @author yole
+ */
+public class ToolBarLayoutCodeGenerator extends LayoutCodeGenerator {
+  private final static Method ourAddMethod = Method.getMethod("java.awt.Component add(java.awt.Component)");
+
+  public void generateComponentLayout(final LwComponent lwComponent,
+                                      final GeneratorAdapter generator,
+                                      final int componentLocal,
+                                      final int parentLocal) {
+    generator.loadLocal(parentLocal);
+    generator.loadLocal(componentLocal);
+    generator.invokeVirtual(ourContainerType, ourAddMethod);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UIDesignerException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UIDesignerException.java
new file mode 100644
index 0000000..4cfff00
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UIDesignerException.java
@@ -0,0 +1,39 @@
+/*
+ * 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.uiDesigner.compiler;
+
+/**
+ * Marker interface for all UI Designer exceptions
+ * @author Eugene Zhuravlev
+ *         Date: 11/5/12
+ */
+public abstract class UIDesignerException extends Exception {
+
+  protected UIDesignerException() {
+  }
+
+  protected UIDesignerException(String message) {
+    super(message);
+  }
+
+  protected UIDesignerException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+  protected UIDesignerException(Throwable cause) {
+    super(cause);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UnexpectedFormElementException.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UnexpectedFormElementException.java
new file mode 100644
index 0000000..d87e549
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/UnexpectedFormElementException.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.uiDesigner.compiler;
+
+/**
+ * @author yole
+ */
+public class UnexpectedFormElementException extends RuntimeException {
+
+  public UnexpectedFormElementException(String message) {
+    super(message);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/Utils.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/Utils.java
new file mode 100644
index 0000000..79fb947
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/compiler/Utils.java
@@ -0,0 +1,367 @@
+/*
+ * 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.uiDesigner.compiler;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.lw.*;
+import org.jdom.Document;
+import org.jdom.input.SAXBuilder;
+import org.xml.sax.Attributes;
+import org.xml.sax.InputSource;
+import org.xml.sax.SAXException;
+import org.xml.sax.helpers.DefaultHandler;
+
+import javax.swing.*;
+import javax.xml.parsers.SAXParser;
+import javax.xml.parsers.SAXParserFactory;
+import java.awt.*;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.StringReader;
+import java.lang.reflect.Constructor;
+import java.lang.reflect.Modifier;
+import java.net.URL;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ *         <p/>
+ *         NOTE: the class must be compilable with JDK 1.3, so any methods and filds introduced in 1.4 or later must not be used
+ */
+public final class Utils {
+  public static final String FORM_NAMESPACE = "http://www.intellij.com/uidesigner/form/";
+  private static final SAXParser SAX_PARSER = createParser();
+
+  private Utils() {
+  }
+
+  private static SAXParser createParser() {
+    try {
+      return SAXParserFactory.newInstance().newSAXParser();
+    }
+    catch (Exception e) {
+      return null;
+    }
+  }
+
+  /**
+   * @param provider if null, no classes loaded and no properties read
+   */
+  public static LwRootContainer getRootContainer(final String formFileContent, final PropertiesProvider provider) throws Exception {
+    if (formFileContent.indexOf(FORM_NAMESPACE) == -1) {
+      throw new AlienFormFileException();
+    }
+
+    final Document document = new SAXBuilder().build(new StringReader(formFileContent), "UTF-8");
+
+    return getRootContainerFromDocument(document, provider);
+  }
+
+  /**
+   * Get root from the url
+   *
+   * @param formFile the document URL
+   * @param provider the provider
+   * @return the root container
+   * @throws Exception if there is a problem with parsing DOM
+   */
+  public static LwRootContainer getRootContainer(final URL formFile, final PropertiesProvider provider) throws Exception {
+    final Document document = new SAXBuilder().build(formFile);
+    return getRootContainerFromDocument(document, provider);
+  }
+
+
+  /**
+   * Get root from the document
+   *
+   * @param document the parsed document
+   * @param provider the provider
+   * @return the root container
+   * @throws Exception if there is a problem with parsing DOM
+   */
+  private static LwRootContainer getRootContainerFromDocument(Document document, PropertiesProvider provider) throws Exception {
+    final LwRootContainer root = new LwRootContainer();
+    root.read(document.getRootElement(), provider);
+    return root;
+  }
+
+  public static LwRootContainer getRootContainer(final InputStream stream, final PropertiesProvider provider) throws Exception {
+    final Document document = new SAXBuilder().build(stream, "UTF-8");
+
+    return getRootContainerFromDocument(document, provider);
+  }
+
+  public synchronized static String getBoundClassName(final String formFileContent) throws Exception {
+    if (formFileContent.indexOf(FORM_NAMESPACE) == -1) {
+      throw new AlienFormFileException();
+    }
+
+    final String[] className = new String[]{null};
+    try {
+      SAX_PARSER.parse(new InputSource(new StringReader(formFileContent)), new DefaultHandler() {
+        public void startElement(String uri, String localName, String qName, Attributes attributes) throws SAXException {
+          if ("form".equals(qName)) {
+            className[0] = attributes.getValue("", "bind-to-class");
+            throw new SAXException("stop parsing");
+          }
+        }
+      });
+    }
+    catch (Exception e) {
+      // Do nothing.
+    }
+
+    return className[0];
+  }
+
+  /**
+   * Validates that specified class represents {@link javax.swing.JComponent} with
+   * empty constructor.
+   *
+   * @return descriptive human readable error message or <code>null</code> if
+   *         no errors were detected.
+   */
+    public static String validateJComponentClass(final ClassLoader loader, final String className, final boolean validateConstructor) {
+        if (loader == null) {
+      throw new IllegalArgumentException("loader cannot be null");
+    }
+    if (className == null) {
+      throw new IllegalArgumentException("className cannot be null");
+    }
+
+    // These classes are not visible for passed class loader!
+    if ("com.intellij.uiDesigner.HSpacer".equals(className) || "com.intellij.uiDesigner.VSpacer".equals(className)) {
+      return null;
+    }
+
+        final Class aClass;
+    try {
+            aClass = Class.forName(className, false, loader);
+    }
+    catch (final ClassNotFoundException exc) {
+      return "Class \"" + className + "\"not found";
+    }
+    catch (NoClassDefFoundError exc) {
+      return "Cannot load class " + className + ": " + exc.getMessage();
+    }
+    catch (ExceptionInInitializerError exc) {
+      return "Cannot initialize class " + className + ": " + exc.getMessage();
+    }
+    catch (UnsupportedClassVersionError exc) {
+      return "Unsupported class version error: " + className;
+    }
+
+    if (validateConstructor) {
+            try {
+                final Constructor constructor = aClass.getConstructor(new Class[0]);
+                if ((constructor.getModifiers() & Modifier.PUBLIC) == 0) {
+        return "Class \"" + className + "\" does not have default public constructor";
+      }
+    }
+            catch (final Exception exc) {
+                return "Class \"" + className + "\" does not have default constructor";
+            }
+        }
+
+    // Check that JComponent is accessible via the loader
+
+        if (!JComponent.class.isAssignableFrom(aClass)) {
+        return "Class \"" + className + "\" is not an instance of javax.swing.JComponent";
+      }
+
+    return null;
+  }
+
+  public static void validateNestedFormLoop(final String formName, final NestedFormLoader nestedFormLoader)
+    throws CodeGenerationException, RecursiveFormNestingException {
+    validateNestedFormLoop(formName, nestedFormLoader, null);
+  }
+
+  public static void validateNestedFormLoop(final String formName, final NestedFormLoader nestedFormLoader, final String targetForm)
+    throws CodeGenerationException, RecursiveFormNestingException {
+    HashSet usedFormNames = new HashSet();
+    if (targetForm != null) {
+      usedFormNames.add(targetForm);
+    }
+    validateNestedFormLoop(usedFormNames, formName, nestedFormLoader);
+  }
+
+  private static void validateNestedFormLoop(final Set usedFormNames, final String formName, final NestedFormLoader nestedFormLoader)
+    throws CodeGenerationException, RecursiveFormNestingException {
+    if (usedFormNames.contains(formName)) {
+      throw new RecursiveFormNestingException();
+    }
+    usedFormNames.add(formName);
+    final LwRootContainer rootContainer;
+    try {
+      rootContainer = nestedFormLoader.loadForm(formName);
+    }
+    catch (Exception e) {
+      throw new CodeGenerationException(null, "Error loading nested form: " + e.getMessage(), e);
+    }
+    final Set thisFormNestedForms = new HashSet();
+    final CodeGenerationException[] validateExceptions = new CodeGenerationException[1];
+    final RecursiveFormNestingException[] recursiveNestingExceptions = new RecursiveFormNestingException[1];
+    rootContainer.accept(new ComponentVisitor() {
+      public boolean visit(final IComponent component) {
+        if (component instanceof LwNestedForm) {
+          LwNestedForm nestedForm = (LwNestedForm)component;
+          if (!thisFormNestedForms.contains(nestedForm.getFormFileName())) {
+            thisFormNestedForms.add(nestedForm.getFormFileName());
+            try {
+              validateNestedFormLoop(usedFormNames, nestedForm.getFormFileName(), nestedFormLoader);
+            }
+            catch (RecursiveFormNestingException e) {
+              recursiveNestingExceptions[0] = e;
+              return false;
+            }
+            catch (CodeGenerationException e) {
+              validateExceptions[0] = e;
+              return false;
+            }
+          }
+        }
+        return true;
+      }
+    });
+    if (recursiveNestingExceptions[0] != null) {
+      throw recursiveNestingExceptions[0];
+    }
+    if (validateExceptions[0] != null) {
+      throw validateExceptions[0];
+    }
+  }
+
+  public static String findNotEmptyPanelWithXYLayout(final IComponent component) {
+    if (!(component instanceof IContainer)) {
+      return null;
+    }
+    final IContainer container = (IContainer)component;
+    if (container.getComponentCount() == 0) {
+      return null;
+    }
+    if (container.isXY()) {
+      return container.getId();
+    }
+    for (int i = 0; i < container.getComponentCount(); i++) {
+      String id = findNotEmptyPanelWithXYLayout(container.getComponent(i));
+      if (id != null) {
+        return id;
+      }
+    }
+    return null;
+  }
+
+  public static int getHGap(LayoutManager layout) {
+    if (layout instanceof BorderLayout) {
+      return ((BorderLayout)layout).getHgap();
+    }
+    if (layout instanceof CardLayout) {
+      return ((CardLayout)layout).getHgap();
+    }
+    return 0;
+  }
+
+  public static int getVGap(LayoutManager layout) {
+    if (layout instanceof BorderLayout) {
+      return ((BorderLayout)layout).getVgap();
+    }
+    if (layout instanceof CardLayout) {
+      return ((CardLayout)layout).getVgap();
+    }
+    return 0;
+  }
+
+  public static int getCustomCreateComponentCount(final IContainer container) {
+    final int[] result = new int[1];
+    result[0] = 0;
+    container.accept(new ComponentVisitor() {
+      public boolean visit(IComponent c) {
+        if (c.isCustomCreate()) {
+          result[0]++;
+        }
+        return true;
+      }
+    });
+    return result[0];
+  }
+
+  public static Class suggestReplacementClass(Class componentClass) {
+    while (true) {
+      componentClass = componentClass.getSuperclass();
+      if (componentClass.equals(JComponent.class)) {
+        return JPanel.class;
+      }
+      if ((componentClass.getModifiers() & (Modifier.ABSTRACT | Modifier.PRIVATE)) != 0) {
+        continue;
+      }
+      try {
+        componentClass.getConstructor(new Class[]{});
+      }
+      catch (NoSuchMethodException ex) {
+        continue;
+      }
+      return componentClass;
+    }
+  }
+
+  public static InstrumentationClassFinder.PseudoClass suggestReplacementClass(InstrumentationClassFinder.PseudoClass componentClass) throws ClassNotFoundException, IOException {
+    final InstrumentationClassFinder.PseudoClass jComponentClass = componentClass.getFinder().loadClass(JComponent.class.getName());
+    while (true) {
+      componentClass = componentClass.getSuperClass();
+      if (componentClass.equals(jComponentClass)) {
+        return componentClass.getFinder().loadClass(JPanel.class.getName());
+      }
+      if ((componentClass.getModifiers() & (Modifier.ABSTRACT | Modifier.PRIVATE)) != 0) {
+        continue;
+      }
+      if (!componentClass.hasDefaultPublicConstructor()) {
+        continue;
+      }
+      return componentClass;
+    }
+  }
+
+  public static int alignFromConstraints(final GridConstraints gc, final boolean horizontal) {
+    int anchor = gc.getAnchor();
+    int fill = gc.getFill();
+    int leftMask = horizontal ? GridConstraints.ANCHOR_WEST : GridConstraints.ANCHOR_NORTH;
+    int rightMask = horizontal ? GridConstraints.ANCHOR_EAST : GridConstraints.ANCHOR_SOUTH;
+    int fillMask = horizontal ? GridConstraints.FILL_HORIZONTAL : GridConstraints.FILL_VERTICAL;
+    if ((fill & fillMask) != 0) return GridConstraints.ALIGN_FILL;
+    if ((anchor & rightMask) != 0) return GridConstraints.ALIGN_RIGHT;
+    if ((anchor & leftMask) != 0) return GridConstraints.ALIGN_LEFT;
+    return GridConstraints.ALIGN_CENTER;
+  }
+
+  public static boolean isBoundField(IComponent component, String fieldName) {
+    if (fieldName.equals(component.getBinding())) {
+      return true;
+    }
+    if (component instanceof IContainer) {
+      IContainer container = (IContainer)component;
+      for (int i = 0; i < container.getComponentCount(); i++) {
+        if (isBoundField(container.getComponent(i), fieldName)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/BorderLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/BorderLayoutSerializer.java
new file mode 100644
index 0000000..b2b769c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/BorderLayoutSerializer.java
@@ -0,0 +1,43 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class BorderLayoutSerializer extends LayoutSerializer {
+  public static final BorderLayoutSerializer INSTANCE = new BorderLayoutSerializer();
+
+  private BorderLayoutSerializer() {
+  }
+
+  void readLayout(Element element, LwContainer container) {
+    final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 0);
+    final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 0);
+    container.setLayout(new BorderLayout(hGap, vGap));
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    component.setCustomLayoutConstraints(LwXmlReader.getRequiredString(constraintsElement,
+                                                                       UIFormXmlConstants.ATTRIBUTE_BORDER_CONSTRAINT));
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java
new file mode 100644
index 0000000..9371b5c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CardLayoutSerializer.java
@@ -0,0 +1,47 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.awt.CardLayout;
+
+/**
+ * @author yole
+ */
+public class CardLayoutSerializer extends LayoutSerializer {
+  public static final CardLayoutSerializer INSTANCE = new CardLayoutSerializer();
+
+  private CardLayoutSerializer() {
+  }
+
+  void readLayout(Element element, LwContainer container) {
+    final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 0);
+    final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 0);
+    container.setLayout(new CardLayout(hGap, vGap));
+
+    String defaultCard = LwXmlReader.getOptionalString(element, UIFormXmlConstants.ATTRIBUTE_SHOW, null);
+    container.putClientProperty(UIFormXmlConstants.LAYOUT_CARD, defaultCard);
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    final Element cardChild = LwXmlReader.getRequiredChild(constraintsElement, UIFormXmlConstants.ELEMENT_CARD);
+    final String name = LwXmlReader.getRequiredString(cardChild, UIFormXmlConstants.ATTRIBUTE_NAME);
+    component.setCustomLayoutConstraints(name);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ColorDescriptor.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ColorDescriptor.java
new file mode 100644
index 0000000..79dd473
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ColorDescriptor.java
@@ -0,0 +1,137 @@
+/*
+ * 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.uiDesigner.lw;
+
+import javax.swing.*;
+import java.awt.*;
+import java.lang.reflect.Field;
+
+/**
+ * @author yole
+ */
+public class ColorDescriptor {
+  private final Color myColor;
+  private String mySwingColor;
+  private String mySystemColor;
+  private String myAWTColor;
+
+  public ColorDescriptor(final Color color) {
+    myColor = color;
+  }
+
+  public static ColorDescriptor fromSwingColor(final String swingColor) {
+    ColorDescriptor result = new ColorDescriptor(null);
+    result.mySwingColor = swingColor;
+    return result;
+  }
+
+  public static ColorDescriptor fromSystemColor(final String systemColor) {
+    ColorDescriptor result = new ColorDescriptor(null);
+    result.mySystemColor = systemColor;
+    return result;
+  }
+
+  public static ColorDescriptor fromAWTColor(final String awtColor) {
+    ColorDescriptor result = new ColorDescriptor(null);
+    result.myAWTColor = awtColor;
+    return result;
+  }
+
+  private static Color getColorField(final Class aClass, final String fieldName) {
+    try {
+      final Field field = aClass.getDeclaredField(fieldName);
+      return (Color)field.get(null);
+    }
+    catch (NoSuchFieldException e) {
+      return Color.black;
+    }
+    catch (IllegalAccessException e) {
+      return Color.black;
+    }
+  }
+
+  public Color getResolvedColor() {
+    if (myColor != null) {
+      return myColor;
+    }
+    if (mySwingColor != null) {
+      return UIManager.getColor(mySwingColor);
+    }
+    if (mySystemColor != null) {
+      return getColorField(SystemColor.class, mySystemColor);
+    }
+    if (myAWTColor != null) {
+      return getColorField(Color.class, myAWTColor);
+    }
+    return null;
+  }
+
+  public Color getColor() {
+    return myColor;
+  }
+
+  public String getSwingColor() {
+    return mySwingColor;
+  }
+
+  public String getSystemColor() {
+    return mySystemColor;
+  }
+
+  public String getAWTColor() {
+    return myAWTColor;
+  }
+
+  public String toString() {
+    if (mySwingColor != null) {
+      return mySwingColor;
+    }
+    if (mySystemColor != null) {
+      return mySystemColor;
+    }
+    if (myAWTColor != null) {
+      return myAWTColor;
+    }
+    if (myColor != null) {
+      return "[" + myColor.getRed() + "," + myColor.getGreen() + "," + myColor.getBlue() + "]";
+    }
+    return "null";
+  }
+
+  public boolean equals(Object obj) {
+    if (obj == null || !(obj instanceof ColorDescriptor)) {
+      return false;
+    }
+    ColorDescriptor rhs = (ColorDescriptor) obj;
+    if (myColor != null) {
+      return myColor.equals(rhs.myColor);
+    }
+    if (mySwingColor != null) {
+      return mySwingColor.equals(rhs.mySwingColor);
+    }
+    if (mySystemColor != null) {
+      return mySystemColor.equals(rhs.mySystemColor);
+    }
+    if (myAWTColor != null) {
+      return myAWTColor.equals(rhs.myAWTColor);
+    }
+    return false;
+  }
+
+  public boolean isColorSet() {
+    return myColor != null || mySwingColor != null || mySystemColor != null || myAWTColor != null;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CompiledClassPropertiesProvider.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CompiledClassPropertiesProvider.java
new file mode 100644
index 0000000..bea75bb
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/CompiledClassPropertiesProvider.java
@@ -0,0 +1,163 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.compiler.Utils;
+
+import javax.swing.*;
+import java.awt.*;
+import java.beans.BeanInfo;
+import java.beans.Introspector;
+import java.beans.PropertyDescriptor;
+import java.lang.reflect.Method;
+import java.util.HashMap;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class CompiledClassPropertiesProvider implements PropertiesProvider {
+  private final ClassLoader myLoader;
+  private final HashMap myCache;
+
+  public CompiledClassPropertiesProvider(final ClassLoader loader) {
+    if (loader == null) {
+      throw new IllegalArgumentException("loader cannot be null");
+    }
+    myLoader = loader;
+    myCache = new HashMap();
+  }
+
+  public HashMap getLwProperties(final String className) {
+    if (myCache.containsKey(className)) {
+      return (HashMap)myCache.get(className);
+    }
+
+    if (Utils.validateJComponentClass(myLoader, className, false) != null) {
+      return null;
+    }
+
+    final Class aClass;
+    try {
+      aClass = Class.forName(className, false, myLoader);
+    }
+    catch (final ClassNotFoundException exc) {
+      throw new RuntimeException(exc.toString()); // should never happen
+    }
+
+    final BeanInfo beanInfo;
+    try {
+      beanInfo = Introspector.getBeanInfo(aClass);
+    }
+    catch (Throwable e) {
+      return null;
+    }
+
+    final HashMap result = new HashMap();
+    final PropertyDescriptor[] descriptors = beanInfo.getPropertyDescriptors();
+    for (int i = 0; i < descriptors.length; i++) {
+      final PropertyDescriptor descriptor = descriptors[i];
+
+      final Method readMethod = descriptor.getReadMethod();
+      final Method writeMethod = descriptor.getWriteMethod();
+      if (writeMethod == null || readMethod == null) {
+        continue;
+      }
+
+      final String name = descriptor.getName();
+
+      final LwIntrospectedProperty property = propertyFromClass(descriptor.getPropertyType(), name);
+
+      if (property != null) {
+        property.setDeclaringClassName(descriptor.getReadMethod().getDeclaringClass().getName());
+        result.put(name, property);
+      }
+    }
+
+    myCache.put(className, result);
+
+    return result;
+  }
+
+  public static LwIntrospectedProperty propertyFromClass(final Class propertyType, final String name) {
+    LwIntrospectedProperty property = propertyFromClassName(propertyType.getName(), name);
+    if (property == null) {
+      if (Component.class.isAssignableFrom(propertyType)) {
+        property = new LwIntroComponentProperty(name, propertyType.getName());
+      }
+      else if (ListModel.class.isAssignableFrom(propertyType)) {
+        property = new LwIntroListModelProperty(name, propertyType.getName());
+      }
+      else if (propertyType.getSuperclass() != null && "java.lang.Enum".equals(propertyType.getSuperclass().getName())) {
+        property = new LwIntroEnumProperty(name, propertyType);
+      }
+    }
+    return property;
+  }
+
+  public static LwIntrospectedProperty propertyFromClassName(final String propertyClassName, final String name) {
+    final LwIntrospectedProperty property;
+    if (int.class.getName().equals(propertyClassName)) { // int
+      property = new LwIntroIntProperty(name);
+    }
+    else if (boolean.class.getName().equals(propertyClassName)) { // boolean
+      property = new LwIntroBooleanProperty(name);
+    }
+    else if (double.class.getName().equals(propertyClassName)) { // double
+      property = new LwIntroPrimitiveTypeProperty(name, Double.class);
+    }
+    else if (float.class.getName().equals(propertyClassName)) {
+      property = new LwIntroPrimitiveTypeProperty(name, Float.class);
+    }
+    else if (long.class.getName().equals(propertyClassName)) {
+      property = new LwIntroPrimitiveTypeProperty(name, Long.class);
+    }
+    else if (byte.class.getName().equals(propertyClassName)) {
+      property = new LwIntroPrimitiveTypeProperty(name, Byte.class);
+    }
+    else if (short.class.getName().equals(propertyClassName)) {
+      property = new LwIntroPrimitiveTypeProperty(name, Short.class);
+    }
+    else if (char.class.getName().equals(propertyClassName)) {
+      property = new LwIntroCharProperty(name);
+    }
+    else if (String.class.getName().equals(propertyClassName)) { // java.lang.String
+      property = new LwRbIntroStringProperty(name);
+    }
+    else if ("java.awt.Insets".equals(propertyClassName)) { // java.awt.Insets
+      property = new LwIntroInsetsProperty(name);
+    }
+    else if ("java.awt.Dimension".equals(propertyClassName)) { // java.awt.Dimension
+      property = new LwIntroDimensionProperty(name);
+    }
+    else if ("java.awt.Rectangle".equals(propertyClassName)) { // java.awt.Rectangle
+      property = new LwIntroRectangleProperty(name);
+    }
+    else if ("java.awt.Color".equals(propertyClassName)) {
+      property = new LwIntroColorProperty(name);
+    }
+    else if ("java.awt.Font".equals(propertyClassName)) {
+      property = new LwIntroFontProperty(name);
+    }
+    else if ("javax.swing.Icon".equals(propertyClassName)) {
+      property = new LwIntroIconProperty(name);
+    }
+    else {
+      property = null;
+    }
+    return property;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ComponentVisitor.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ComponentVisitor.java
new file mode 100644
index 0000000..8f94061
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ComponentVisitor.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.uiDesigner.lw;
+
+/**
+ * @author yole
+ */
+public interface ComponentVisitor {
+  /**
+   * @return true if iteration should continue
+   */
+  boolean visit(IComponent c);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FlowLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FlowLayoutSerializer.java
new file mode 100644
index 0000000..8933ee3
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FlowLayoutSerializer.java
@@ -0,0 +1,42 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.awt.FlowLayout;
+
+/**
+ * @author yole
+ */
+public class FlowLayoutSerializer extends LayoutSerializer {
+  public static final FlowLayoutSerializer INSTANCE = new FlowLayoutSerializer();
+
+  private FlowLayoutSerializer() {
+  }
+
+  void readLayout(Element element, LwContainer container) {
+    final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, 5);
+    final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, 5);
+    final int flowAlign = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_FLOW_ALIGN, FlowLayout.CENTER);
+    container.setLayout(new FlowLayout(flowAlign, hGap, vGap));
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FontDescriptor.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FontDescriptor.java
new file mode 100644
index 0000000..a6250cb
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FontDescriptor.java
@@ -0,0 +1,97 @@
+/*
+ * 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.uiDesigner.lw;
+
+import javax.swing.*;
+import java.awt.Font;
+
+/**
+ * @author yole
+ */
+public class FontDescriptor {
+  private String myFontName;
+  private int myFontSize;
+  private int myFontStyle;
+  private String mySwingFont;
+
+  private FontDescriptor() {
+  }
+
+  public FontDescriptor(final String fontName, final int fontStyle, final int fontSize) {
+    myFontName = fontName;
+    myFontSize = fontSize;
+    myFontStyle = fontStyle;
+  }
+
+  public boolean isFixedFont() {
+    return mySwingFont == null;
+  }
+
+  public boolean isFullyDefinedFont() {
+    return myFontName != null && myFontSize >= 0 && myFontStyle >= 0;
+  }
+
+  public static FontDescriptor fromSwingFont(String swingFont) {
+    FontDescriptor result = new FontDescriptor();
+    result.mySwingFont = swingFont;
+    return result;
+  }
+
+  public String getFontName() {
+    return myFontName;
+  }
+
+  public int getFontSize() {
+    return myFontSize;
+  }
+
+  public int getFontStyle() {
+    return myFontStyle;
+  }
+
+  public Font getFont(Font defaultFont) {
+    return new Font(myFontName != null ? myFontName : defaultFont.getFontName(),
+                    myFontStyle >= 0 ? myFontStyle : defaultFont.getStyle(),
+                    myFontSize >= 0 ? myFontSize : defaultFont.getSize());
+  }
+
+  public String getSwingFont() {
+    return mySwingFont;
+  }
+
+  public Font getResolvedFont(Font defaultFont) {
+    if (mySwingFont != null) {
+      return UIManager.getFont(mySwingFont);
+    }
+    return getFont(defaultFont);
+  }
+
+  public boolean equals(Object obj) {
+    if (obj == null || !(obj instanceof FontDescriptor)) {
+      return false;
+    }
+    FontDescriptor rhs = (FontDescriptor) obj;
+    if (mySwingFont != null) {
+      return mySwingFont.equals(rhs.mySwingFont);
+    }
+    else {
+      if (myFontName == null && rhs.myFontName != null) return false;
+      if (myFontName != null && rhs.myFontName == null) return false;
+      if (myFontName != null && !myFontName.equals(rhs.myFontName)) return false;
+      return myFontSize == rhs.myFontSize && myFontStyle == rhs.myFontStyle;
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FormLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FormLayoutSerializer.java
new file mode 100644
index 0000000..86544b9
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/FormLayoutSerializer.java
@@ -0,0 +1,105 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.jgoodies.forms.layout.FormLayout;
+import com.jgoodies.forms.layout.RowSpec;
+import com.jgoodies.forms.layout.ColumnSpec;
+import com.jgoodies.forms.layout.CellConstraints;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.compiler.Utils;
+
+import java.util.List;
+import java.util.Iterator;
+
+/**
+ * @author yole
+ */
+public class FormLayoutSerializer extends GridLayoutSerializer {
+  private FormLayoutSerializer() {
+  }
+
+  public static FormLayoutSerializer INSTANCE = new FormLayoutSerializer();
+
+  public static CellConstraints.Alignment[] ourHorizontalAlignments = {
+    CellConstraints.LEFT, CellConstraints.CENTER, CellConstraints.RIGHT, CellConstraints.FILL
+  };
+  public static CellConstraints.Alignment[] ourVerticalAlignments = {
+    CellConstraints.TOP, CellConstraints.CENTER, CellConstraints.BOTTOM, CellConstraints.FILL
+  };
+
+  void readLayout(Element element, LwContainer container) {
+    FormLayout layout = new FormLayout();
+    final List rowSpecs = element.getChildren(UIFormXmlConstants.ELEMENT_ROWSPEC, element.getNamespace());
+    for (Iterator iterator = rowSpecs.iterator(); iterator.hasNext();) {
+      Element rowSpecElement = (Element) iterator.next();
+      final String spec = LwXmlReader.getRequiredString(rowSpecElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
+      layout.appendRow(new RowSpec(spec));
+    }
+
+    final List colSpecs = element.getChildren(UIFormXmlConstants.ELEMENT_COLSPEC, element.getNamespace());
+    for (Iterator iterator = colSpecs.iterator(); iterator.hasNext();) {
+      Element colSpecElement = (Element) iterator.next();
+      final String spec = LwXmlReader.getRequiredString(colSpecElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
+      layout.appendColumn(new ColumnSpec(spec));
+    }
+
+    int[][] rowGroups = readGroups(element, UIFormXmlConstants.ELEMENT_ROWGROUP);
+    int[][] colGroups = readGroups(element, UIFormXmlConstants.ELEMENT_COLGROUP);
+    if (rowGroups != null) {
+      layout.setRowGroups(rowGroups);
+    }
+    if (colGroups != null) {
+      layout.setColumnGroups(colGroups);
+    }
+    container.setLayout(layout);
+  }
+
+  private static int[][] readGroups(final Element element, final String elementName) {
+    final List groupElements = element.getChildren(elementName, element.getNamespace());
+    if (groupElements.size() == 0) return null;
+    int[][] groups = new int[groupElements.size()][];
+    for(int i=0; i<groupElements.size(); i++) {
+      Element groupElement = (Element) groupElements.get(i);
+      List groupMembers = groupElement.getChildren(UIFormXmlConstants.ELEMENT_MEMBER, element.getNamespace());
+      groups [i] = new int[groupMembers.size()];
+      for(int j=0; j<groupMembers.size(); j++) {
+        groups [i][j] = LwXmlReader.getRequiredInt((Element) groupMembers.get(j), UIFormXmlConstants.ATTRIBUTE_INDEX);
+      }
+    }
+    return groups;
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    super.readChildConstraints(constraintsElement, component);
+    CellConstraints cc = new CellConstraints();
+    final Element formsElement = LwXmlReader.getChild(constraintsElement, UIFormXmlConstants.ELEMENT_FORMS);
+    if (formsElement != null) {
+      if (formsElement.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_TOP) != null) {
+        cc.insets = LwXmlReader.readInsets(formsElement);
+      }
+      if (!LwXmlReader.getOptionalBoolean(formsElement, UIFormXmlConstants.ATTRIBUTE_DEFAULTALIGN_HORZ, true)) {
+        cc.hAlign = ourHorizontalAlignments [Utils.alignFromConstraints(component.getConstraints(), true)];
+      }
+      if (!LwXmlReader.getOptionalBoolean(formsElement, UIFormXmlConstants.ATTRIBUTE_DEFAULTALIGN_VERT, true)) {
+        cc.vAlign = ourVerticalAlignments [Utils.alignFromConstraints(component.getConstraints(), false)];
+      }
+    }
+    component.setCustomLayoutConstraints(cc);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridBagLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridBagLayoutSerializer.java
new file mode 100644
index 0000000..a895b5d
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridBagLayoutSerializer.java
@@ -0,0 +1,57 @@
+/*
+ * 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 30.08.2006
+ * Time: 13:02:12
+ */
+package com.intellij.uiDesigner.lw;
+
+import com.intellij.uiDesigner.compiler.GridBagConverter;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.awt.*;
+
+public class GridBagLayoutSerializer extends GridLayoutSerializer {
+  private GridBagLayoutSerializer() {
+  }
+
+  public static GridBagLayoutSerializer INSTANCE = new GridBagLayoutSerializer();
+
+  void readLayout(Element element, LwContainer container) {
+    container.setLayout(new GridBagLayout());
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    super.readChildConstraints(constraintsElement, component);
+    GridBagConstraints gbc = new GridBagConstraints();
+    GridBagConverter.constraintsToGridBag(component.getConstraints(), gbc);
+    final Element gridBagElement = LwXmlReader.getChild(constraintsElement, UIFormXmlConstants.ELEMENT_GRIDBAG);
+    if (gridBagElement != null) {
+      if (gridBagElement.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_TOP) != null) {
+        gbc.insets = LwXmlReader.readInsets(gridBagElement);
+      }
+      gbc.weightx = LwXmlReader.getOptionalDouble(gridBagElement, UIFormXmlConstants.ATTRIBUTE_WEIGHTX, 0.0);
+      gbc.weighty = LwXmlReader.getOptionalDouble(gridBagElement, UIFormXmlConstants.ATTRIBUTE_WEIGHTY, 0.0);
+      gbc.ipadx = LwXmlReader.getOptionalInt(gridBagElement, UIFormXmlConstants.ATTRIBUTE_IPADX, 0);
+      gbc.ipady = LwXmlReader.getOptionalInt(gridBagElement, UIFormXmlConstants.ATTRIBUTE_IPADY, 0);
+    }
+    component.setCustomLayoutConstraints(gbc);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridLayoutSerializer.java
new file mode 100644
index 0000000..274daa9
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/GridLayoutSerializer.java
@@ -0,0 +1,104 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.core.GridConstraints;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class GridLayoutSerializer extends LayoutSerializer {
+  protected GridLayoutSerializer() {
+  }
+
+  public static GridLayoutSerializer INSTANCE = new GridLayoutSerializer();
+
+  void readLayout(Element element, LwContainer container) {
+    final int rowCount = LwXmlReader.getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_ROW_COUNT);
+    final int columnCount = LwXmlReader.getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_COLUMN_COUNT);
+
+    final int hGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_HGAP, -1);
+    final int vGap = LwXmlReader.getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_VGAP, -1);
+
+    // attribute is optional for compatibility with IDEA 4.0 forms
+    final boolean sameSizeHorizontally = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_SAME_SIZE_HORIZONTALLY, false);
+    final boolean sameSizeVertically = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_SAME_SIZE_VERTICALLY, false);
+
+    final Element marginElement = LwXmlReader.getRequiredChild(element, "margin");
+    final Insets margin = new Insets(
+      LwXmlReader.getRequiredInt(marginElement,"top"),
+      LwXmlReader.getRequiredInt(marginElement,"left"),
+      LwXmlReader.getRequiredInt(marginElement,"bottom"),
+      LwXmlReader.getRequiredInt(marginElement,"right")
+    );
+
+    final GridLayoutManager layout = new GridLayoutManager(rowCount, columnCount);
+    layout.setMargin(margin);
+    layout.setVGap(vGap);
+    layout.setHGap(hGap);
+    layout.setSameSizeHorizontally(sameSizeHorizontally);
+    layout.setSameSizeVertically(sameSizeVertically);
+    container.setLayout(layout);
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    // Read Grid constraints
+    final Element gridElement = LwXmlReader.getChild(constraintsElement, "grid");
+    if(gridElement != null){
+      final GridConstraints constraints=new GridConstraints();
+
+      constraints.setRow(LwXmlReader.getRequiredInt(gridElement, "row"));
+      constraints.setColumn(LwXmlReader.getRequiredInt(gridElement, "column"));
+      constraints.setRowSpan(LwXmlReader.getRequiredInt(gridElement, "row-span"));
+      constraints.setColSpan(LwXmlReader.getRequiredInt(gridElement, "col-span"));
+      constraints.setVSizePolicy(LwXmlReader.getRequiredInt(gridElement, "vsize-policy"));
+      constraints.setHSizePolicy(LwXmlReader.getRequiredInt(gridElement, "hsize-policy"));
+      constraints.setAnchor(LwXmlReader.getRequiredInt(gridElement, "anchor"));
+      constraints.setFill(LwXmlReader.getRequiredInt(gridElement, "fill"));
+      constraints.setIndent(LwXmlReader.getOptionalInt(gridElement, UIFormXmlConstants.ATTRIBUTE_INDENT, 0));
+      constraints.setUseParentLayout(LwXmlReader.getOptionalBoolean(gridElement, UIFormXmlConstants.ATTRIBUTE_USE_PARENT_LAYOUT, false));
+
+      // minimum size
+      final Element minSizeElement = LwXmlReader.getChild(gridElement, "minimum-size");
+      if (minSizeElement != null) {
+        constraints.myMinimumSize.width = LwXmlReader.getRequiredInt(minSizeElement, "width");
+        constraints.myMinimumSize.height = LwXmlReader.getRequiredInt(minSizeElement, "height");
+      }
+
+      // preferred size
+      final Element prefSizeElement = LwXmlReader.getChild(gridElement, "preferred-size");
+      if (prefSizeElement != null) {
+        constraints.myPreferredSize.width = LwXmlReader.getRequiredInt(prefSizeElement, "width");
+        constraints.myPreferredSize.height = LwXmlReader.getRequiredInt(prefSizeElement, "height");
+      }
+
+      // maximum size
+      final Element maxSizeElement = LwXmlReader.getChild(gridElement, "maximum-size");
+      if (maxSizeElement != null) {
+        constraints.myMaximumSize.width = LwXmlReader.getRequiredInt(maxSizeElement, "width");
+        constraints.myMaximumSize.height = LwXmlReader.getRequiredInt(maxSizeElement, "height");
+      }
+
+      component.getConstraints().restore(constraints);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IButtonGroup.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IButtonGroup.java
new file mode 100644
index 0000000..ed7e156
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IButtonGroup.java
@@ -0,0 +1,26 @@
+/*
+ * 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.uiDesigner.lw;
+
+/**
+ * @author yole
+ */
+public interface IButtonGroup {
+  String getName();
+  boolean isBound();
+  String[] getComponentIds();
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IComponent.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IComponent.java
new file mode 100644
index 0000000..d5e87e0
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IComponent.java
@@ -0,0 +1,58 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public interface IComponent {
+  Object getClientProperty(Object key);
+
+  void putClientProperty(Object key, Object value);
+
+  /**
+   * @return name of the field (in bound class). Returns <code>null</code>
+   * if the component is not bound to any field.
+   */
+  String getBinding();
+
+  String getComponentClassName();
+
+  String getId();
+
+  boolean isCustomCreate();
+
+  IProperty[] getModifiedProperties();
+
+  IContainer getParentContainer();
+
+  GridConstraints getConstraints();
+
+  Object getCustomLayoutConstraints();
+
+  boolean accept(ComponentVisitor visitor);
+
+  /**
+   * Returns true if only one of the children of the component can be visible at a time
+   * (for example, the component is a tabbed pane or a container with CardLayout).
+   *
+   * @return true if children are exclusive, false otherwise.
+   */
+  boolean areChildrenExclusive();
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IContainer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IContainer.java
new file mode 100644
index 0000000..2ae0814
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IContainer.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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.shared.BorderType;
+
+public interface IContainer extends IComponent {
+  int getComponentCount();
+  IComponent getComponent(int index);
+  int indexOfComponent(final IComponent lwComponent);
+  boolean isXY();
+  StringDescriptor getBorderTitle();
+  BorderType getBorderType();
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IProperty.java
new file mode 100644
index 0000000..b976d1f
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IProperty.java
@@ -0,0 +1,25 @@
+/*
+ * 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.uiDesigner.lw;
+
+/**
+ * @author yole
+ */
+public interface IProperty {
+  String getName();
+
+  Object getPropertyValue(final IComponent component);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IRootContainer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IRootContainer.java
new file mode 100644
index 0000000..67622d8
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IRootContainer.java
@@ -0,0 +1,24 @@
+/*
+ * 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.uiDesigner.lw;
+
+public interface IRootContainer extends IContainer {
+  String getClassToBind();
+  String getButtonGroupName(IComponent component);
+  String[] getButtonGroupComponentIds(String groupName);
+  boolean isInspectionSuppressed(final String inspectionId, final String componentId);
+  IButtonGroup[] getButtonGroups();
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ITabbedPane.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ITabbedPane.java
new file mode 100644
index 0000000..a070e69
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/ITabbedPane.java
@@ -0,0 +1,26 @@
+/*
+ * 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.uiDesigner.lw;
+
+/**
+ * @author yole
+ */
+public interface ITabbedPane extends IContainer {
+  String TAB_TITLE_PROPERTY = "Tab Title";
+  String TAB_TOOLTIP_PROPERTY = "Tab Tooltip";
+
+  StringDescriptor getTabProperty(IComponent component, final String propName);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IconDescriptor.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IconDescriptor.java
new file mode 100644
index 0000000..8510121
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/IconDescriptor.java
@@ -0,0 +1,42 @@
+/*
+ * 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.uiDesigner.lw;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class IconDescriptor {
+  private final String myIconPath;
+  private Icon myIcon;
+
+  public IconDescriptor(final String iconPath) {
+    myIconPath = iconPath;
+  }
+
+  public String getIconPath() {
+    return myIconPath;
+  }
+
+  public Icon getIcon() {
+    return myIcon;
+  }
+
+  public void setIcon(final Icon icon) {
+    myIcon = icon;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LayoutSerializer.java
new file mode 100644
index 0000000..e4f77dd
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LayoutSerializer.java
@@ -0,0 +1,28 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author yole
+ */
+public abstract class LayoutSerializer {
+  abstract void readLayout(Element element, LwContainer container);
+
+  abstract void readChildConstraints(final Element constraintsElement, final LwComponent component);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwAtomicComponent.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwAtomicComponent.java
new file mode 100644
index 0000000..23d32b5
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwAtomicComponent.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public class LwAtomicComponent extends LwComponent {
+  public LwAtomicComponent(final String className){
+    super(className);
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception{
+    readBase(element);
+    readConstraints(element);
+    readProperties(element, provider);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwButtonGroup.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwButtonGroup.java
new file mode 100644
index 0000000..b3e999d
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwButtonGroup.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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+import java.util.Iterator;
+import java.util.ArrayList;
+
+/**
+ * @author yole
+ */
+public class LwButtonGroup implements IButtonGroup {
+  private String myName;
+  private final ArrayList myComponentIds = new ArrayList();
+  private boolean myBound;
+
+  public void read(final Element element) {
+    myName = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_NAME);
+    myBound = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_BOUND, false);
+    for(Iterator i=element.getChildren().iterator(); i.hasNext();){
+      final Element child = (Element)i.next();
+      myComponentIds.add(child.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_ID));
+    }
+  }
+
+  public String getName() {
+    return myName;
+  }
+
+  public String[] getComponentIds() {
+    return (String[])myComponentIds.toArray(new String[myComponentIds.size()]);
+  }
+
+  public boolean isBound() {
+    return myBound;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwComponent.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwComponent.java
new file mode 100644
index 0000000..cddfc5a
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwComponent.java
@@ -0,0 +1,327 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.core.GridConstraints;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.awt.*;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public abstract class LwComponent implements IComponent{
+  /**
+   *  Component's ID. Cannot be null.
+   */
+  private String myId;
+  /**
+   * may be null
+   */
+  private String myBinding;
+  /**
+   * Component class
+   */
+  private final String myClassName;
+  /**
+   * Parent LwContainer. This field is always not <code>null</code>
+   * is the component is in hierarchy. But the root of hierarchy
+   * has <code>null</code> parent indeed.
+   */
+  private LwContainer myParent;
+  /**
+   * never <code>null</code>
+   */
+  private final GridConstraints myConstraints;
+
+  private Object myCustomLayoutConstraints;
+  /**
+   * Bounds in XY layout
+   */
+  private final Rectangle myBounds;
+
+  private final HashMap myIntrospectedProperty2Value;
+  /**
+   * if class is unknown (cannot be loaded), properties tag is stored as is
+   */
+  private Element myErrorComponentProperties;
+  protected final HashMap myClientProperties;
+  protected final HashMap myDelegeeClientProperties;
+  private boolean myCustomCreate = false;
+  private boolean myDefaultBinding = false;
+
+  public LwComponent(final String className){
+    if (className == null){
+      throw new IllegalArgumentException("className cannot be null");
+    }
+    myBounds = new Rectangle();
+    myConstraints = new GridConstraints();
+    myIntrospectedProperty2Value = new HashMap();
+    myClassName = className;
+    myClientProperties = new HashMap();
+    myDelegeeClientProperties = new HashMap();
+  }
+
+  public final String getId() {
+    return myId;
+  }
+
+  public final void setId(final String id){
+    if (id == null) {
+      throw new IllegalArgumentException("id cannot be null");
+    }
+    myId = id;
+  }
+
+  public final String getBinding(){
+    return myBinding;
+  }
+
+  public final void setBinding(final String binding){
+    myBinding = binding;
+  }
+
+  public final Object getCustomLayoutConstraints(){
+    return myCustomLayoutConstraints;
+  }
+
+  public final void setCustomLayoutConstraints(final Object customLayoutConstraints){
+    myCustomLayoutConstraints = customLayoutConstraints;
+  }
+
+  /**
+   * @return never null
+   */
+  public final String getComponentClassName(){
+    return myClassName;
+  }
+
+  public IProperty[] getModifiedProperties() {
+    return getAssignedIntrospectedProperties();
+  }
+
+  /**
+   * @return component's constraints in XY layout. This method rever
+   * returns <code>null</code>.
+   */
+  public final Rectangle getBounds(){
+    return (Rectangle)myBounds.clone();
+  }
+
+  /**
+   * @return component's constraints in GridLayoutManager. This method never
+   * returns <code>null</code>.
+   */
+  public final GridConstraints getConstraints(){
+    return myConstraints;
+  }
+
+  public boolean isCustomCreate() {
+    return myCustomCreate;
+  }
+
+  public boolean isDefaultBinding() {
+    return myDefaultBinding;
+  }
+
+  public boolean accept(ComponentVisitor visitor) {
+    return visitor.visit(this);
+  }
+
+  public boolean areChildrenExclusive() {
+    return false;
+  }
+
+  public final LwContainer getParent(){
+    return myParent;
+  }
+
+  public IContainer getParentContainer() {
+    return myParent;
+  }
+
+  protected final void setParent(final LwContainer parent){
+    myParent = parent;
+  }
+
+  public final void setBounds(final Rectangle bounds) {
+    myBounds.setBounds(bounds);
+  }
+
+  public final Object getPropertyValue(final LwIntrospectedProperty property){
+    return myIntrospectedProperty2Value.get(property);
+  }
+
+  public final void setPropertyValue(final LwIntrospectedProperty property, final Object value){
+    myIntrospectedProperty2Value.put(property, value);
+  }
+
+  /**
+   * @return <code>null</code> only if component class is not valid.
+   * Class validation is performed with {@link com.intellij.uiDesigner.compiler.Utils#validateJComponentClass(ClassLoader,String,boolean)}
+   */
+  public final Element getErrorComponentProperties(){
+    return myErrorComponentProperties;
+  }
+
+  public final LwIntrospectedProperty[] getAssignedIntrospectedProperties() {
+    final LwIntrospectedProperty[] properties = new LwIntrospectedProperty[myIntrospectedProperty2Value.size()];
+    final Iterator iterator = myIntrospectedProperty2Value.keySet().iterator();
+    //noinspection ForLoopThatDoesntUseLoopVariable
+    for (int i=0; iterator.hasNext(); i++) {
+      properties[i] = (LwIntrospectedProperty)iterator.next();
+    }
+    return properties;
+  }
+
+  /**
+   * 'id' is required attribute
+   * 'binding' is optional attribute
+   */
+  protected final void readBase(final Element element) {
+    setId(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_ID));
+    setBinding(element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_BINDING));
+    myCustomCreate = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_CUSTOM_CREATE, false);
+    myDefaultBinding = LwXmlReader.getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_DEFAULT_BINDING, false);
+  }
+
+  /**
+   * 'properties' is not required subtag
+   * @param provider can be null if no properties should be read 
+   */
+  protected final void readProperties(final Element element, final PropertiesProvider provider) {
+    if (provider == null) {
+      // do not read properties 
+      return;
+    }
+
+    Element propertiesElement = LwXmlReader.getChild(element, UIFormXmlConstants.ELEMENT_PROPERTIES);
+    if(propertiesElement == null){
+      propertiesElement = new Element(UIFormXmlConstants.ELEMENT_PROPERTIES, element.getNamespace());
+    }
+
+    final HashMap name2property = provider.getLwProperties(getComponentClassName());
+    if (name2property == null) {
+      myErrorComponentProperties = (Element)propertiesElement.clone();
+      return;
+    }
+
+    final List propertyElements = propertiesElement.getChildren();
+    for (int i = 0; i < propertyElements.size(); i++) {
+      final Element t = (Element)propertyElements.get(i);
+      final String name = t.getName();
+      final LwIntrospectedProperty property = (LwIntrospectedProperty)name2property.get(name);
+      if (property == null){
+        continue;
+      }
+      try {
+        final Object value = property.read(t);
+        setPropertyValue(property, value);
+      }
+      catch (final Exception exc) {
+        // Skip non readable properties
+      }
+    }
+
+    readClientProperties(element);
+  }
+
+  private void readClientProperties(final Element element) {
+    Element propertiesElement = LwXmlReader.getChild(element, UIFormXmlConstants.ELEMENT_CLIENT_PROPERTIES);
+    if (propertiesElement == null) return;
+    final List clientPropertyList = propertiesElement.getChildren();
+    for(int i=0; i<clientPropertyList.size(); i++) {
+      final Element prop = (Element) clientPropertyList.get(i);
+      final String propName = prop.getName();
+      final String className = LwXmlReader.getRequiredString(prop, UIFormXmlConstants.ATTRIBUTE_CLASS);
+
+      LwIntrospectedProperty lwProp;
+      if (className.equals(Integer.class.getName())) {
+        lwProp = new LwIntroIntProperty(propName);
+      }
+      else if (className.equals(Boolean.class.getName())) {
+        lwProp = new LwIntroBooleanProperty(propName);
+      }
+      else if (className.equals(Double.class.getName())) {
+        lwProp = new LwIntroPrimitiveTypeProperty(propName, Double.class);
+      }
+      else {
+        Class propClass;
+        try {
+          propClass = Class.forName(className);
+        }
+        catch (ClassNotFoundException e) {
+          continue;
+        }
+        lwProp = CompiledClassPropertiesProvider.propertyFromClass(propClass, propName);
+      }
+
+      if (lwProp != null) {
+        final Object value;
+        try {
+          value = lwProp.read(prop);
+        }
+        catch (Exception e) {
+          continue;
+        }
+        myDelegeeClientProperties.put(propName, value);
+      }
+    }
+  }
+
+  /**
+   * Delegates reading of constraints to the parent container
+   */
+  protected final void readConstraints(final Element element){
+    final LwContainer parent = getParent();
+    if(parent == null){
+      throw new IllegalStateException("component must be in LW tree: "+this);
+    }
+    parent.readConstraintsForChild(element, this);
+  }
+
+  /**
+   * @param provider can be null if no component classes should not be created
+   */
+  public abstract void read(Element element, PropertiesProvider provider) throws Exception;
+
+  /**
+   * @see javax.swing.JComponent#getClientProperty(Object)
+   */
+  public final Object getClientProperty(final Object key){
+    if (key == null) {
+      throw new IllegalArgumentException("key cannot be null");
+    }
+    return myClientProperties.get(key);
+  }
+
+  /**
+   * @see javax.swing.JComponent#putClientProperty(Object, Object)
+   */
+  public final void putClientProperty(final Object key, final Object value){
+    if (key == null) {
+      throw new IllegalArgumentException("key cannot be null");
+    }
+    myClientProperties.put(key, value);
+  }
+
+  public HashMap getDelegeeClientProperties() {
+    return myDelegeeClientProperties;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwContainer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwContainer.java
new file mode 100644
index 0000000..4e70b4f
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwContainer.java
@@ -0,0 +1,385 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
+import com.intellij.uiDesigner.core.GridLayoutManager;
+import com.intellij.uiDesigner.shared.BorderType;
+import com.intellij.uiDesigner.shared.XYLayoutManager;
+import org.jdom.Element;
+
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Iterator;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public class LwContainer extends LwComponent implements IContainer{
+  // PLEASE DO NOT USE GENERICS IN THIS FILE AS IT IS USED IN JAVAC2 ANT TASK THAT SHOULD BE RUNNABLE WITH JDK 1.3
+
+  /**
+   * Children components
+   */
+  private final ArrayList myComponents;
+  /**
+   * Describes border's type. This member is never <code>null</code>
+   */
+  private BorderType myBorderType;
+  /**
+   * Border's title. If border doesn't have any title then
+   * this member is <code>null</code>.
+   */
+  private StringDescriptor myBorderTitle;
+  private int myBorderTitleJustification;
+  private int myBorderTitlePosition;
+  private FontDescriptor myBorderTitleFont;
+  private ColorDescriptor myBorderTitleColor;
+  private Insets myBorderSize;
+  private ColorDescriptor myBorderColor;
+  private LayoutManager myLayout;
+  private String myLayoutManager;
+  protected LayoutSerializer myLayoutSerializer;
+
+  public LwContainer(final String className){
+    super(className);
+    myComponents = new ArrayList();
+
+    // By default container doesn't have any special border
+    setBorderType(BorderType.NONE);
+
+    myLayout = createInitialLayout();
+  }
+
+
+  protected LayoutManager createInitialLayout(){
+    return new XYLayoutManager();
+  }
+
+  public final LayoutManager getLayout() {
+    return myLayout;
+  }
+
+  public final void setLayout(final LayoutManager layout) {
+    myLayout = layout;
+  }
+
+  public String getLayoutManager() {
+    return myLayoutManager;
+  }
+
+  public final boolean isGrid(){
+    return getLayout() instanceof GridLayoutManager;
+  }
+
+  public final boolean isXY(){
+    return getLayout() instanceof XYLayoutManager;
+  }
+
+  /**
+   * @param component component to be added.
+   *
+   * @exception IllegalArgumentException if <code>component</code> is <code>null</code>
+   * @exception IllegalArgumentException if <code>component</code> already exist in the
+   * container
+   */
+  public final void addComponent(final LwComponent component){
+    if (component == null) {
+      throw new IllegalArgumentException("component cannot be null");
+    }
+    if (myComponents.contains(component)) {
+      throw new IllegalArgumentException("component is already added: " + component);
+    }
+    if (component.getParent() != null) {
+      throw new IllegalArgumentException("component already added to another container");
+    }
+
+    // Attach to new parent
+    myComponents.add(component);
+    component.setParent(this);
+  }
+
+  public final IComponent getComponent(final int index) {
+    return (IComponent)myComponents.get(index);
+  }
+
+  public final int getComponentCount() {
+    return myComponents.size();
+  }
+
+  public int indexOfComponent(final IComponent lwComponent) {
+    return myComponents.indexOf(lwComponent);
+  }
+
+  /**
+   * @return border's type. The method never return <code>null</code>.
+   *
+   * @see BorderType
+   */
+  public final BorderType getBorderType(){
+    return myBorderType;
+  }
+
+  public boolean accept(ComponentVisitor visitor) {
+    if (!super.accept(visitor)) {
+      return false;
+    }
+
+    for (int i = 0; i < getComponentCount(); i++) {
+      final IComponent c = getComponent(i);
+      if (!c.accept(visitor)) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  /**
+   * @see BorderType
+   *
+   * @exception IllegalArgumentException if <code>type</code>
+   * is <code>null</code>
+   */
+  public final void setBorderType(final BorderType type){
+    if(type==null){
+      throw new IllegalArgumentException("type cannot be null");
+    }
+    myBorderType=type;
+  }
+
+  /**
+   * @return border's title. If the container doesn't have any title then the
+   * method returns <code>null</code>.
+   */
+  public final StringDescriptor getBorderTitle(){
+    return myBorderTitle;
+  }
+
+  /**
+   * @param title new border's title. <code>null</code> means that
+   * the containr doesn't have have titled border.
+   */
+  public final void setBorderTitle(final StringDescriptor title){
+    myBorderTitle=title;
+  }
+
+  public int getBorderTitleJustification() {
+    return myBorderTitleJustification;
+  }
+
+  public int getBorderTitlePosition() {
+    return myBorderTitlePosition;
+  }
+
+  public FontDescriptor getBorderTitleFont() {
+    return myBorderTitleFont;
+  }
+
+  public ColorDescriptor getBorderTitleColor() {
+    return myBorderTitleColor;
+  }
+
+  public Insets getBorderSize() {
+    return myBorderSize;
+  }
+
+  public ColorDescriptor getBorderColor() {
+    return myBorderColor;
+  }
+
+  /**
+   * TODO[anton,vova] looks like it is better to pass contraints tag
+   * 
+   * @param element XML element which should contains 'constraints' tag
+   */
+  protected void readConstraintsForChild(final Element element, final LwComponent component){
+    if (myLayoutSerializer != null) {
+      final Element constraintsElement = LwXmlReader.getRequiredChild(element, "constraints");
+      myLayoutSerializer.readChildConstraints(constraintsElement, component);
+    }
+  }
+
+  /**
+   * 'border' is required subtag
+   */
+  protected final void readBorder(final Element element) {
+    final Element borderElement = LwXmlReader.getRequiredChild(element, UIFormXmlConstants.ELEMENT_BORDER);
+    setBorderType(BorderType.valueOf(LwXmlReader.getRequiredString(borderElement, UIFormXmlConstants.ATTRIBUTE_TYPE)));
+
+    StringDescriptor descriptor = LwXmlReader.getStringDescriptor(borderElement,
+                                                                  UIFormXmlConstants.ATTRIBUTE_TITLE,
+                                                                  UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE,
+                                                                  UIFormXmlConstants.ATTRIBUTE_TITLE_KEY);
+    if (descriptor != null) {
+      setBorderTitle(descriptor);
+    }
+
+    myBorderTitleJustification = LwXmlReader.getOptionalInt(borderElement, UIFormXmlConstants.ATTRIBUTE_TITLE_JUSTIFICATION, 0);
+    myBorderTitlePosition = LwXmlReader.getOptionalInt(borderElement, UIFormXmlConstants.ATTRIBUTE_TITLE_POSITION, 0);
+    Element fontElement = LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_FONT);
+    if (fontElement != null) {
+      myBorderTitleFont = LwXmlReader.getFontDescriptor(fontElement);
+    }
+    myBorderTitleColor = LwXmlReader.getOptionalColorDescriptor(LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_TITLE_COLOR));
+    myBorderColor = LwXmlReader.getOptionalColorDescriptor(LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_COLOR));
+    Element sizeElement = LwXmlReader.getChild(borderElement, UIFormXmlConstants.ELEMENT_SIZE);
+    if (sizeElement != null) {
+      try {
+        myBorderSize = LwXmlReader.readInsets(sizeElement);
+      }
+      catch(Exception e) {
+        myBorderSize = null;
+      }
+    }
+  }
+
+  /**
+   * 'children' is required attribute
+   */
+  protected final void readChildren(final Element element, final PropertiesProvider provider) throws Exception{
+    final Element childrenElement = LwXmlReader.getRequiredChild(element, "children");
+    for(Iterator i=childrenElement.getChildren().iterator(); i.hasNext();){
+      final Element child = (Element)i.next();
+      final LwComponent component = createComponentFromTag(child);
+      addComponent(component);
+      component.read(child, provider);
+    }
+  }
+
+  public static LwComponent createComponentFromTag(final Element child) throws Exception {
+    final String name = child.getName();
+    final LwComponent component;
+    if("component".equals(name)){
+      final String className = LwXmlReader.getRequiredString(child, UIFormXmlConstants.ATTRIBUTE_CLASS);
+      component = new LwAtomicComponent(className);
+    }
+    else if (UIFormXmlConstants.ELEMENT_NESTED_FORM.equals(name)) {
+      component = new LwNestedForm();
+    }
+    else if("vspacer".equals(name)){
+      component = new LwVSpacer();
+    }
+    else if("hspacer".equals(name)){
+      component = new LwHSpacer();
+    }
+    else if("xy".equals(name) || "grid".equals(name)){
+      String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JPanel");
+      component = new LwContainer(className);
+    }
+    else if(UIFormXmlConstants.ELEMENT_SCROLLPANE.equals(name)) {
+      String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JScrollPane");
+      component = new LwScrollPane(className);
+    }
+    else if(UIFormXmlConstants.ELEMENT_TABBEDPANE.equals(name)){
+      String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JTabbedPane");
+      component = new LwTabbedPane(className);
+    }
+    else if(UIFormXmlConstants.ELEMENT_SPLITPANE.equals(name)){
+      String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JSplitPane");
+      component = new LwSplitPane(className);
+    }
+    else if (UIFormXmlConstants.ELEMENT_TOOLBAR.equals(name)) {
+      String className = LwXmlReader.getOptionalString(child, UIFormXmlConstants.ATTRIBUTE_CLASS, "javax.swing.JToolBar");
+      component = new LwToolBar(className);
+    }
+    else{
+      throw new UnexpectedFormElementException("unexpected element: "+child);
+    }
+    return component;
+  }
+
+  /**
+   * 'xy' or 'grid'
+   */
+  protected final void readLayout(final Element element){
+    myLayoutManager = element.getAttributeValue("layout-manager");
+    if("xy".equals(element.getName())){
+      myLayoutSerializer = XYLayoutSerializer.INSTANCE;
+    }
+    else if("grid".equals(element.getName())){
+      createLayoutSerializer();
+    }
+    else{
+      throw new UnexpectedFormElementException("unexpected element: "+element);
+    }
+    myLayoutSerializer.readLayout(element, this);
+  }
+
+  public void setLayoutManager(final String layoutManager) {
+    myLayoutManager = layoutManager;
+    createLayoutSerializer();
+  }
+
+  private void createLayoutSerializer() {
+    if (UIFormXmlConstants.LAYOUT_BORDER.equals(myLayoutManager)) {
+      myLayoutSerializer = BorderLayoutSerializer.INSTANCE;
+    }
+    else if (UIFormXmlConstants.LAYOUT_FLOW.equals(myLayoutManager)) {
+      myLayoutSerializer = FlowLayoutSerializer.INSTANCE;
+    }
+    else if (UIFormXmlConstants.LAYOUT_CARD.equals(myLayoutManager)) {
+      myLayoutSerializer = CardLayoutSerializer.INSTANCE;
+    }
+    else if (UIFormXmlConstants.LAYOUT_XY.equals(myLayoutManager)) {
+      myLayoutSerializer = XYLayoutSerializer.INSTANCE;
+    }
+    else if (UIFormXmlConstants.LAYOUT_FORM.equals(myLayoutManager)) {
+      myLayoutSerializer = FormLayoutSerializer.INSTANCE;
+    }
+    else if (UIFormXmlConstants.LAYOUT_GRIDBAG.equals(myLayoutManager)) {
+      myLayoutSerializer = GridBagLayoutSerializer.INSTANCE;      
+    }
+    else {
+      myLayoutSerializer = GridLayoutSerializer.INSTANCE;
+    }
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    readBase(element);
+
+    // Layout
+    readLayout(element);
+
+    // Constraints and properties
+    readConstraints(element);
+    readProperties(element, provider);
+
+    // Border
+    readBorder(element);
+
+    readChildren(element, provider);
+  }
+
+  protected void readNoLayout(final Element element, final PropertiesProvider provider) throws Exception {
+    readBase(element);
+
+    // Constraints and properties
+    readConstraints(element);
+    readProperties(element, provider);
+
+    // Border
+    readBorder(element);
+
+    readChildren(element, provider);
+  }
+
+  public boolean areChildrenExclusive() {
+    return UIFormXmlConstants.LAYOUT_CARD.equals(myLayoutManager);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwHSpacer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwHSpacer.java
new file mode 100644
index 0000000..4be52ac
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwHSpacer.java
@@ -0,0 +1,33 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class LwHSpacer extends LwAtomicComponent {
+  public LwHSpacer() throws Exception{
+    super("com.intellij.uiDesigner.core.Spacer");
+  }
+  
+  public void read(final Element element, final PropertiesProvider provider) throws Exception{
+    readBase(element);
+    readConstraints(element);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwInspectionSuppression.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwInspectionSuppression.java
new file mode 100644
index 0000000..e0722c8
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwInspectionSuppression.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.uiDesigner.lw;
+
+/**
+ * @author yole
+ */
+public class LwInspectionSuppression {
+  public static final LwInspectionSuppression[] EMPTY_ARRAY = new LwInspectionSuppression[0];
+
+  private final String myInspectionId;
+  private final String myComponentId;
+
+  public LwInspectionSuppression(final String inspectionId, final String componentId) {
+    myInspectionId = inspectionId;
+    myComponentId = componentId;
+  }
+
+  public String getInspectionId() {
+    return myInspectionId;
+  }
+
+  public String getComponentId() {
+    return myComponentId;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroBooleanProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroBooleanProperty.java
new file mode 100644
index 0000000..394beb7
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroBooleanProperty.java
@@ -0,0 +1,30 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+public final class LwIntroBooleanProperty extends LwIntrospectedProperty {
+  public LwIntroBooleanProperty(final String name){
+    super(name, Boolean.class.getName());
+  }
+
+  public Object read(final Element element) throws Exception{
+    return Boolean.valueOf(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE));
+  }
+}
+
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroCharProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroCharProperty.java
new file mode 100644
index 0000000..cb5287c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroCharProperty.java
@@ -0,0 +1,14 @@
+package com.intellij.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+public final class LwIntroCharProperty extends LwIntrospectedProperty {
+  public LwIntroCharProperty(final String name){
+    super(name, Character.class.getName());
+  }
+
+  public Object read(final Element element) throws Exception{
+    return Character.valueOf(LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE).charAt(0));
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroColorProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroColorProperty.java
new file mode 100644
index 0000000..d310928
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroColorProperty.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author yole
+ */
+public class LwIntroColorProperty extends LwIntrospectedProperty {
+  public LwIntroColorProperty(final String name) {
+    super(name, "java.awt.Color");
+  }
+
+  public Object read(Element element) throws Exception {
+    return LwXmlReader.getColorDescriptor(element);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroComponentProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroComponentProperty.java
new file mode 100644
index 0000000..660e5ec
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroComponentProperty.java
@@ -0,0 +1,32 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+/**
+ * @author yole
+ */
+public class LwIntroComponentProperty extends LwIntrospectedProperty {
+  public LwIntroComponentProperty(final String name, final String propertyClassName) {
+    super(name, propertyClassName);
+  }
+
+  public Object read(Element element) throws Exception {
+    return LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroDimensionProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroDimensionProperty.java
new file mode 100644
index 0000000..e150c84
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroDimensionProperty.java
@@ -0,0 +1,35 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author Anton Katilin
+ */
+public final class LwIntroDimensionProperty extends LwIntrospectedProperty {
+  public LwIntroDimensionProperty(final String name){
+    super(name, "java.awt.Dimension");
+  }
+
+  public Object read(final Element element) throws Exception{
+    final int width = LwXmlReader.getRequiredInt(element, "width");
+    final int height = LwXmlReader.getRequiredInt(element, "height");
+    return new Dimension(width, height);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroEnumProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroEnumProperty.java
new file mode 100644
index 0000000..ff2ac74
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroEnumProperty.java
@@ -0,0 +1,44 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.lang.reflect.Method;
+
+/**
+ * @author yole
+ */
+public class LwIntroEnumProperty extends LwIntrospectedProperty {
+  private final Class myEnumClass;
+
+  public LwIntroEnumProperty(final String name, final Class enumClass) {
+    super(name, enumClass.getName());
+    myEnumClass = enumClass;
+  }
+
+  public Object read(Element element) throws Exception {
+    String value = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_VALUE);
+    final Method method = myEnumClass.getMethod("valueOf", new Class[] { String.class} );
+    return method.invoke(null, new Object[] { value } );
+  }
+
+  public String getCodeGenPropertyClassName() {
+    return "java.lang.Enum";
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroFontProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroFontProperty.java
new file mode 100644
index 0000000..01e1151
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroFontProperty.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author yole
+ */
+public class LwIntroFontProperty extends LwIntrospectedProperty {
+  public LwIntroFontProperty(final String name) {
+    super(name, "java.awt.Font");
+  }
+
+  public Object read(Element element) throws Exception {
+    return LwXmlReader.getFontDescriptor(element);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIconProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIconProperty.java
new file mode 100644
index 0000000..3fcd11c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIconProperty.java
@@ -0,0 +1,33 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+/**
+ * @author yole
+ */
+public class LwIntroIconProperty extends LwIntrospectedProperty {
+  public LwIntroIconProperty(final String name) {
+    super(name, "javax.swing.Icon");
+  }
+
+  public Object read(Element element) throws Exception {
+    String value = LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_VALUE);
+    return new IconDescriptor(value);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroInsetsProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroInsetsProperty.java
new file mode 100644
index 0000000..826577c
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroInsetsProperty.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public final class LwIntroInsetsProperty extends LwIntrospectedProperty{
+  public LwIntroInsetsProperty(final String name){
+    super(name, "java.awt.Insets");
+  }
+
+  public Object read(final Element element) throws Exception{
+    return LwXmlReader.readInsets(element);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIntProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIntProperty.java
new file mode 100644
index 0000000..d6b9857
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroIntProperty.java
@@ -0,0 +1,28 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+public final class LwIntroIntProperty extends LwIntrospectedProperty {
+  public LwIntroIntProperty(final String name){
+    super(name, Integer.class.getName());
+  }
+
+  public Object read(final Element element) throws Exception{
+    return new Integer(LwXmlReader.getRequiredInt(element, "value"));
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroListModelProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroListModelProperty.java
new file mode 100644
index 0000000..1c5fddd
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroListModelProperty.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.util.List;
+
+/**
+ * @author yole
+ */
+public class LwIntroListModelProperty extends LwIntrospectedProperty {
+  public LwIntroListModelProperty(final String name, final String propertyClassName) {
+    super(name, propertyClassName);
+  }
+
+  public Object read(Element element) throws Exception {
+    final List list = element.getChildren(UIFormXmlConstants.ELEMENT_ITEM, element.getNamespace());
+    String[] result = new String[list.size()];
+    for(int i=0; i<list.size(); i++) {
+      Element itemElement = (Element) list.get(i);
+      result [i] = LwXmlReader.getRequiredString(itemElement, UIFormXmlConstants.ATTRIBUTE_VALUE);
+    }
+    return result;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroPrimitiveTypeProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroPrimitiveTypeProperty.java
new file mode 100644
index 0000000..da7c160
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroPrimitiveTypeProperty.java
@@ -0,0 +1,17 @@
+package com.intellij.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+public final class LwIntroPrimitiveTypeProperty extends LwIntrospectedProperty {
+  private final Class myValueClass;
+
+  public LwIntroPrimitiveTypeProperty(final String name, final Class valueClass){
+    super(name, valueClass.getName());
+    myValueClass = valueClass;
+  }
+
+  public Object read(final Element element) throws Exception{
+    return LwXmlReader.getRequiredPrimitiveTypeValue(element, UIFormXmlConstants.ATTRIBUTE_VALUE, myValueClass);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroRectangleProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroRectangleProperty.java
new file mode 100644
index 0000000..d43a499
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntroRectangleProperty.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public final class LwIntroRectangleProperty extends LwIntrospectedProperty{
+  public LwIntroRectangleProperty(final String name){
+    super(name, "java.awt.Rectangle");
+  }
+
+  public Object read(final Element element) throws Exception{
+    final int x = LwXmlReader.getRequiredInt(element, "x");
+    final int y = LwXmlReader.getRequiredInt(element, "y");
+    final int width = LwXmlReader.getRequiredInt(element, "width");
+    final int height = LwXmlReader.getRequiredInt(element, "height");
+    return new Rectangle(x, y, width, height);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntrospectedProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntrospectedProperty.java
new file mode 100644
index 0000000..c39f97b
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwIntrospectedProperty.java
@@ -0,0 +1,89 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+public abstract class LwIntrospectedProperty implements IProperty {
+
+  private final String myName;
+  private final String myPropertyClassName;
+  private String myDeclaringClassName;
+
+  public LwIntrospectedProperty(
+    final String name,
+    final String propertyClassName
+  ){
+    if (name == null){
+      throw new IllegalArgumentException("name cannot be null");
+    }
+    if (propertyClassName == null){
+      throw new IllegalArgumentException("propertyClassName cannot be null");
+    }
+
+    myName = name;
+    myPropertyClassName = propertyClassName;
+  }
+
+  /**
+   * @return never null
+   */ 
+  public final String getName(){
+    return myName;
+  }
+
+  /**
+   * @return never null
+   */ 
+  public final String getPropertyClassName(){
+    return myPropertyClassName;
+  }
+  
+  public final String getReadMethodName() {
+    return "get" + Character.toUpperCase(myName.charAt(0)) + myName.substring(1);
+  }
+
+  public final String getWriteMethodName() {
+    return "set" + Character.toUpperCase(myName.charAt(0)) + myName.substring(1);
+  }
+
+  public String getDeclaringClassName() {
+    return myDeclaringClassName;
+  }
+
+  public void setDeclaringClassName(final String definingClassName) {
+    myDeclaringClassName = definingClassName;
+  }
+
+  /**
+   * @param element element that contains serialized property data. This element was
+   * written by {@link com.intellij.uiDesigner.propertyInspector.IntrospectedProperty#write(Object, com.intellij.uiDesigner.XmlWriter)}
+   * method. So <code>read</code> and <code>write</code> methods should be consistent.
+   *
+   * @return property value. Should never return <code>null</code>. For example,
+   * value can be <code>java.lang.Integer</code> for <code>IntroIntProperty</code>.
+   *
+   */
+  public abstract Object read(Element element) throws Exception;
+
+  public Object getPropertyValue(final IComponent component) {
+    return ((LwComponent) component).getPropertyValue(this);
+  }
+
+  public String getCodeGenPropertyClassName() {
+    return getPropertyClassName();
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwNestedForm.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwNestedForm.java
new file mode 100644
index 0000000..11dcb14
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwNestedForm.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+/**
+ * @author yole
+ */
+public class LwNestedForm extends LwComponent {
+  private String myFormFileName;
+
+  public LwNestedForm() {
+    super("");
+  }
+
+  public void read(Element element, PropertiesProvider provider) throws Exception {
+    myFormFileName = LwXmlReader.getRequiredString(element, UIFormXmlConstants.ATTRIBUTE_FORM_FILE);
+    readBase(element);
+    readConstraints(element);
+  }
+
+  public String getFormFileName() {
+    return myFormFileName;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRbIntroStringProperty.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRbIntroStringProperty.java
new file mode 100644
index 0000000..d12187b
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRbIntroStringProperty.java
@@ -0,0 +1,43 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.UIFormXmlConstants;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public final class LwRbIntroStringProperty extends LwIntrospectedProperty {
+  public LwRbIntroStringProperty(final String name){
+    super(name, String.class.getName());
+  }
+
+  /**
+   * @return instance of {@link com.intellij.uiDesigner.lw.StringDescriptor}
+   */
+  public Object read(final Element element) throws Exception{
+    final StringDescriptor descriptor = LwXmlReader.getStringDescriptor(element,
+                                                                        UIFormXmlConstants.ATTRIBUTE_VALUE,
+                                                                        UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE,
+                                                                        UIFormXmlConstants.ATTRIBUTE_KEY);
+    if (descriptor == null) {
+      throw new IllegalArgumentException("String descriptor value required");
+    }
+    return descriptor;
+  }
+}
+
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRootContainer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRootContainer.java
new file mode 100644
index 0000000..3ee850e
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwRootContainer.java
@@ -0,0 +1,148 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import com.intellij.uiDesigner.compiler.AlienFormFileException;
+import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
+import com.intellij.uiDesigner.compiler.Utils;
+import org.jdom.Element;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+  */
+public final class LwRootContainer extends LwContainer implements IRootContainer{
+  private String myClassToBind;
+  private String myMainComponentBinding;
+  private final ArrayList myButtonGroups = new ArrayList();
+  private final ArrayList myInspectionSuppressions = new ArrayList();
+
+  public LwRootContainer() throws Exception{
+    super("javax.swing.JPanel");
+    myLayoutSerializer = XYLayoutSerializer.INSTANCE;
+  }
+
+  public String getMainComponentBinding(){
+    return myMainComponentBinding;
+  }
+
+  public String getClassToBind(){
+    return myClassToBind;
+  }
+
+  public void setClassToBind(final String classToBind) {
+    myClassToBind = classToBind;
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    if (element == null) {
+      throw new IllegalArgumentException("element cannot be null");
+    }
+    if (!Utils.FORM_NAMESPACE.equals(element.getNamespace().getURI())) {
+      throw new AlienFormFileException();
+    }
+    if(!"form".equals(element.getName())){
+      throw new UnexpectedFormElementException("unexpected element: "+element);
+    }
+
+    setId("root");
+
+    myClassToBind = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_BIND_TO_CLASS);
+
+    // Constraints and properties
+    for(Iterator i=element.getChildren().iterator(); i.hasNext();){
+      final Element child = (Element)i.next();
+      if (child.getName().equals(UIFormXmlConstants.ELEMENT_BUTTON_GROUPS)) {
+        readButtonGroups(child);
+      }
+      else if (child.getName().equals(UIFormXmlConstants.ELEMENT_INSPECTION_SUPPRESSIONS)) {
+        readInspectionSuppressions(child);
+      }
+      else {
+        final LwComponent component = createComponentFromTag(child);
+        addComponent(component);
+        component.read(child, provider);
+      }
+    }
+
+    myMainComponentBinding = element.getAttributeValue("stored-main-component-binding");
+  }
+
+  private void readButtonGroups(final Element element) {
+    for(Iterator i=element.getChildren().iterator(); i.hasNext();){
+      final Element child = (Element)i.next();
+      LwButtonGroup group = new LwButtonGroup();
+      group.read(child);
+      myButtonGroups.add(group);
+    }
+  }
+
+  private void readInspectionSuppressions(final Element element) {
+    for(Iterator i=element.getChildren().iterator(); i.hasNext();){
+      final Element child = (Element)i.next();
+      String inspectionId = LwXmlReader.getRequiredString(child, UIFormXmlConstants.ATTRIBUTE_INSPECTION);
+      String componentId = LwXmlReader.getString(child, UIFormXmlConstants.ATTRIBUTE_ID);
+      myInspectionSuppressions.add(new LwInspectionSuppression(inspectionId, componentId));
+    }
+  }
+
+  public IButtonGroup[] getButtonGroups() {
+    return (LwButtonGroup[])myButtonGroups.toArray(new LwButtonGroup[myButtonGroups.size()]);
+  }
+
+  public String getButtonGroupName(IComponent component) {
+    for(int i=0; i<myButtonGroups.size(); i++) {
+      LwButtonGroup group = (LwButtonGroup) myButtonGroups.get(i);
+      final String[] ids = group.getComponentIds();
+      for(int j=0; j<ids.length; j++) {
+        if (ids [j].equals(component.getId())) {
+          return group.getName();
+        }
+      }
+    }
+    return null;
+  }
+
+  public String[] getButtonGroupComponentIds(String groupName) {
+    for(int i=0; i<myButtonGroups.size(); i++) {
+      LwButtonGroup group = (LwButtonGroup) myButtonGroups.get(i);
+      if (group.getName().equals(groupName)) {
+        return group.getComponentIds();
+      }
+    }
+    throw new IllegalArgumentException("Cannot find group " + groupName);
+  }
+
+  public boolean isInspectionSuppressed(final String inspectionId, final String componentId) {
+    for (Iterator iterator = myInspectionSuppressions.iterator(); iterator.hasNext();) {
+      LwInspectionSuppression suppression = (LwInspectionSuppression)iterator.next();
+      if ((suppression.getComponentId() == null || suppression.getComponentId().equals(componentId)) &&
+          suppression.getInspectionId().equals(inspectionId)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public LwInspectionSuppression[] getInspectionSuppressions() {
+    return (LwInspectionSuppression[]) myInspectionSuppressions.toArray(new LwInspectionSuppression[myInspectionSuppressions.size()]);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwScrollPane.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwScrollPane.java
new file mode 100644
index 0000000..1a68041
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwScrollPane.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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class LwScrollPane extends LwContainer {
+  public LwScrollPane(String className) {
+    super(className);
+  }
+
+  protected LayoutManager createInitialLayout(){
+    return null;
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    readNoLayout(element, provider);
+  }
+
+  protected void readConstraintsForChild(final Element element, final LwComponent component) {}
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwSplitPane.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwSplitPane.java
new file mode 100644
index 0000000..edf0828
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwSplitPane.java
@@ -0,0 +1,57 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class LwSplitPane extends LwContainer{
+  public static final String POSITION_LEFT = "left";
+  public static final String POSITION_RIGHT = "right";
+
+  public LwSplitPane(String className) {
+    super(className);
+  }
+
+  protected LayoutManager createInitialLayout(){
+    return null;
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    readNoLayout(element, provider);
+  }
+
+  protected void readConstraintsForChild(final Element element, final LwComponent component) {
+    final Element constraintsElement = LwXmlReader.getRequiredChild(element, "constraints");
+    final Element splitterChild = LwXmlReader.getRequiredChild(constraintsElement, "splitpane");
+    final String position = LwXmlReader.getRequiredString(splitterChild, "position");
+    if ("left".equals(position)) {
+      component.setCustomLayoutConstraints(POSITION_LEFT);
+    }
+    else if ("right".equals(position)) {
+      component.setCustomLayoutConstraints(POSITION_RIGHT);
+    }
+    else {
+      throw new UnexpectedFormElementException("unexpected position: " + position);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwTabbedPane.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwTabbedPane.java
new file mode 100644
index 0000000..2414857
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwTabbedPane.java
@@ -0,0 +1,114 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class LwTabbedPane extends LwContainer implements ITabbedPane {
+  public LwTabbedPane(String className) {
+    super(className);
+  }
+
+  protected LayoutManager createInitialLayout() {
+    return null;
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    readNoLayout(element, provider);
+  }
+
+  protected void readConstraintsForChild(final Element element, final LwComponent component) {
+    final Element constraintsElement = LwXmlReader.getRequiredChild(element, UIFormXmlConstants.ELEMENT_CONSTRAINTS);
+    final Element tabbedPaneChild = LwXmlReader.getRequiredChild(constraintsElement, UIFormXmlConstants.ELEMENT_TABBEDPANE);
+
+    final StringDescriptor descriptor = LwXmlReader.getStringDescriptor(tabbedPaneChild,
+                                                                        UIFormXmlConstants.ATTRIBUTE_TITLE,
+                                                                        UIFormXmlConstants.ATTRIBUTE_TITLE_RESOURCE_BUNDLE,
+                                                                        UIFormXmlConstants.ATTRIBUTE_TITLE_KEY);
+    if (descriptor == null) {
+      throw new IllegalArgumentException("String descriptor value required");
+    }
+    final Constraints constraints = new Constraints(descriptor);
+
+    final Element tooltipElement = LwXmlReader.getChild(tabbedPaneChild, UIFormXmlConstants.ELEMENT_TOOLTIP);
+    if (tooltipElement != null) {
+      constraints.myToolTip = LwXmlReader.getStringDescriptor(tooltipElement,
+                                                              UIFormXmlConstants.ATTRIBUTE_VALUE,
+                                                              UIFormXmlConstants.ATTRIBUTE_RESOURCE_BUNDLE,
+                                                              UIFormXmlConstants.ATTRIBUTE_KEY);
+    }
+
+    String icon = tabbedPaneChild.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_ICON);
+    if (icon != null) {
+      constraints.myIcon = new IconDescriptor(icon);
+    }
+    icon = tabbedPaneChild.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_DISABLED_ICON);
+    if (icon != null) {
+      constraints.myDisabledIcon = new IconDescriptor(icon);
+    }
+    constraints.myEnabled = LwXmlReader.getOptionalBoolean(tabbedPaneChild, UIFormXmlConstants.ATTRIBUTE_ENABLED, true);
+
+    component.setCustomLayoutConstraints(constraints);
+  }
+
+  public static final class Constraints {
+    /**
+     * never null
+     */
+    public StringDescriptor myTitle;
+    public StringDescriptor myToolTip;
+    public IconDescriptor myIcon;
+    public IconDescriptor myDisabledIcon;
+    public boolean myEnabled = true;
+
+    public Constraints(final StringDescriptor title){
+      if (title == null){
+        throw new IllegalArgumentException("title cannot be null");
+      }
+      myTitle = title;
+    }
+
+    public StringDescriptor getProperty(final String propName) {
+      if (propName.equals(TAB_TITLE_PROPERTY)) {
+        return myTitle;
+      }
+      if (propName.equals(TAB_TOOLTIP_PROPERTY)) {
+        return myToolTip;
+      }
+      throw new IllegalArgumentException("Unknown property name " + propName);
+    }
+  }
+
+  public StringDescriptor getTabProperty(IComponent component, final String propName) {
+    LwComponent lwComponent = (LwComponent) component;
+    LwTabbedPane.Constraints constraints = (LwTabbedPane.Constraints) lwComponent.getCustomLayoutConstraints();
+    if (constraints == null) {
+      return null;
+    }
+    return constraints.getProperty(propName);
+  }
+
+  public boolean areChildrenExclusive() {
+    return true;
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwToolBar.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwToolBar.java
new file mode 100644
index 0000000..1849b14
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwToolBar.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class LwToolBar extends LwContainer {
+  public LwToolBar(String className) {
+    super(className);
+  }
+
+  protected LayoutManager createInitialLayout() {
+    return null;
+  }
+
+  public void read(final Element element, final PropertiesProvider provider) throws Exception {
+    readNoLayout(element, provider);
+  }
+
+  protected void readConstraintsForChild(final Element element, final LwComponent component) {
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwVSpacer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwVSpacer.java
new file mode 100644
index 0000000..71ef7cb
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwVSpacer.java
@@ -0,0 +1,33 @@
+/*
+ * 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.uiDesigner.lw;
+
+import org.jdom.Element;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class LwVSpacer extends LwAtomicComponent {
+  public LwVSpacer() throws Exception{
+    super("com.intellij.uiDesigner.core.Spacer");
+  }
+  
+  public void read(final Element element, final PropertiesProvider provider) throws Exception{
+    readBase(element);
+    readConstraints(element);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwXmlReader.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwXmlReader.java
new file mode 100644
index 0000000..e8e84df
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/LwXmlReader.java
@@ -0,0 +1,220 @@
+/*
+ * 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.uiDesigner.lw;
+
+import com.intellij.uiDesigner.UIFormXmlConstants;
+import org.jdom.Attribute;
+import org.jdom.Element;
+
+import java.awt.*;
+import java.lang.reflect.Method;
+
+public final class LwXmlReader {
+  private LwXmlReader() {
+  }
+
+  /**
+   * @return can be <code>null</code>.
+   */
+  public static Element getChild(final Element element, final String childName) {
+    return element.getChild(childName, element.getNamespace());
+  }
+
+  /**
+   * @return never <code>null</code>.
+   */
+  public static Element getRequiredChild(final Element element, final String childName) {
+    final Element child = getChild(element, childName);
+    if(child == null){
+      throw new IllegalArgumentException("subtag '" + childName + "' is required: "+element);
+    }
+    return child;
+  }
+
+  /**
+   * @return <code>null</code> or trimmed attribute value.
+   */
+  public static String getString(final Element element, final String attributeName){
+    final String value = element.getAttributeValue(attributeName);
+    return value != null ? value.trim() : null;
+  }
+
+  /**
+   * @return never <code>null</code> trimmed attribute value.
+   */
+  public static String getRequiredString(final Element element, final String attributeName) {
+    final String value = getString(element, attributeName);
+    if(value != null){
+      return value;
+    }
+    else{
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is required: "+element);
+    }
+  }
+
+  public static String getOptionalString(final Element element, final String attributeName, final String defaultValue) {
+    final String value = element.getAttributeValue(attributeName);
+    return value != null ? value.trim() : defaultValue;
+  }
+
+  public static int getRequiredInt(final Element element, final String attributeName) {
+    final String str = getRequiredString(element, attributeName);
+    try {
+      return Integer.parseInt(str);
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper integer: " + str);
+    }
+  }
+
+  public static int getOptionalInt(final Element element, final String attributeName, final int defaultValue) {
+    final String str = element.getAttributeValue(attributeName);
+    if (str == null) {
+      return defaultValue;
+    }
+    try {
+      return Integer.parseInt(str);
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper integer: " + str);
+    }
+  }
+
+  public static boolean getOptionalBoolean(final Element element, final String attributeName, final boolean defaultValue) {
+    final String str = element.getAttributeValue(attributeName);
+    if (str == null) {
+      return defaultValue;
+    }
+    return Boolean.valueOf(str).booleanValue();
+  }
+
+  public static double getRequiredDouble(final Element element, final String attributeName) {
+    final String str = getRequiredString(element, attributeName);
+    try {
+      return Double.parseDouble(str);
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper double: " + str);
+    }
+  }
+
+  public static double getOptionalDouble(final Element element, final String attributeName, double defaultValue) {
+    final String str = element.getAttributeValue(attributeName);
+    if (str == null) {
+      return defaultValue;
+    }
+    try {
+      return Double.parseDouble(str);
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper double: " + str);
+    }
+  }
+
+  public static float getRequiredFloat(final Element element, final String attributeName) {
+    final String str = getRequiredString(element, attributeName);
+    try {
+      return Float.parseFloat(str);
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper float: " + str);
+    }
+  }
+
+  public static Object getRequiredPrimitiveTypeValue(final Element element, final String attributeName, final Class valueClass) {
+    final String str = getRequiredString(element, attributeName);
+    try {
+      final Method method = valueClass.getMethod("valueOf", new Class[]{String.class});
+      //noinspection unchecked
+      return method.invoke(null, new Object[]{str});
+    }
+    catch (NumberFormatException e) {
+      throw new IllegalArgumentException("attribute '" + attributeName + "' is not a proper float: " + str);
+    }
+    catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static StringDescriptor getStringDescriptor(final Element element, final String valueAttr,
+                                                     final String bundleAttr, final String keyAttr) {
+    final String title = element.getAttributeValue(valueAttr);
+    if (title != null) {
+      StringDescriptor descriptor = StringDescriptor.create(title);
+      descriptor.setNoI18n(getOptionalBoolean(element, UIFormXmlConstants.ATTRIBUTE_NOI18N, false));
+      return descriptor;
+    }
+    else {
+      final String bundle = element.getAttributeValue(bundleAttr);
+      if (bundle != null) {
+        final String key = getRequiredString(element, keyAttr);
+        return new StringDescriptor(bundle, key);
+      }
+    }
+
+    return null;
+  }
+
+  public static FontDescriptor getFontDescriptor(final Element element) {
+    String swingFont = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SWING_FONT);
+    if (swingFont != null) {
+      return FontDescriptor.fromSwingFont(swingFont);
+    }
+
+    String fontName = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_NAME);
+    int fontStyle = getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_STYLE, -1);
+    int fontSize = getOptionalInt(element, UIFormXmlConstants.ATTRIBUTE_SIZE, -1);
+    return new FontDescriptor(fontName, fontStyle, fontSize);
+  }
+
+  public static ColorDescriptor getColorDescriptor(final Element element) throws Exception {
+    Attribute attr = element.getAttribute(UIFormXmlConstants.ATTRIBUTE_COLOR);
+    if (attr != null) {
+      return new ColorDescriptor(new Color(attr.getIntValue()));
+    }
+    String swingColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SWING_COLOR);
+    if (swingColor != null) {
+      return ColorDescriptor.fromSwingColor(swingColor);
+    }
+    String systemColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_SYSTEM_COLOR);
+    if (systemColor != null) {
+      return ColorDescriptor.fromSystemColor(systemColor);
+    }
+    String awtColor = element.getAttributeValue(UIFormXmlConstants.ATTRIBUTE_AWT_COLOR);
+    if (awtColor != null) {
+      return ColorDescriptor.fromAWTColor(awtColor);
+    }
+    return new ColorDescriptor(null);
+  }
+
+  public static ColorDescriptor getOptionalColorDescriptor(final Element element) {
+    if (element == null) return null;
+    try {
+      return getColorDescriptor(element);
+    }
+    catch(Exception ex) {
+      return null;
+    }
+  }
+
+  public static Insets readInsets(final Element element) {
+    final int top = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_TOP);
+    final int left = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_LEFT);
+    final int bottom = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_BOTTOM);
+    final int right = getRequiredInt(element, UIFormXmlConstants.ATTRIBUTE_RIGHT);
+    return new Insets(top, left, bottom, right);
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/PropertiesProvider.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/PropertiesProvider.java
new file mode 100644
index 0000000..e342631
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/PropertiesProvider.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.uiDesigner.lw;
+
+import java.util.HashMap;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+
+public interface PropertiesProvider {
+  /**
+   * @return key - property name (String), value - LwProperty. If class cannot be inspected for some reason,
+   * returns null 
+   */
+  HashMap getLwProperties(String className);
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/StringDescriptor.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/StringDescriptor.java
new file mode 100644
index 0000000..dd46dda
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/StringDescriptor.java
@@ -0,0 +1,150 @@
+/*
+ * 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.uiDesigner.lw;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public final class StringDescriptor {
+  /**
+   * Name of resource bundle
+   */
+  private final String myBundleName;
+  /**
+   * Key in the resource bundle
+   */
+  private final String myKey;
+  /**
+   * Value has sense if it's calculated not via resource bundle
+   */
+  private final String myValue;
+  /**
+   * Cached resolved value. We need it here to speed up property inspector
+   * painting.
+   */
+  private String myResolvedValue;
+
+  /**
+   * Marker for string values which do not need internationalization
+   */
+  private boolean myNoI18n;
+
+  private StringDescriptor(final String value){
+    if (value == null) {
+      throw new IllegalArgumentException("value cannot be null");
+    }
+    myBundleName = null;
+    myKey = null;
+    myValue = value;
+  }
+
+  public StringDescriptor(final String bundleName, final String key) {
+    if (bundleName == null) {
+      throw new IllegalArgumentException("bundleName cannot be null");
+    }
+    if (key == null) {
+      throw new IllegalArgumentException("key cannot be null");
+    }
+    myBundleName = bundleName.replace('.', '/');
+    myKey = key;
+    myValue = null;
+  }
+
+  /**
+   * Creates "trivial" StringDescriptor.
+   */
+  public static StringDescriptor create(final String value){
+    return value != null ? new StringDescriptor(value) : null;
+  }
+
+  /**
+   * @return not <code>null</code> value if this is "trivial" StringDescriptor.
+   * If StringDescriptor is "trivial" then {@link #getBundleName()} and {@link #getKey()}
+   * return <code>null</code>.
+   */
+  public String getValue(){
+    return myValue;
+  }
+
+  /**
+   * @return not <code>null</code> value if this is non "trivial" StringDescriptor.
+   */
+  public String getBundleName() {
+    return myBundleName;
+  }
+
+  public String getDottedBundleName() {
+    return myBundleName == null ? null : myBundleName.replace('/', '.');
+  }
+
+  /**
+   * @return not <code>null</code> value if this is non "trivial" StringDescriptor.
+   */
+  public String getKey() {
+    return myKey;
+  }
+
+  /**
+   * @return can be null
+   */
+  public String getResolvedValue() {
+    return myResolvedValue;
+  }
+
+  /**
+   * @param resolvedValue can be null
+   */
+  public void setResolvedValue(final String resolvedValue) {
+    myResolvedValue = resolvedValue;
+  }
+
+  public boolean isNoI18n() {
+    return myNoI18n;
+  }
+
+  public void setNoI18n(final boolean noI18n) {
+    myNoI18n = noI18n;
+  }
+
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (!(o instanceof StringDescriptor)) return false;
+
+    final StringDescriptor descriptor = (StringDescriptor)o;
+
+    if (myBundleName != null ? !myBundleName.equals(descriptor.myBundleName) : descriptor.myBundleName != null) return false;
+    if (myKey != null ? !myKey.equals(descriptor.myKey) : descriptor.myKey != null) return false;
+    if (myValue != null ? !myValue.equals(descriptor.myValue) : descriptor.myValue != null) return false;
+    if (myNoI18n != descriptor.myNoI18n) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = (myBundleName != null ? myBundleName.hashCode() : 0);
+    result = 29 * result + (myKey != null ? myKey.hashCode() : 0);
+    result = 29 * result + (myValue != null ? myValue.hashCode() : 0);
+    return result;
+  }
+
+  public String toString() {
+    if (myValue != null) {
+      return "[StringDescriptor:" + myValue + "]";
+    }
+    return "[StringDescriptor" + myBundleName + ":" + myKey + "]";
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/XYLayoutSerializer.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/XYLayoutSerializer.java
new file mode 100644
index 0000000..f637d8f
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/lw/XYLayoutSerializer.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.uiDesigner.lw;
+
+import org.jdom.Element;
+import com.intellij.uiDesigner.shared.XYLayoutManager;
+
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class XYLayoutSerializer extends LayoutSerializer {
+  static XYLayoutSerializer INSTANCE = new XYLayoutSerializer();
+
+  private XYLayoutSerializer() {
+  }
+
+  void readLayout(Element element, LwContainer container) {
+    container.setLayout(new XYLayoutManager());
+  }
+
+  void readChildConstraints(final Element constraintsElement, final LwComponent component) {
+    final Element xyElement = LwXmlReader.getChild(constraintsElement, "xy");
+    if(xyElement != null){
+      component.setBounds(
+        new Rectangle(
+          LwXmlReader.getRequiredInt(xyElement, "x"),
+          LwXmlReader.getRequiredInt(xyElement, "y"),
+          LwXmlReader.getRequiredInt(xyElement, "width"),
+          LwXmlReader.getRequiredInt(xyElement, "height")
+        )
+      );
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/BorderType.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/BorderType.java
new file mode 100644
index 0000000..fe72072
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/BorderType.java
@@ -0,0 +1,111 @@
+/*
+ * 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.uiDesigner.shared;
+
+import com.intellij.uiDesigner.compiler.UnexpectedFormElementException;
+
+import javax.swing.*;
+import javax.swing.border.Border;
+import java.awt.*;
+
+/**
+ * @author Vladimir Kondratyev
+ */
+public final class BorderType {
+  public static final BorderType NONE = new BorderType("none", "None",null,null);
+  public static final BorderType BEVEL_LOWERED = new BorderType("bevel-lowered", "Bevel Lowered", BorderFactory.createLoweredBevelBorder(), "createLoweredBevelBorder");
+  public static final BorderType BEVEL_RAISED = new BorderType("bevel-raised", "Bevel Raised", BorderFactory.createRaisedBevelBorder(), "createRaisedBevelBorder");
+  public static final BorderType ETCHED = new BorderType("etched", "Etched", BorderFactory.createEtchedBorder(), "createEtchedBorder");
+  public static final BorderType LINE = new BorderType("line", "Line", BorderFactory.createLineBorder(Color.BLACK), "createLineBorder");
+  public static final BorderType EMPTY = new BorderType("empty", "Empty", BorderFactory.createEmptyBorder(0, 0, 0, 0), "createEmptyBorder");
+
+  private final String myId;
+  private final String myName;
+  private final Border myBorder;
+  private final String myBorderFactoryMethodName;
+
+  private BorderType(final String id, final String name, final Border border, final String borderFactoryMethodName) {
+    myId=id;
+    myName=name;
+    myBorder=border;
+    myBorderFactoryMethodName = borderFactoryMethodName;
+  }
+
+  public String getId(){
+    return myId;
+  }
+
+  public String getName(){
+    return myName;
+  }
+
+  public Border createBorder(final String title,
+                             final int titleJustification,
+                             final int titlePosition,
+                             final Font titleFont,
+                             final Color titleColor,
+                             final Insets borderSize, 
+                             final Color borderColor) {
+    Border baseBorder = myBorder;
+    if (equals(EMPTY) && borderSize != null) {
+      baseBorder = BorderFactory.createEmptyBorder(borderSize.top, borderSize.left, borderSize.bottom, borderSize.right);
+    }
+    else if (equals(LINE) && borderColor != null) {
+      baseBorder = BorderFactory.createLineBorder(borderColor);
+    }
+
+    if (title != null) {
+      return BorderFactory.createTitledBorder(baseBorder, title, titleJustification, titlePosition, titleFont, titleColor);
+    }
+    else {
+      return baseBorder;
+    }
+  }
+
+  public String getBorderFactoryMethodName(){
+    return myBorderFactoryMethodName;
+  }
+
+  public boolean equals(final Object o){
+    if (o instanceof BorderType){
+      return myId.equals(((BorderType)o).myId);
+    }
+    return false;
+  }
+
+  public int hashCode(){
+    return 0;
+  }
+
+  public static BorderType valueOf(final String name){
+    BorderType[] allTypes = getAllTypes();
+    for(int i=0; i<allTypes.length; i++) {
+      if (allTypes [i].getId().equals(name)) return allTypes [i];
+    }
+    throw new UnexpectedFormElementException("unknown type: "+name);
+  }
+
+  public static BorderType[] getAllTypes() {
+    return new BorderType[]{
+          BorderType.NONE,
+          BorderType.EMPTY,
+          BorderType.BEVEL_LOWERED,
+          BorderType.BEVEL_RAISED,
+          BorderType.ETCHED,
+          BorderType.LINE
+        };
+  }
+}
diff --git a/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/XYLayoutManager.java b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/XYLayoutManager.java
new file mode 100644
index 0000000..bdc5a41
--- /dev/null
+++ b/java/compiler/forms-compiler/src/com/intellij/uiDesigner/shared/XYLayoutManager.java
@@ -0,0 +1,48 @@
+/*
+ * 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.uiDesigner.shared;
+
+import com.intellij.uiDesigner.core.AbstractLayout;
+
+import java.awt.*;
+
+public class XYLayoutManager extends AbstractLayout {
+  public XYLayoutManager(){
+  }
+
+  public Dimension maximumLayoutSize(final Container target){
+    throw new UnsupportedOperationException();
+  }
+
+  public Dimension preferredLayoutSize(final Container parent){
+    throw new UnsupportedOperationException();
+  }
+
+  public Dimension minimumLayoutSize(final Container parent){
+    throw new UnsupportedOperationException();
+  }
+
+  public void layoutContainer(final Container parent){
+    throw new UnsupportedOperationException();
+  }
+  
+  public void setPreferredSize(final Dimension size){
+    throw new UnsupportedOperationException();
+  }
+
+  public final void invalidateLayout(final Container target){
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EliminateTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EliminateTest.java
new file mode 100644
index 0000000..2594945
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EliminateTest.java
@@ -0,0 +1,205 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+/**
+ * @author Anton Katilin
+ * @author Vladimir Kondratyev
+ */
+public final class EliminateTest extends TestCase{
+  public void test1() {
+    // 11
+    //  2
+    doTest(
+      new int[][]{
+        {0, 2},
+        {1, 1}
+      },
+      new int[][]{
+        {0, 1},
+        {0, 1}
+      }
+    );
+  }
+
+  public void test2(){
+    // 111
+    //  2
+    doTest(
+      new int[][]{
+        {0, 3},
+        {1, 1}
+      },
+      new int[][]{
+        {0, 1},
+        {0, 1}
+      }
+    );
+  }
+
+  public void test3(){
+    // 11
+    // 2
+    doTest(
+      new int[][]{
+        {0,2},
+        {0,1}
+      },
+      new int[][]{
+        {0, 1},
+        {0, 1}
+      }
+    );
+  }
+
+  public void test4(){
+    // 12
+    // 33
+    doTest(
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      }
+    );
+  }
+
+  public void test5(){
+    // 112
+    //  333
+    doTest(
+      new int[][]{
+        {0, 2},
+        {2, 1},
+        {1, 3}
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      }
+    );
+  }
+
+  public void test7(){
+    // 11 222
+    //  3333
+    doTest(
+      new int[][]{
+        {0, 2},
+        {3, 3},
+        {1, 4}
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      }
+    );
+  }
+
+  public void test8(){
+    //   111
+    // 222
+    doTest(
+      new int[][]{
+        {2, 3},
+        {0, 3}
+      },
+      new int[][]{
+        {0, 1},
+        {0, 1}
+      }
+    );
+  }
+
+  public void test9(){
+    // 1 22
+    // 333
+    doTest(
+      new int[][]{
+        {0, 1},
+        {2, 2},
+        {0, 3}
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      }
+    );
+  }
+
+  public void test9a(){
+    // 122
+    // 33
+    doTest(
+      new int[][]{
+        {0, 1},
+        {1, 2},
+        {0, 2}
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+        {0, 2}
+      }
+    );
+  }
+
+  public void test10(){
+    // 1 2
+    doTest(
+      new int[][]{
+        {0, 1},
+        {2, 1},
+      },
+      new int[][]{
+        {0, 1},
+        {1, 1},
+      }
+    );
+  }
+
+  private static void doTest(final int[][] src, final int[][] expected) {
+    final int[] cells = new int[src.length];
+    final int[] spans = new int[src.length];
+    for (int i = 0; i < cells.length; i++) {
+       cells[i] = src[i][0];
+       spans[i] = src[i][1];
+    }
+
+    Util.eliminate(cells, spans, null);
+
+    for (int i = 0; i < spans.length; i++) {
+      if (cells[i] != expected[i][0] ||
+        spans[i] != expected[i][1]
+      ){
+        for (int j = 0; j < spans.length; j++) {
+          System.out.println("i=" + j + " expected ("+expected[j][0] + "," + expected[j][1] +"), result (" + cells[j] + "," + spans[j]+")");
+        }
+        assertTrue(false);
+      }
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EmptyPanelTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EmptyPanelTest.java
new file mode 100644
index 0000000..603c005
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EmptyPanelTest.java
@@ -0,0 +1,77 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
+
+public final class EmptyPanelTest extends TestCase {
+
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2, 3, new Insets(0, 0, 0, 0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    assertEquals(0, panel.getPreferredSize().width);
+    assertEquals(0, panel.getPreferredSize().height);
+
+    panel.setSize(90, 200);
+    panel.doLayout(); // should not crash with exception
+
+    assertTrue(Arrays.equals(new int[]{0, 30, 60}, layoutManager.getXs()));
+    assertTrue(Arrays.equals(new int[]{30, 30, 30}, layoutManager.getWidths()));
+
+    assertTrue(Arrays.equals(new int[]{0, 100}, layoutManager.getYs()));
+    assertTrue(Arrays.equals(new int[]{100, 100}, layoutManager.getHeights()));
+
+    // add component 
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(100, 20));
+    panel.add(button,
+              new GridConstraints(0, 1, 1, 2, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH, GridConstraints.SIZEPOLICY_CAN_GROW,
+                                  GridConstraints.SIZEPOLICY_FIXED, null, null, null,
+                                  0));
+
+    // wisdom
+    layoutManager.invalidateLayout(panel);
+
+    if (SystemInfo.isMac) {
+      assertEquals(new Dimension(100, 29), panel.getPreferredSize());
+      panel.setSize(panel.getPreferredSize());
+      panel.doLayout();
+      assertEquals(100, button.getWidth());
+      assertEquals(29, panel.getHeight());
+
+      assertTrue(Arrays.equals(new int[]{0, 29}, layoutManager.getYs()));
+      assertTrue(Arrays.equals(new int[]{29, 0}, layoutManager.getHeights()));
+    }
+    else {
+      assertEquals(new Dimension(100, 20), panel.getPreferredSize());
+      panel.setSize(panel.getPreferredSize());
+      panel.doLayout();
+      assertEquals(100, button.getWidth());
+      assertEquals(20, panel.getHeight());
+
+      assertTrue(Arrays.equals(new int[]{0, 20}, layoutManager.getYs()));
+      assertTrue(Arrays.equals(new int[]{20, 0}, layoutManager.getHeights()));
+    }
+
+    assertTrue(Arrays.equals(new int[]{0, 0, 100}, layoutManager.getXs()));
+    assertTrue(Arrays.equals(new int[]{0, 100, 0}, layoutManager.getWidths()));
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EqualSizeCellsTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EqualSizeCellsTest.java
new file mode 100644
index 0000000..43e156f
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/EqualSizeCellsTest.java
@@ -0,0 +1,127 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class EqualSizeCellsTest extends TestCase{
+  /**
+   * field1 | field2 | field3
+   */ 
+  public void test1() {
+    final GridLayoutManager layout = new GridLayoutManager(1,3, new Insets(0,0,0,0), 7, 0);
+
+    layout.setSameSizeHorizontally(true);
+
+    final JPanel panel = new JPanel(layout);
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(5,20));
+    field1.setPreferredSize(new Dimension(10,20));
+
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(25,20));
+    field2.setPreferredSize(new Dimension(50,20));
+
+    final JTextField field3 = new JTextField();
+    field3.setMinimumSize(new Dimension(70,20));
+    field3.setPreferredSize(new Dimension(100,20));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension minimumSize = panel.getMinimumSize();
+    assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.width);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.width);
+
+    //
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    assertEquals(100, field1.getWidth());
+    assertEquals(100, field2.getWidth());
+    assertEquals(100, field3.getWidth());
+
+    //
+    panel.setSize(new Dimension(1000, 1000));
+    panel.doLayout();
+
+    assertEquals(329, field1.getWidth());
+    assertEquals(329, field2.getWidth());
+    assertEquals(328, field3.getWidth());
+  }
+
+
+  /**
+   * field1
+   * ------
+   * field2
+   * ------
+   * field3
+   */
+  public void test2() {
+    final GridLayoutManager layout = new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7);
+
+    layout.setSameSizeVertically(true);
+
+    final JPanel panel = new JPanel(layout);
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(20, 5));
+    field1.setPreferredSize(new Dimension(20, 10));
+
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(20, 25));
+    field2.setPreferredSize(new Dimension(20, 50));
+
+    final JTextField field3 = new JTextField();
+    field3.setMinimumSize(new Dimension(20, 70));
+    field3.setPreferredSize(new Dimension(20, 100));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    panel.add(field3, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    final Dimension minimumSize = panel.getMinimumSize();
+    assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.height);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.height);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    assertEquals(100, field1.getHeight());
+    assertEquals(100, field2.getHeight());
+    assertEquals(100, field3.getHeight());
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GapsTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GapsTest.java
new file mode 100644
index 0000000..bdc045c
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GapsTest.java
@@ -0,0 +1,275 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class GapsTest extends TestCase{
+  public void test1() {
+    final JPanel panel = new JPanel(new GridLayoutManager(1,2, new Insets(0,0,0,0), 10, 0));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,20));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(210, preferredSize.width);
+  }
+
+  /**
+   * field (span 2) | field (span 1)
+   */
+  public void test2() {
+    final JPanel panel = new JPanel(new GridLayoutManager(1,3, new Insets(0,0,0,0), 7, 0));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,20));
+
+    panel.add(field1, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(207, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    if (SystemInfo.isMac) {
+      assertEquals(new Rectangle(0,0,100,28), field1.getBounds());
+      assertEquals(new Rectangle(107,0,100,28), field2.getBounds());
+    } else {
+      assertEquals(new Rectangle(0,0,100,20), field1.getBounds());
+      assertEquals(new Rectangle(107,0,100,20), field2.getBounds());
+    }
+  }
+
+
+  /**
+   *
+   * btn1   |    btn2  | btn4
+   *  btn3 (span 2)    |
+   */
+  public void test3() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 7, 0));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+    final JButton btn4 = new JButton();
+    btn4.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(314, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   *
+   * btn1   |    btn2  | btn4
+   *  btn3 (span 2)    |
+   */
+  public void test3a() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 1000, 0));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+    final JButton btn4 = new JButton();
+    btn4.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(2300, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   *
+   * btn1   |    btn2
+   *  btn3 (span 2)
+   */
+  public void test3b() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 1000, 0));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(1200, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   * btn1
+   * -----
+   * empty
+   * ----
+   * btn2
+   */
+  public void test4() {
+    final JPanel panel = new JPanel(new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(65, preferredSize.height);
+    } else {
+      assertEquals(47, preferredSize.height);
+    }
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   * btn1
+   * -----
+   * spacer
+   * ----
+   * btn2
+   */
+  public void test5() {
+    final JPanel panel = new JPanel(new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 7));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(new Spacer(), new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(65, preferredSize.height);
+    } else {
+      assertEquals(47, preferredSize.height);
+    }
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   * btn1
+   * ----- (very big gap)
+   * btn2
+   */
+  public void test6() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,1, new Insets(0,0,0,0), 0, 500));
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+
+    panel.add(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(btn2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(558, preferredSize.height);
+    } else {
+      assertEquals(540, preferredSize.height);
+    }
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout(); // should not crash
+  }
+
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java
new file mode 100644
index 0000000..1785247
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/GridBagConverterTest.java
@@ -0,0 +1,905 @@
+/*
+ * 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.uiDesigner.core;
+
+import com.intellij.uiDesigner.compiler.GridBagConverter;
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class GridBagConverterTest extends TestCase {
+  /**
+   * button 1
+   * <empty>
+   * button 2
+   */
+  public void testLayout2() {
+    final GridBagLayout layoutManager = new GridBagLayout();
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JButton button1 = new JButton();
+    button1.setMinimumSize(new Dimension(9, 7));
+    button1.setPreferredSize(new Dimension(50, 10));
+
+    final JButton button2 = new JButton();
+    button2.setMinimumSize(new Dimension(15, 6));
+    button2.setPreferredSize(new Dimension(50, 10));
+
+    GridBagConverter converter = new GridBagConverter();
+    final GridConstraints button1Constraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
+                                                                   GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK,
+                                                                   null, null, null, 0);
+    converter.addComponent(button1, button1Constraints);
+
+    final GridConstraints button2Constraints = new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
+                                                                   GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
+                                                                   GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0);
+
+    converter.addComponent(button2, button2Constraints);
+
+    applyConversionResults(panel, converter);
+
+    assertEquals(20, panel.getPreferredSize().height);
+    assertEquals(50, panel.getPreferredSize().width);
+
+    assertEquals(17, panel.getMinimumSize().height);
+    assertEquals(50, panel.getMinimumSize().width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(50, button1.getHeight());
+    assertEquals(50, button2.getHeight());
+  }
+
+  public void testLayout2ByConstraints() {
+    final GridBagLayout layoutManager = new GridBagLayout();
+    final JPanel panel = new JPanel(layoutManager);
+    final JButton button1 = new JButton();
+    final JButton button2 = new JButton();
+
+    GridBagConverter converter = new GridBagConverter();
+    final GridConstraints button1Constraints = new GridConstraints(0, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
+                                                                   GridConstraints.SIZEPOLICY_CAN_GROW,
+                                                                   GridConstraints.SIZEPOLICY_CAN_SHRINK,
+                                                                   new Dimension(9, 7), new Dimension(50, 10), null, 0);
+    converter.addComponent(button1, button1Constraints);
+
+    final GridConstraints button2Constraints = new GridConstraints(2, 0, 1, 1, GridConstraints.ANCHOR_CENTER, GridConstraints.FILL_BOTH,
+                                                                   GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK,
+                                                                   GridConstraints.SIZEPOLICY_FIXED,
+                                                                   new Dimension(15, 6), new Dimension(50, 10), null, 0);
+
+    converter.addComponent(button2, button2Constraints);
+
+    applyConversionResults(panel, converter);
+
+    assertEquals(20, panel.getPreferredSize().height);
+    assertEquals(50, panel.getPreferredSize().width);
+
+    assertEquals(17, panel.getMinimumSize().height);
+    assertEquals(50, panel.getMinimumSize().width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(50, button1.getHeight());
+    assertEquals(50, button2.getHeight());
+  }
+
+  public void testLayout3() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton button1 = new JButton();
+    button1.setPreferredSize(new Dimension(100,20));
+    final JButton button2 = new JButton();
+    button2.setPreferredSize(new Dimension(100,100));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(120, preferredSize.height);
+  }
+
+  public void testLayout4() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    // button 1  button 3
+    // button 2  button 3
+
+    final JButton button1 = new JButton();
+    button1.setPreferredSize(new Dimension(100,10));
+    final JButton button2 = new JButton();
+    button2.setPreferredSize(new Dimension(100,10));
+    final JButton button3 = new JButton();
+    button3.setPreferredSize(new Dimension(100,200));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    converter.addComponent(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    converter.addComponent(button3, new GridConstraints(0,1,2,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    applyConversionResults(panel, converter);
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(200, preferredSize.height);
+  }
+
+  /* TODO[yole]: this layout does not work as expected at runtime
+  public void testLayout5_1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    // label textfield(span 2)
+    // textfield(span 2)
+
+    final JTextField label = new JTextField();
+    label.setPreferredSize(new Dimension(10,30));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,30));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,30));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
+
+    converter.addComponent(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
+
+    converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null));
+
+    applyConversionResults(panel, converter);
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(110, preferredSize.width);
+    assertEquals(60, preferredSize.height);
+  }
+  */
+
+  public void testLayout7() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JLabel label = new JLabel();
+    label.setPreferredSize(new Dimension(50,10));
+
+    final JTextField field = new JTextField();
+    field.setPreferredSize(new Dimension(100,10));
+
+    final JTextField scroll = new JTextField();
+    scroll.setPreferredSize(new Dimension(503, 10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    converter.addComponent(field, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    converter.addComponent(scroll, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    assertEquals(503, panel.getMinimumSize().width);
+    assertEquals(503, panel.getPreferredSize().width);
+
+    panel.setSize(503, 100);
+    panel.doLayout();
+
+    assertEquals(50, label.getWidth());
+    assertEquals(453, field.getWidth());
+  }
+
+  public void testLayout8() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JLabel label1 = new JLabel();
+    label1.setMinimumSize(new Dimension(10,10));
+    label1.setPreferredSize(new Dimension(100,10));
+
+    final JLabel label2 = new JLabel();
+    label2.setMinimumSize(new Dimension(10,10));
+    label2.setPreferredSize(new Dimension(100,10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW,
+      GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK,
+      GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(new JLabel(), new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW + GridConstraints.SIZEPOLICY_WANT_GROW,
+      GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0));
+    applyConversionResults(panel, converter);
+
+    assertEquals(20, panel.getMinimumSize().width);
+    assertEquals(200, panel.getPreferredSize().width);
+
+    // minimum
+    panel.setSize(20, 100);
+    panel.doLayout();
+    assertEquals(10, label1.getWidth());
+    assertEquals(10, label2.getWidth());
+
+    // between min and pref
+    /* TODO[yole]: GridBag honors weights in this situation, and GridLayout distributes evenly
+    panel.setSize(76, 100);
+    panel.doLayout();
+    assertEquals(38, label1.getWidth());
+    assertEquals(38, label2.getWidth());
+    */
+
+    // pref-1
+    /* TODO[yole]: investigate
+    panel.setSize(199, 100);
+    panel.doLayout();
+    assertEquals(100, label1.getWidth());
+    assertEquals(99, label2.getWidth());
+    */
+
+    // pref
+    panel.setSize(200, 100);
+    panel.doLayout();
+    assertEquals(100, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+
+    // pref+1
+    panel.setSize(201, 100);
+    panel.doLayout();
+    assertEquals(101, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+
+    // pref + few
+    panel.setSize(205, 100);
+    panel.doLayout();
+    assertEquals(105, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+  }
+
+  public void testPrefSize1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(110,10));
+    field1.setPreferredSize(new Dimension(120,10));
+
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(215,10));
+    field2.setPreferredSize(new Dimension(225,10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(345, preferredSize.width);
+
+    final Dimension minSize = panel.getMinimumSize();
+    assertEquals(325, minSize.width);
+
+    panel.setSize(preferredSize.width, preferredSize.height);
+    panel.doLayout();
+
+    assertEquals(120, field1.getWidth());
+    assertEquals(225, field2.getWidth());
+
+    panel.setSize(400, panel.getWidth());
+    panel.invalidate(); // to invalidate layout
+    panel.doLayout();
+  }
+
+  /* TODO[yole]: this relies on strange myMinCellSize logic
+  public void testPrefSize2() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,10));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(200,10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
+
+    converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(300 + 20, preferredSize.width);
+
+    panel.setSize(preferredSize.width, preferredSize.height);
+    panel.doLayout();
+
+    assertEquals(100, field1.getWidth());
+    assertEquals(200, field2.getWidth());
+
+    panel.setSize(270, preferredSize.height);
+    panel.doLayout();   // should not fail
+  }
+  */
+
+  /**
+   * button(can grow) | text field (want grow)
+   *   text field (want grow, span 2)
+   */
+  public void testSpans1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field2 = new JTextField();
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100, preferredSize.width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(500, field2.getWidth());
+    assertEquals(50, button.getWidth());
+    assertEquals(450, field1.getWidth());
+  }
+
+  /**
+   * button(can grow) | text field (can grow)
+   *   text field (want grow, span 2)
+   */
+  public void testSpans2() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field2 = new JTextField();
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+                                          GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100, preferredSize.width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(500, field2.getWidth());
+    assertEquals(250, button.getWidth());
+    assertEquals(250, field1.getWidth());
+  }
+
+  /**
+   * button(can grow) | text field (want grow, span 2)
+   */
+  public void testSpans3() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(110, 10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(160, preferredSize.width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(50, button.getWidth());
+    assertEquals(450, field1.getWidth());
+  }
+
+  /**
+   * button (can grow, span 2 )       | text field 1 (span 1)
+   * text field 2 (want grow, span 2) | empty
+   */
+  public void testSpans4() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(110, 10));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(110, 10));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(button, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field1, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(220, preferredSize.width);
+
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(250, button.getWidth());
+    assertEquals(250, field1.getWidth());
+    assertEquals(250, field2.getWidth());
+  }
+
+  /**
+   * label   |    label
+   * text area (span 2)
+   */
+  public void testTextAreas1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JLabel label1 = new JLabel();
+    label1.setPreferredSize(new Dimension(15,20));
+    final JLabel label2 = new JLabel();
+    label2.setPreferredSize(new Dimension(15,20));
+    final JTextArea textArea = new JTextArea();
+    textArea.setLineWrap(true);
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(textArea, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    assertEquals(100, textArea.getPreferredSize().width);
+
+    final Dimension initialPreferredSize = panel.getPreferredSize();
+    assertEquals(new Dimension(100,20 + textArea.getPreferredSize().height), initialPreferredSize);
+
+    panel.setSize(initialPreferredSize);
+    panel.invalidate();
+    panel.doLayout();
+
+    assertEquals(initialPreferredSize, panel.getPreferredSize());
+  }
+
+  /**
+   * textfield1 | textfield2
+   *  textfield3 (span 2)
+   *
+   * important: hspan should be greater than 0
+   */
+  public void testTextAreas2() {
+    final JPanel panel = new JPanel(/*new GridLayoutManager(2,2, new Insets(0,0,0,0), 11, 0)*/ new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(15,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(15,20));
+    final JTextField field3 = new JTextField();
+    field3.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter();
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    assertEquals(100, panel.getPreferredSize().width);
+  }
+
+  public void testGaps1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 10, 0, false, false);
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(210, preferredSize.width);
+  }
+
+  /**
+   * field (span 2) | field (span 1)
+   */
+  public void testGaps2() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, false, false);
+    converter.addComponent(field1, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(207, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    assertEquals(new Rectangle(0,0,100,20), field1.getBounds());
+    assertEquals(new Rectangle(107,0,100,20), field2.getBounds());
+  }
+
+  /**
+   *
+   * btn1   |    btn2  | btn4
+   *  btn3 (span 2)    |
+   */
+  public void testGaps3() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+    final JButton btn4 = new JButton();
+    btn4.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, false, false);
+    converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(314, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   *
+   * btn1   |    btn2  | btn4
+   *  btn3 (span 2)    |
+   */
+  public void testGaps3a() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+    final JButton btn4 = new JButton();
+    btn4.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 1000, 0, false, false);
+    converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn4, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(2300, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   *
+   * btn1   |    btn2
+   *  btn3 (span 2)
+   */
+  public void testGaps3b() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+    final JButton btn3 = new JButton();
+    btn3.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 1000, 0, false, false);
+    converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(1200, preferredSize.width);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  /**
+   * btn1
+   * -----
+   * empty
+   * ----
+   * btn2
+   */
+  public void testGaps4() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 7, false, false);
+    converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(47, preferredSize.height);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+  }
+
+  // skipped GapsTest.test5 because its only difference from test4 is spacer usage
+
+  public void testGaps6() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JButton btn1 = new JButton();
+    btn1.setPreferredSize(new Dimension(100,20));
+    final JButton btn2 = new JButton();
+    btn2.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 500, false, false);
+    converter.addComponent(btn1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(btn2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(540, preferredSize.height);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout(); // should not crash
+  }
+
+  public void testEqualSizeCells1() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(5,20));
+    field1.setPreferredSize(new Dimension(10,20));
+
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(25,20));
+    field2.setPreferredSize(new Dimension(50,20));
+
+    final JTextField field3 = new JTextField();
+    field3.setMinimumSize(new Dimension(70,20));
+    field3.setPreferredSize(new Dimension(100,20));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 7, 0, true, false);
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    converter.addComponent(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension minimumSize = panel.getMinimumSize();
+    assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.width);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.width);
+
+    //
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    assertEquals(100, field1.getWidth());
+    assertEquals(100, field2.getWidth());
+    assertEquals(100, field3.getWidth());
+
+    //
+    panel.setSize(new Dimension(1000, 1000));
+    panel.doLayout();
+
+    assertEquals(329, field1.getWidth(), 1.0);
+    assertEquals(329, field2.getWidth(), 1.0);
+    assertEquals(328, field3.getWidth(), 1.0);
+  }
+
+  public void testEqualSizeCells2() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(20, 5));
+    field1.setPreferredSize(new Dimension(20, 10));
+
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(20, 25));
+    field2.setPreferredSize(new Dimension(20, 50));
+
+    final JTextField field3 = new JTextField();
+    field3.setMinimumSize(new Dimension(20, 70));
+    field3.setPreferredSize(new Dimension(20, 100));
+
+    GridBagConverter converter = new GridBagConverter(new Insets(0, 0, 0, 0), 0, 7, false, true);
+    converter.addComponent(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    converter.addComponent(field2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    converter.addComponent(field3, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    applyConversionResults(panel, converter);
+
+    final Dimension minimumSize = panel.getMinimumSize();
+    assertEquals(70 + 7 + 70 + 7 + 70, minimumSize.height);
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(100 + 7 + 100 + 7 + 100, preferredSize.height);
+
+    panel.setSize(panel.getPreferredSize());
+    panel.doLayout();
+
+    assertEquals(100, field1.getHeight());
+    assertEquals(100, field2.getHeight());
+    assertEquals(100, field3.getHeight());
+  }
+
+  private static void applyConversionResults(final JPanel panel, final GridBagConverter converter) {
+    GridBagConverter.Result[] results = converter.convert();
+    for(int i=0; i<results.length; i++)  {
+      GridBagConverter.Result result = results [i];
+      JComponent component = result.isFillerPanel ? new JPanel() : result.component;
+      if (result.minimumSize != null) {
+        component.setMinimumSize(result.minimumSize);
+      }
+      if (result.preferredSize != null) {
+        component.setPreferredSize(result.preferredSize);
+      }
+      panel.add(component, result.constraints);
+    }
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/IndentTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/IndentTest.java
new file mode 100644
index 0000000..076539d
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/IndentTest.java
@@ -0,0 +1,46 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+/**
+ * @author yole
+ */
+public class IndentTest extends TestCase {
+  public void testSimple() {
+    final GridLayoutManager layout = new GridLayoutManager(1,1, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layout);
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(5,20));
+    field1.setPreferredSize(new Dimension(10,20));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 1));
+    assertEquals(15, panel.getMinimumSize().width);
+    assertEquals(20, panel.getPreferredSize().width);
+
+    panel.setSize(new Dimension(100, 100));
+    panel.doLayout();
+
+    assertEquals(10, field1.getBounds().x);
+    assertEquals(90, field1.getBounds().width);
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout2Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout2Test.java
new file mode 100644
index 0000000..c39845b
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout2Test.java
@@ -0,0 +1,60 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout2Test extends TestCase{
+  /**
+   * button 1
+   * <empty>
+   * button 2 
+   */ 
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(3,1, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JButton button1 = new JButton();
+    button1.setMinimumSize(new Dimension(9, 7));
+    button1.setPreferredSize(new Dimension(50, 10));
+
+    final JButton button2 = new JButton();
+    button2.setMinimumSize(new Dimension(15, 6));
+    button2.setPreferredSize(new Dimension(50, 10));
+    
+    panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null, 0));
+
+    panel.add(button2, new GridConstraints(2,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    assertEquals(20, panel.getPreferredSize().height);
+    assertEquals(50, panel.getPreferredSize().width);
+    
+    assertEquals(17, panel.getMinimumSize().height);
+    assertEquals(50, panel.getMinimumSize().width);
+    
+    panel.setSize(new Dimension(500, 100));
+    panel.doLayout();
+
+    assertEquals(50, button1.getHeight());
+    assertEquals(50, button2.getHeight());
+  }
+  
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout3Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout3Test.java
new file mode 100644
index 0000000..60c335b
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout3Test.java
@@ -0,0 +1,41 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout3Test extends TestCase{
+  public void test1() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,1, new Insets(0,0,0,0), 0, 0));
+
+    final JButton button1 = new JButton();
+    button1.setPreferredSize(new Dimension(100,20));
+    final JButton button2 = new JButton();
+    button2.setPreferredSize(new Dimension(100,100));
+
+    panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(SystemInfo.isMac ? 129 : 120, preferredSize.height);
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout4Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout4Test.java
new file mode 100644
index 0000000..7e2f477
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout4Test.java
@@ -0,0 +1,54 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout4Test extends TestCase{
+  
+  
+  public void test1() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
+
+    // button 1  button 3
+    // button 2  button 3
+    
+    final JButton button1 = new JButton();
+    button1.setPreferredSize(new Dimension(100,10));
+    final JButton button2 = new JButton();
+    button2.setPreferredSize(new Dimension(100,10));
+    final JButton button3 = new JButton();
+    button3.setPreferredSize(new Dimension(100,200));
+
+    panel.add(button1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    panel.add(button2, new GridConstraints(1,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    panel.add(button3, new GridConstraints(0,1,2,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_WANT_GROW + GridConstraints.SIZEPOLICY_CAN_SHRINK, null, null, null,
+      0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(200, preferredSize.height);
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout5Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout5Test.java
new file mode 100644
index 0000000..f3dfc56
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout5Test.java
@@ -0,0 +1,142 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout5Test extends TestCase{
+  
+  
+  public void test1() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0));
+
+    // label textfield(span 2)
+    // textfield(span 2)
+    
+    final JTextField label = new JTextField();
+    label.setPreferredSize(new Dimension(10,30));
+    
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,30));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,30));
+    
+    panel.add(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(110, preferredSize.width);
+    assertEquals(60, preferredSize.height);
+  }
+
+
+  public void test2() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    // empty textfield(span 2)
+    // textfield(span 2) empty
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,30));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,30));
+
+    panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+
+    // after getPreferredSize() invocation, the field should be not null
+    final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
+    assertEquals(3, horizontalInfo.getCellCount());
+    assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(0));
+    assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW, horizontalInfo.getCellSizePolicy(1));
+    assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(2));
+
+    assertEquals(100, preferredSize.width);
+    assertEquals(60, preferredSize.height);
+
+    panel.setSize(400, 100);
+    panel.doLayout();
+    assertEquals(400, field1.getWidth());
+    assertEquals(400, field2.getWidth());
+  }
+
+  public void test3() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    // label textfield(span 2)
+    // textfield(span 2) label
+
+    final JTextField label1 = new JTextField();
+    label1.setPreferredSize(new Dimension(10,30));
+
+    final JTextField label2 = new JTextField();
+    label2.setPreferredSize(new Dimension(10,30));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,30));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(100,30));
+
+    panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(label2, new GridConstraints(1,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+
+    // after getPreferredSize() invocation, the field should be not null 
+    final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
+    assertEquals(GridConstraints.SIZEPOLICY_FIXED, horizontalInfo.getCellSizePolicy(0));
+    assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(1));
+    assertEquals(GridConstraints.SIZEPOLICY_FIXED, horizontalInfo.getCellSizePolicy(2));
+    
+    assertEquals(110, preferredSize.width);
+    assertEquals(60, preferredSize.height);
+    
+    panel.setSize(400, 100);
+    panel.doLayout();
+    assertEquals(390, field1.getWidth());
+    assertEquals(390, field2.getWidth());
+    assertEquals(10, label1.getWidth());
+    assertEquals(10, label2.getWidth());
+  }
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout6Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout6Test.java
new file mode 100644
index 0000000..493af8e
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout6Test.java
@@ -0,0 +1,61 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout6Test extends TestCase{
+  
+
+  /**
+   * control(min size 10) control(same) control(same)
+   */ 
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(10,30));
+    
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(10,30));
+
+    final JTextField field3 = new JTextField();
+    field3.setPreferredSize(new Dimension(10,30));
+    
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field3, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(30, preferredSize.width);
+    
+    for (int size = 31; size < 100; size++) {
+      panel.setSize(size, 30);
+      layoutManager.invalidateLayout(panel); // wisdom
+      panel.doLayout();
+    }
+  }
+
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout7Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout7Test.java
new file mode 100644
index 0000000..5970a7e
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout7Test.java
@@ -0,0 +1,60 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout7Test extends TestCase{
+  /**
+   * label | text field
+   *    scroll pane
+   */
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JLabel label = new JLabel();
+    label.setPreferredSize(new Dimension(50,10));
+    
+    final JTextField field = new JTextField();
+    field.setPreferredSize(new Dimension(100,10));
+
+    final JTextField scroll = new JTextField();
+    scroll.setPreferredSize(new Dimension(503, 10));
+
+    panel.add(label, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(field, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    panel.add(scroll, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, new Dimension(0,0), null, null, 0));
+
+    assertEquals(503, panel.getMinimumSize().width);
+    assertEquals(503, panel.getPreferredSize().width);
+
+    panel.setSize(503, 100);
+    panel.doLayout();
+
+    assertEquals(50, label.getWidth());
+    assertEquals(453, field.getWidth());
+  }
+
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout8Test.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout8Test.java
new file mode 100644
index 0000000..ef51c40
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/Layout8Test.java
@@ -0,0 +1,92 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class Layout8Test extends TestCase{
+  /**
+   * label 1 (pref=100, min=10, can shrink, can grow) | label 2 (pref=100, min=10, can shrink)
+   *                                            (can grow, want grow)
+   */
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JLabel label1 = new JLabel();
+    label1.setMinimumSize(new Dimension(10,10));
+    label1.setPreferredSize(new Dimension(100,10));
+
+    final JLabel label2 = new JLabel();
+    label2.setMinimumSize(new Dimension(10,10));
+    label2.setPreferredSize(new Dimension(100,10));
+
+    panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW,
+      GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK,
+      GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(new JLabel(), new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK + GridConstraints.SIZEPOLICY_CAN_GROW + GridConstraints.SIZEPOLICY_WANT_GROW,
+      GridConstraints.SIZEPOLICY_FIXED, null, new Dimension(150, -1), null, 0));
+
+    assertEquals(20, panel.getMinimumSize().width);
+    assertEquals(200, panel.getPreferredSize().width);
+
+    // minimum
+    panel.setSize(20, 100);
+    panel.doLayout();
+    assertEquals(10, label1.getWidth());
+    assertEquals(10, label2.getWidth());
+
+    // between min and pref
+    panel.setSize(76, 100);
+    panel.doLayout();
+    assertEquals(38, label1.getWidth());
+    assertEquals(38, label2.getWidth());
+
+    // pref-1
+    panel.setSize(199, 100);
+    panel.doLayout();
+    assertEquals(100, label1.getWidth());
+    assertEquals(99, label2.getWidth());
+
+    // pref
+    panel.setSize(200, 100);
+    panel.doLayout();
+    assertEquals(100, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+
+    // pref+1
+    panel.setSize(201, 100);
+    panel.doLayout();
+    assertEquals(101, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+
+    // pref + few
+    panel.setSize(205, 100);
+    panel.doLayout();
+    assertEquals(105, label1.getWidth());
+    assertEquals(100, label2.getWidth());
+  }
+
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/PrefSizeTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/PrefSizeTest.java
new file mode 100644
index 0000000..f967839
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/PrefSizeTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class PrefSizeTest extends TestCase{
+  /**
+   * control(min size 110, pref size 120) control(min size 215, pref size 225)
+   */ 
+  public void test1() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(1,2, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JTextField field1 = new JTextField();
+    field1.setMinimumSize(new Dimension(110,10));
+    field1.setPreferredSize(new Dimension(120,10));
+    
+    final JTextField field2 = new JTextField();
+    field2.setMinimumSize(new Dimension(215,10));
+    field2.setPreferredSize(new Dimension(225,10));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(345, preferredSize.width);
+
+    final Dimension minSize = panel.getMinimumSize();
+    assertEquals(325, minSize.width);
+
+    panel.setSize(preferredSize.width, preferredSize.height);
+    panel.doLayout();
+
+    assertEquals(120, field1.getWidth());
+    assertEquals(225, field2.getWidth());
+
+    panel.setSize(400, panel.getWidth());
+    panel.invalidate(); // to invalidate layout
+    panel.doLayout();
+
+  }
+
+  public void test2() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(1,3); // min cell size should
+    layoutManager.setHGap(0);
+    layoutManager.setVGap(0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(100,10));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(200,10));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    assertEquals(300 + 20, preferredSize.width);
+
+    panel.setSize(preferredSize.width, preferredSize.height);
+    panel.doLayout();
+    
+    assertEquals(100, field1.getWidth());
+    assertEquals(200, field2.getWidth());
+
+    panel.setSize(270, preferredSize.height);
+    panel.doLayout();   // should not fail
+  }
+  
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SpansTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SpansTest.java
new file mode 100644
index 0000000..4d9bfd0
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SpansTest.java
@@ -0,0 +1,196 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class SpansTest extends TestCase{
+  
+  /**
+   * button(can grow) | text field (want grow)
+   *   text field (want grow, span 2) 
+   */ 
+  public void test1() {
+    final GridLayoutManager layout = new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layout);
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+    
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field2 = new JTextField();
+
+    panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(125, preferredSize.width);
+    } else {
+      assertEquals(100, preferredSize.width);
+    }
+
+    panel.setSize(new Dimension(500, panel.getHeight()));
+    panel.doLayout();
+
+    assertEquals(500, field2.getWidth());
+    if (SystemInfo.isMac) {
+      assertEquals(75, button.getWidth());
+      assertEquals(425, field1.getWidth());
+    } else {
+      assertEquals(50, button.getWidth());
+      assertEquals(450, field1.getWidth());
+    }
+  }
+
+
+  /**
+   * button(can grow) | text field (can grow)
+   *   text field (want grow, span 2)
+   */
+  public void test2() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field2 = new JTextField();
+
+    panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field1, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(125, preferredSize.width);
+    } else {
+      assertEquals(100, preferredSize.width);
+    }
+
+    panel.setSize(new Dimension(500, panel.getHeight()));
+    panel.doLayout();
+
+    assertEquals(500, field2.getWidth());
+    if (SystemInfo.isMac) {
+      assertEquals(263, button.getWidth());
+      assertEquals(237, field1.getWidth());
+    } else {
+      assertEquals(250, button.getWidth());
+      assertEquals(250, field1.getWidth());
+    }
+  }
+
+  /**
+   * button(can grow) | text field (want grow, span 2)
+   */
+  public void test3() {
+    final JPanel panel = new JPanel(new GridLayoutManager(1,3, new Insets(0,0,0,0), 0, 0));
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(110, 10));
+
+    panel.add(button, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field1, new GridConstraints(0,1,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+    if (SystemInfo.isMac) {
+      assertEquals(185, preferredSize.width);
+    } else {
+      assertEquals(160, preferredSize.width);
+    }
+
+    panel.setSize(new Dimension(500, panel.getHeight()));
+    panel.doLayout();
+
+    if (SystemInfo.isMac) {
+      assertEquals(75, button.getWidth());
+      assertEquals(425, field1.getWidth());
+    } else {
+      assertEquals(50, button.getWidth());
+      assertEquals(450, field1.getWidth());
+    }
+  }
+
+  /**
+   * button (can grow, span 2 )       | text field 1 (span 1)
+   * text field 2 (want grow, span 2) | empty
+   */
+  public void test4() {
+    final GridLayoutManager layoutManager = new GridLayoutManager(2,3, new Insets(0,0,0,0), 0, 0);
+    final JPanel panel = new JPanel(layoutManager);
+
+    final JButton button = new JButton();
+    button.setPreferredSize(new Dimension(50, 10));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(110, 10));
+
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(110, 10));
+
+    panel.add(button, new GridConstraints(0,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field1, new GridConstraints(0,2,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_WANT_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    final Dimension preferredSize = panel.getPreferredSize();
+
+    // field will be not null after getPreferredSize()
+    final DimensionInfo horizontalInfo = layoutManager.myHorizontalInfo;
+    assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW | GridConstraints.SIZEPOLICY_CAN_GROW, horizontalInfo.getCellSizePolicy(0));
+    assertEquals(GridConstraints.SIZEPOLICY_CAN_SHRINK, horizontalInfo.getCellSizePolicy(1));
+    assertEquals(GridConstraints.SIZEPOLICY_WANT_GROW, horizontalInfo.getCellSizePolicy(2));
+
+    assertEquals(220, preferredSize.width);
+    
+    panel.setSize(new Dimension(500, panel.getHeight()));
+    panel.doLayout();
+
+    assertEquals(250, button.getWidth());
+    assertEquals(250, field1.getWidth());
+    assertEquals(250, field2.getWidth());
+  }
+  
+}
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SystemInfo.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SystemInfo.java
new file mode 100644
index 0000000..687a1d4
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/SystemInfo.java
@@ -0,0 +1,23 @@
+/*
+ * 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.uiDesigner.core;
+
+/**
+ * @author Alexander Lobas
+ */
+public class SystemInfo {
+  public static final boolean isMac = System.getProperty("os.name").toLowerCase().startsWith("mac");
+}
\ No newline at end of file
diff --git a/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java
new file mode 100644
index 0000000..7fa442f
--- /dev/null
+++ b/java/compiler/forms-compiler/testSrc/com/intellij/uiDesigner/core/TextAreasTest.java
@@ -0,0 +1,89 @@
+/*
+ * 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.uiDesigner.core;
+
+import junit.framework.TestCase;
+
+import javax.swing.*;
+import java.awt.*;
+
+public final class TextAreasTest extends TestCase{
+  /**
+   * label   |    label
+   * text area (span 2)
+   */ 
+  
+  public void test1() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 0, 0));
+
+    final JLabel label1 = new JLabel();
+    label1.setPreferredSize(new Dimension(15,20));
+    final JLabel label2 = new JLabel();
+    label2.setPreferredSize(new Dimension(15,20));
+    final JTextArea textArea = new JTextArea();
+    textArea.setLineWrap(true);
+
+    panel.add(label1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(label2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_FIXED, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(textArea, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW,
+      GridConstraints.SIZEPOLICY_CAN_SHRINK | GridConstraints.SIZEPOLICY_CAN_GROW, null, null, null, 0));
+
+    assertEquals(100, textArea.getPreferredSize().width);
+
+    final Dimension initialPreferredSize = panel.getPreferredSize();
+    assertEquals(new Dimension(100,20 + textArea.getPreferredSize().height), initialPreferredSize);
+
+    panel.setSize(initialPreferredSize);
+    panel.invalidate();
+    panel.doLayout();
+
+    assertEquals(initialPreferredSize, panel.getPreferredSize());
+  }
+
+  /**
+   * textfield1 | textfield2
+   *  textfield3 (span 2)
+   *
+   * important: hspan should be greater than 0
+   */
+  public void test2() {
+    final JPanel panel = new JPanel(new GridLayoutManager(2,2, new Insets(0,0,0,0), 11, 0));
+
+    final JTextField field1 = new JTextField();
+    field1.setPreferredSize(new Dimension(15,20));
+    final JTextField field2 = new JTextField();
+    field2.setPreferredSize(new Dimension(15,20));
+    final JTextField field3 = new JTextField();
+    field3.setPreferredSize(new Dimension(100,20));
+
+    panel.add(field1, new GridConstraints(0,0,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field2, new GridConstraints(0,1,1,1,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_HORIZONTAL,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    panel.add(field3, new GridConstraints(1,0,1,2,GridConstraints.ANCHOR_CENTER,GridConstraints.FILL_BOTH,
+      GridConstraints.SIZEPOLICY_CAN_GROW, GridConstraints.SIZEPOLICY_FIXED, null, null, null, 0));
+
+    assertEquals(100, panel.getPreferredSize().width);
+  }
+  
+}
diff --git a/java/compiler/impl/compiler-impl.iml b/java/compiler/impl/compiler-impl.iml
new file mode 100644
index 0000000..9bb8c9a
--- /dev/null
+++ b/java/compiler/impl/compiler-impl.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+      <sourceFolder url="file://$MODULE_DIR$/testSrc" isTestSource="true" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="compiler-openapi" exported="" />
+    <orderEntry type="library" name="OroMatcher" level="project" />
+    <orderEntry type="library" name="JDOM" level="project" />
+    <orderEntry type="module" module-name="util" />
+    <orderEntry type="module" module-name="openapi" />
+    <orderEntry type="library" name="Trove4j" level="project" />
+    <orderEntry type="module" module-name="java-runtime" />
+    <orderEntry type="module" module-name="instrumentation-util" />
+    <orderEntry type="library" name="asm4" level="project" />
+    <orderEntry type="library" name="Eclipse" level="project" />
+    <orderEntry type="module" module-name="platform-api" />
+    <orderEntry type="module" module-name="lang-impl" />
+    <orderEntry type="module" module-name="jsp-openapi" />
+    <orderEntry type="module" module-name="java-impl" />
+    <orderEntry type="module" module-name="jps-builders" />
+    <orderEntry type="library" name="Netty" level="project" />
+    <orderEntry type="module" module-name="testFramework-java" scope="TEST" />
+    <orderEntry type="module" module-name="jps-model-impl" />
+  </component>
+  <component name="copyright">
+    <Base>
+      <setting name="state" value="1" />
+    </Base>
+  </component>
+</module>
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java
new file mode 100644
index 0000000..cbf1b68
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerConfigurationImpl.java
@@ -0,0 +1,1000 @@
+
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 3, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler;
+
+import com.intellij.CommonBundle;
+import com.intellij.ProjectTopics;
+import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.compiler.impl.javaCompiler.api.CompilerAPICompiler;
+import com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompiler;
+import com.intellij.compiler.impl.javaCompiler.eclipse.EclipseEmbeddedCompiler;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
+import com.intellij.compiler.options.ExternalBuildOptionListener;
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.ModuleAdapter;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.ui.InputValidator;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.messages.MessageBusConnection;
+import org.apache.oro.text.regex.*;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+import org.jetbrains.jps.model.java.impl.compiler.ProcessorConfigProfileImpl;
+import org.jetbrains.jps.model.serialization.java.compiler.AnnotationProcessorProfileSerializer;
+import org.jetbrains.jps.model.serialization.java.compiler.JpsJavaCompilerConfigurationSerializer;
+
+import java.io.File;
+import java.util.*;
+
+@State(
+  name = "CompilerConfiguration",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE),
+    @Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+  }
+)
+public class CompilerConfigurationImpl extends CompilerConfiguration implements PersistentStateComponent<Element>, ProjectComponent {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.CompilerConfiguration");
+  @NonNls public static final String TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME = "tests.external.compiler.home";
+  public static final int DEPENDENCY_FORMAT_VERSION = 55;
+
+  @SuppressWarnings({"WeakerAccess"}) public String DEFAULT_COMPILER;
+  @NotNull private BackendCompiler myDefaultJavaCompiler;
+
+  // extensions of the files considered as resource files
+  private final List<Pattern> myRegexpResourcePatterns = new ArrayList<Pattern>();
+  // extensions of the files considered as resource files. If present, overrides patterns in old regexp format stored in myRegexpResourcePatterns
+  private final List<String> myWildcardPatterns = new ArrayList<String>();
+  private final List<CompiledPattern> myCompiledPatterns = new ArrayList<CompiledPattern>();
+  private final List<CompiledPattern> myNegatedCompiledPatterns = new ArrayList<CompiledPattern>();
+  private boolean myWildcardPatternsInitialized = false;
+  private final Project myProject;
+  private final ExcludedEntriesConfiguration myExcludedEntriesConfiguration;
+
+  private final Collection<BackendCompiler> myRegisteredCompilers = new ArrayList<BackendCompiler>();
+  private JavacCompiler JAVAC_EXTERNAL_BACKEND;
+  private final Perl5Matcher myPatternMatcher = new Perl5Matcher();
+
+  {
+    loadDefaultWildcardPatterns();
+  }
+  private boolean myAddNotNullAssertions = true;
+
+  private final ProcessorConfigProfile myDefaultProcessorsProfile = new ProcessorConfigProfileImpl("Default");
+  private final List<ProcessorConfigProfile> myModuleProcessorProfiles = new ArrayList<ProcessorConfigProfile>();
+
+  // the map is calculated by module processor profiles list for faster access to module settings
+  private Map<Module, ProcessorConfigProfile> myProcessorsProfilesMap = null;
+
+  @Nullable
+  private String myBytecodeTargetLevel = null;  // null means compiler default
+  private final Map<String, String> myModuleBytecodeTarget = new java.util.HashMap<String, String>();
+
+  public CompilerConfigurationImpl(Project project) {
+    myProject = project;
+    myExcludedEntriesConfiguration = new ExcludedEntriesConfiguration();
+    Disposer.register(project, myExcludedEntriesConfiguration);
+    MessageBusConnection connection = project.getMessageBus().connect(project);
+    connection.subscribe(ProjectTopics.MODULES, new ModuleAdapter() {
+      public void beforeModuleRemoved(Project project, Module module) {
+        getAnnotationProcessingConfiguration(module).removeModuleName(module.getName());
+      }
+
+      public void moduleAdded(Project project, Module module) {
+        myProcessorsProfilesMap = null; // clear cache
+      }
+    });
+
+    connection.subscribe(ExternalBuildOptionListener.TOPIC, new ExternalBuildOptionListener() {
+      @Override
+      public void externalBuildOptionChanged(boolean externalBuildEnabled) {
+    // this will schedule for compilation all files that might become compilable after resource patterns' changing
+        final TranslatingCompilerFilesMonitor monitor = TranslatingCompilerFilesMonitor.getInstance();
+        if (externalBuildEnabled) {
+          monitor.suspendProject(myProject);
+        }
+        else {
+          monitor.watchProject(myProject);
+          monitor.scanSourcesForCompilableFiles(myProject);
+          if (!myProject.isDefault()) {
+            final File buildSystem = BuildManager.getInstance().getBuildSystemDirectory();
+            final File[] subdirs = buildSystem.listFiles();
+            if (subdirs != null) {
+              final String prefix = myProject.getName().toLowerCase(Locale.US) + "_";
+              for (File subdir : subdirs) {
+                if (subdir.getName().startsWith(prefix)) {
+                  FileUtil.asyncDelete(subdir);
+                }
+              }
+            }
+          }
+        }
+      }
+    });
+  }
+
+  public Element getState() {
+    try {
+      @NonNls final Element e = new Element("state");
+      writeExternal(e);
+      return e;
+    }
+    catch (WriteExternalException e1) {
+      LOG.error(e1);
+      return null;
+    }
+  }
+
+  public void loadState(Element state) {
+    try {
+      readExternal(state);
+    }
+    catch (InvalidDataException e) {
+      LOG.error(e);
+    }
+  }
+
+  public void setProjectBytecodeTarget(@Nullable String level) {
+    myBytecodeTargetLevel = level;
+  }
+
+  @Override
+  @Nullable
+  public String getProjectBytecodeTarget() {
+    return myBytecodeTargetLevel;
+  }
+
+  public void setModulesBytecodeTargetMap(@NotNull Map<String, String> mapping) {
+    myModuleBytecodeTarget.clear();
+    myModuleBytecodeTarget.putAll(mapping);
+  }
+
+  public Map<String, String> getModulesBytecodeTargetMap() {
+    return myModuleBytecodeTarget;
+  }
+
+  public void setBytecodeTargetLevel(Module module, String level) {
+    final String previous;
+    if (StringUtil.isEmpty(level)) {
+      previous = myModuleBytecodeTarget.remove(module.getName());
+    }
+    else {
+      previous = myModuleBytecodeTarget.put(module.getName(), level);
+    }
+    // todo: mark module as dirty in order to rebuild it completely with the new target level
+    //if (!Comparing.equal(previous, level)) {
+    //  final Project project = module.getProject();
+    //
+    //}
+  }
+
+  @Override
+  @Nullable
+  public String getBytecodeTargetLevel(Module module) {
+    final String level = myModuleBytecodeTarget.get(module.getName());
+    if (level != null) {
+      return level.isEmpty() ? null : level;
+    }
+    return myBytecodeTargetLevel;
+  }
+
+  private void loadDefaultWildcardPatterns() {
+    if (!myWildcardPatterns.isEmpty()) {
+      removeWildcardPatterns();
+    }
+    try {
+      addWildcardResourcePattern("!?*.java");
+      addWildcardResourcePattern("!?*.form");
+      addWildcardResourcePattern("!?*.class");
+      addWildcardResourcePattern("!?*.groovy");
+      addWildcardResourcePattern("!?*.scala");
+      addWildcardResourcePattern("!?*.flex");
+      addWildcardResourcePattern("!?*.kt");
+      addWildcardResourcePattern("!?*.clj");
+    }
+    catch (MalformedPatternException e) {
+      LOG.error(e);
+    }
+  }
+
+  public static String getTestsExternalCompilerHome() {
+    String compilerHome = System.getProperty(TESTS_EXTERNAL_COMPILER_HOME_PROPERTY_NAME, null);
+    if (compilerHome == null) {
+      if (SystemInfo.isMac) {
+        compilerHome = new File(System.getProperty("java.home")).getAbsolutePath();
+      }
+      else {
+        compilerHome = new File(System.getProperty("java.home")).getParentFile().getAbsolutePath();        
+      }
+    }
+    return compilerHome;
+  }
+
+  private static Pattern compilePattern(@NonNls String s) throws MalformedPatternException {
+    try {
+      final PatternCompiler compiler = new Perl5Compiler();
+      return SystemInfo.isFileSystemCaseSensitive? compiler.compile(s) : compiler.compile(s, Perl5Compiler.CASE_INSENSITIVE_MASK);
+    }
+    catch (org.apache.oro.text.regex.MalformedPatternException ex) {
+      throw new MalformedPatternException(ex);
+    }
+  }
+
+  public void disposeComponent() {
+  }
+
+  public void initComponent() { }
+
+  public void projectClosed() {
+  }
+
+  public JavacCompiler getJavacCompiler() {
+    createCompilers();
+    return JAVAC_EXTERNAL_BACKEND;
+  }
+
+  public void projectOpened() {
+    createCompilers();
+  }
+
+  private void createCompilers() {
+    if (JAVAC_EXTERNAL_BACKEND != null) {
+      return;
+    }
+
+    JAVAC_EXTERNAL_BACKEND = new JavacCompiler(myProject);
+    myRegisteredCompilers.add(JAVAC_EXTERNAL_BACKEND);
+
+    if (!ApplicationManager.getApplication().isUnitTestMode()) {
+      //final BackendCompiler JIKES_BACKEND = new JikesCompiler(myProject);
+      //myRegisteredCompilers.add(JIKES_BACKEND);
+
+      if (EclipseCompiler.isInitialized()) {
+        final EclipseCompiler eclipse = new EclipseCompiler(myProject);
+        myRegisteredCompilers.add(eclipse);
+      }
+
+      if (ApplicationManagerEx.getApplicationEx().isInternal()) {
+        try {
+          final EclipseEmbeddedCompiler eclipseEmbedded = new EclipseEmbeddedCompiler(myProject);
+          myRegisteredCompilers.add(eclipseEmbedded);
+        }
+        catch (NoClassDefFoundError e) {
+          // eclipse jar must be not in the classpath
+        }
+        try {
+          CompilerAPICompiler inProcessJavaCompiler = new CompilerAPICompiler(myProject);
+          myRegisteredCompilers.add(inProcessJavaCompiler);
+        }
+        catch (NoClassDefFoundError e) {
+          // wrong JDK
+        }
+      }
+    }
+
+    final BackendCompiler[] compilers = Extensions.getExtensions(BackendCompiler.EP_NAME, myProject);
+    final Set<FileType> types = new HashSet<FileType>();
+    for (BackendCompiler compiler : compilers) {
+      myRegisteredCompilers.add(compiler);
+      types.addAll(compiler.getCompilableFileTypes());
+    }
+
+    final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+    for (FileType type : types) {
+      compilerManager.addCompilableFileType(type);
+    }
+
+    myDefaultJavaCompiler = JAVAC_EXTERNAL_BACKEND;
+    for (BackendCompiler compiler : myRegisteredCompilers) {
+      if (compiler.getId().equals(DEFAULT_COMPILER)) {
+        myDefaultJavaCompiler = compiler;
+        break;
+      }
+    }
+    DEFAULT_COMPILER = myDefaultJavaCompiler.getId();
+  }
+
+  public Collection<BackendCompiler> getRegisteredJavaCompilers() {
+    createCompilers();
+    return myRegisteredCompilers;
+  }
+
+  public String[] getResourceFilePatterns() {
+    return getWildcardPatterns();
+  }
+
+  private String[] getRegexpPatterns() {
+    String[] patterns = ArrayUtil.newStringArray(myRegexpResourcePatterns.size());
+    int index = 0;
+    for (final Pattern myRegexpResourcePattern : myRegexpResourcePatterns) {
+      patterns[index++] = myRegexpResourcePattern.getPattern();
+    }
+    return patterns;
+  }
+
+  private String[] getWildcardPatterns() {
+    return ArrayUtil.toStringArray(myWildcardPatterns);
+  }
+
+  public void addResourceFilePattern(String namePattern) throws MalformedPatternException {
+    addWildcardResourcePattern(namePattern);
+  }
+
+  // need this method only for handling patterns in old regexp format
+  private void addRegexpPattern(String namePattern) throws MalformedPatternException {
+    Pattern pattern = compilePattern(namePattern);
+    if (pattern != null) {
+      myRegexpResourcePatterns.add(pattern);
+    }
+  }
+
+  @Override
+  public ExcludedEntriesConfiguration getExcludedEntriesConfiguration() {
+    return myExcludedEntriesConfiguration;
+  }
+
+  public boolean isExcludedFromCompilation(final VirtualFile virtualFile) {
+    return myExcludedEntriesConfiguration.isExcluded(virtualFile);
+  }
+
+  @Override
+  public boolean isResourceFile(VirtualFile virtualFile) {
+    return isResourceFile(virtualFile.getName(), virtualFile.getParent());
+  }
+
+  @Override
+  public boolean isAddNotNullAssertions() {
+    return myAddNotNullAssertions;
+  }
+
+  @Override
+  public void setAddNotNullAssertions(boolean enabled) {
+    myAddNotNullAssertions = enabled;
+  }
+
+  @NotNull
+  public ProcessorConfigProfile getDefaultProcessorProfile() {
+    return myDefaultProcessorsProfile;
+  }
+
+  public void setDefaultProcessorProfile(ProcessorConfigProfile profile) {
+    myDefaultProcessorsProfile.initFrom(profile);
+  }
+
+  @NotNull
+  public List<ProcessorConfigProfile> getModuleProcessorProfiles() {
+    return myModuleProcessorProfiles;
+  }
+
+  public void setModuleProcessorProfiles(Collection<ProcessorConfigProfile> moduleProfiles) {
+    myModuleProcessorProfiles.clear();
+    myModuleProcessorProfiles.addAll(moduleProfiles);
+    myProcessorsProfilesMap = null;
+  }
+
+  @Nullable
+  public ProcessorConfigProfile findModuleProcessorProfile(@NotNull String name) {
+    for (ProcessorConfigProfile profile : myModuleProcessorProfiles) {
+      if (name.equals(profile.getName())) {
+        return profile;
+      }
+    }
+
+    return null;
+  }
+
+  public void removeModuleProcessorProfile(ProcessorConfigProfile profile) {
+    myModuleProcessorProfiles.remove(profile);
+    myProcessorsProfilesMap = null; // clear cache
+  }
+
+  public void addModuleProcessorProfile(@NotNull ProcessorConfigProfile profile) {
+    myModuleProcessorProfiles.add(profile);
+    myProcessorsProfilesMap = null; // clear cache
+  }
+
+  @Override
+  @NotNull
+  public ProcessorConfigProfile getAnnotationProcessingConfiguration(Module module) {
+    Map<Module, ProcessorConfigProfile> map = myProcessorsProfilesMap;
+    if (map == null) {
+      map = new HashMap<Module, ProcessorConfigProfile>();
+      final Map<String, Module> namesMap = new HashMap<String, Module>();
+      for (Module m : ModuleManager.getInstance(module.getProject()).getModules()) {
+        namesMap.put(m.getName(), m);
+      }
+      if (!namesMap.isEmpty()) {
+        for (ProcessorConfigProfile profile : myModuleProcessorProfiles) {
+          for (String name : profile.getModuleNames()) {
+            final Module mod = namesMap.get(name);
+            if (mod != null) {
+              map.put(mod, profile);
+            }
+          }
+        }
+      }
+      myProcessorsProfilesMap = map;
+    }
+    final ProcessorConfigProfile profile = map.get(module);
+    return profile != null? profile : myDefaultProcessorsProfile;
+  }
+
+  @Override
+  public boolean isAnnotationProcessorsEnabled() {
+    if (myDefaultProcessorsProfile.isEnabled()) {
+      return true;
+    }
+    for (ProcessorConfigProfile profile : myModuleProcessorProfiles) {
+      if (profile.isEnabled()) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private void addWildcardResourcePattern(@NonNls final String wildcardPattern) throws MalformedPatternException {
+    final CompiledPattern pattern = convertToRegexp(wildcardPattern);
+    if (pattern != null) {
+      myWildcardPatterns.add(wildcardPattern);
+      if (isPatternNegated(wildcardPattern)) {
+        myNegatedCompiledPatterns.add(pattern);
+      }
+      else {
+        myCompiledPatterns.add(pattern);
+      }
+    }
+  }
+
+  public void removeResourceFilePatterns() {
+    removeWildcardPatterns();
+  }
+
+  private void removeRegexpPatterns() {
+    myRegexpResourcePatterns.clear();
+  }
+
+  private void removeWildcardPatterns() {
+    myWildcardPatterns.clear();
+    myCompiledPatterns.clear();
+    myNegatedCompiledPatterns.clear();
+  }
+
+  private static CompiledPattern convertToRegexp(String wildcardPattern) {
+    if (isPatternNegated(wildcardPattern)) {
+      wildcardPattern = wildcardPattern.substring(1);
+    }
+
+    wildcardPattern = FileUtil.toSystemIndependentName(wildcardPattern);
+
+    String srcRoot = null;
+    int colon = wildcardPattern.indexOf(":");
+    if (colon > 0) {
+      srcRoot = wildcardPattern.substring(0, colon);
+      wildcardPattern = wildcardPattern.substring(colon + 1);
+    }
+
+    String dirPattern = null;
+    int slash = wildcardPattern.lastIndexOf('/');
+    if (slash >= 0) {
+      dirPattern = wildcardPattern.substring(0, slash + 1);
+      wildcardPattern = wildcardPattern.substring(slash + 1);
+      if (!dirPattern.startsWith("/")) {
+        dirPattern = "/" + dirPattern;
+      }
+      //now dirPattern starts and ends with '/'
+
+      dirPattern = normalizeWildcards(dirPattern);
+
+      dirPattern = StringUtil.replace(dirPattern, "/.*.*/", "(/.*)?/");
+      dirPattern = StringUtil.trimEnd(dirPattern, "/");
+
+      dirPattern = optimize(dirPattern);
+    }
+
+    wildcardPattern = normalizeWildcards(wildcardPattern);
+    wildcardPattern = optimize(wildcardPattern);
+
+    final Pattern dirCompiled = dirPattern == null ? null : compilePattern(dirPattern);
+    final Pattern srcCompiled = srcRoot == null ? null : compilePattern(optimize(normalizeWildcards(srcRoot)));
+    return new CompiledPattern(compilePattern(wildcardPattern), dirCompiled, srcCompiled);
+  }
+
+  private static String optimize(String wildcardPattern) {
+    return wildcardPattern.replaceAll("(?:\\.\\*)+", ".*");
+  }
+
+  private static String normalizeWildcards(String wildcardPattern) {
+    wildcardPattern = StringUtil.replace(wildcardPattern, "\\!", "!");
+    wildcardPattern = StringUtil.replace(wildcardPattern, ".", "\\.");
+    wildcardPattern = StringUtil.replace(wildcardPattern, "*?", ".+");
+    wildcardPattern = StringUtil.replace(wildcardPattern, "?*", ".+");
+    wildcardPattern = StringUtil.replace(wildcardPattern, "*", ".*");
+    wildcardPattern = StringUtil.replace(wildcardPattern, "?", ".");
+    return wildcardPattern;
+  }
+
+  public static boolean isPatternNegated(String wildcardPattern) {
+    return wildcardPattern.length() > 1 && wildcardPattern.charAt(0) == '!';
+  }
+
+  public boolean isResourceFile(String name) {
+    return isResourceFile(name, null);
+  }
+
+  private boolean matches(String s, Pattern p) {
+    synchronized (myPatternMatcher) {
+      try {
+        return myPatternMatcher.matches(s, p);
+      }
+      catch (Exception e) {
+        LOG.error("Exception matching file name \"" + s + "\" against the pattern \"" + p + "\"", e);
+        return false;
+      }
+    }
+  }
+
+  private boolean isResourceFile(String name, @Nullable VirtualFile parent) {
+    final Ref<String> parentRef = Ref.create(null);
+    //noinspection ForLoopReplaceableByForEach
+    for (int i = 0; i < myCompiledPatterns.size(); i++) {
+      if (matches(name, parent, parentRef, myCompiledPatterns.get(i))) {
+        return true;
+      }
+    }
+
+    if (myNegatedCompiledPatterns.isEmpty()) {
+      return false;
+    }
+
+    //noinspection ForLoopReplaceableByForEach
+    for (int i = 0; i < myNegatedCompiledPatterns.size(); i++) {
+      if (matches(name, parent, parentRef, myNegatedCompiledPatterns.get(i))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private boolean matches(String name, VirtualFile parent, Ref<String> parentRef, CompiledPattern pair) {
+    if (!matches(name, pair.fileName)) {
+      return false;
+    }
+
+    if (parent != null && (pair.dir != null || pair.srcRoot != null)) {
+      VirtualFile srcRoot = ProjectRootManager.getInstance(myProject).getFileIndex().getSourceRootForFile(parent);
+      if (pair.dir != null) {
+        String parentPath = parentRef.get();
+        if (parentPath == null) {
+          parentRef.set(parentPath = srcRoot == null ? parent.getPath() : VfsUtilCore.getRelativePath(parent, srcRoot, '/'));
+        }
+        if (parentPath == null || !matches("/" + parentPath, pair.dir)) {
+          return false;
+        }
+      }
+
+      if (pair.srcRoot != null) {
+        String srcRootName = srcRoot == null ? null : srcRoot.getName();
+        if (srcRootName == null || !matches(srcRootName, pair.srcRoot)) {
+          return false;
+        }
+      }
+    }
+
+    return true;
+  }
+
+
+  public void readExternal(Element parentNode) throws InvalidDataException {
+    DefaultJDOMExternalizer.readExternal(this, parentNode);
+
+    final Element notNullAssertions = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.ADD_NOTNULL_ASSERTIONS);
+    if (notNullAssertions != null) {
+      myAddNotNullAssertions = Boolean.valueOf(notNullAssertions.getAttributeValue(JpsJavaCompilerConfigurationSerializer.ENABLED, "true"));
+    }
+
+    Element node = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.EXCLUDE_FROM_COMPILE);
+    if (node != null) {
+      myExcludedEntriesConfiguration.readExternal(node);
+    }
+
+    try {
+      removeRegexpPatterns();
+      node = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.RESOURCE_EXTENSIONS);
+      if (node != null) {
+        for (final Object o : node.getChildren(JpsJavaCompilerConfigurationSerializer.ENTRY)) {
+          Element element = (Element)o;
+          String pattern = element.getAttributeValue(JpsJavaCompilerConfigurationSerializer.NAME);
+          if (!StringUtil.isEmpty(pattern)) {
+            addRegexpPattern(pattern);
+          }
+        }
+      }
+
+      removeWildcardPatterns();
+      node = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.WILDCARD_RESOURCE_PATTERNS);
+      if (node != null) {
+        myWildcardPatternsInitialized = true;
+        for (final Object o : node.getChildren(JpsJavaCompilerConfigurationSerializer.ENTRY)) {
+          final Element element = (Element)o;
+          String pattern = element.getAttributeValue(JpsJavaCompilerConfigurationSerializer.NAME);
+          if (!StringUtil.isEmpty(pattern)) {
+            addWildcardResourcePattern(pattern);
+          }
+        }
+      }
+    }
+    catch (MalformedPatternException e) {
+      throw new InvalidDataException(e);
+    }
+
+
+    myModuleProcessorProfiles.clear();
+    myProcessorsProfilesMap = null;
+
+    final Element annotationProcessingSettings = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.ANNOTATION_PROCESSING);
+    if (annotationProcessingSettings != null) {
+      final List profiles = annotationProcessingSettings.getChildren("profile");
+      if (!profiles.isEmpty()) {
+        for (Object elem : profiles) {
+          final Element profileElement = (Element)elem;
+          final boolean isDefault = "true".equals(profileElement.getAttributeValue("default"));
+          if (isDefault) {
+            AnnotationProcessorProfileSerializer.readExternal(myDefaultProcessorsProfile, profileElement);
+          }
+          else {
+            final ProcessorConfigProfile profile = new ProcessorConfigProfileImpl("");
+            AnnotationProcessorProfileSerializer.readExternal(profile, profileElement);
+            myModuleProcessorProfiles.add(profile);
+          }
+        }
+      }
+      else {
+        // assuming older format
+        loadProfilesFromOldFormat(annotationProcessingSettings);
+      }
+    }
+
+    myBytecodeTargetLevel = null;
+    myModuleBytecodeTarget.clear();
+    final Element bytecodeTargetElement = parentNode.getChild(JpsJavaCompilerConfigurationSerializer.BYTECODE_TARGET_LEVEL);
+    if (bytecodeTargetElement != null) {
+      myBytecodeTargetLevel = bytecodeTargetElement.getAttributeValue(JpsJavaCompilerConfigurationSerializer.TARGET_ATTRIBUTE);
+      for (Element elem : (Collection<Element>)bytecodeTargetElement.getChildren(JpsJavaCompilerConfigurationSerializer.MODULE)) {
+        final String name = elem.getAttributeValue(JpsJavaCompilerConfigurationSerializer.NAME);
+        if (name == null) {
+          continue;
+        }
+        final String target = elem.getAttributeValue(JpsJavaCompilerConfigurationSerializer.TARGET_ATTRIBUTE);
+        if (target == null) {
+          continue;
+        }
+        myModuleBytecodeTarget.put(name, target);
+      }
+    }
+  }
+
+  private void loadProfilesFromOldFormat(Element processing) {
+    // collect data
+    final boolean isEnabled = Boolean.parseBoolean(processing.getAttributeValue(JpsJavaCompilerConfigurationSerializer.ENABLED, "false"));
+    final boolean isUseClasspath = Boolean.parseBoolean(processing.getAttributeValue("useClasspath", "true"));
+    final StringBuilder processorPath = new StringBuilder();
+    final Set<String> optionPairs = new HashSet<String>();
+    final Set<String> processors = new HashSet<String>();
+    final List<Pair<String, String>> modulesToProcess = new ArrayList<Pair<String, String>>();
+
+    for (Object child : processing.getChildren("processorPath")) {
+      final Element pathElement = (Element)child;
+      final String path = pathElement.getAttributeValue("value", (String)null);
+      if (path != null) {
+        if (processorPath.length() > 0) {
+          processorPath.append(File.pathSeparator);
+        }
+        processorPath.append(path);
+      }
+    }
+
+    for (Object child : processing.getChildren("processor")) {
+      final Element processorElement = (Element)child;
+      final String proc = processorElement.getAttributeValue(JpsJavaCompilerConfigurationSerializer.NAME, (String)null);
+      if (proc != null) {
+        processors.add(proc);
+      }
+      final StringTokenizer tokenizer = new StringTokenizer(processorElement.getAttributeValue("options", ""), " ", false);
+      while (tokenizer.hasMoreTokens()) {
+        final String pair = tokenizer.nextToken();
+        optionPairs.add(pair);
+      }
+    }
+
+    for (Object child : processing.getChildren("processModule")) {
+      final Element moduleElement = (Element)child;
+      final String name = moduleElement.getAttributeValue(JpsJavaCompilerConfigurationSerializer.NAME, (String)null);
+      if (name == null) {
+        continue;
+      }
+      final String dir = moduleElement.getAttributeValue("generatedDirName", (String)null);
+      modulesToProcess.add(Pair.create(name, dir));
+    }
+
+    myDefaultProcessorsProfile.setEnabled(false);
+    myDefaultProcessorsProfile.setObtainProcessorsFromClasspath(isUseClasspath);
+    if (processorPath.length() > 0) {
+      myDefaultProcessorsProfile.setProcessorPath(processorPath.toString());
+    }
+    if (!optionPairs.isEmpty()) {
+      for (String pair : optionPairs) {
+        final int index = pair.indexOf("=");
+        if (index > 0) {
+          myDefaultProcessorsProfile.setOption(pair.substring(0, index), pair.substring(index + 1));
+        }
+      }
+    }
+    for (String processor : processors) {
+      myDefaultProcessorsProfile.addProcessor(processor);
+    }
+
+    final Map<String, Set<String>> dirNameToModulesMap = new HashMap<String, Set<String>>();
+    for (Pair<String, String> moduleDirPair : modulesToProcess) {
+      final String dir = moduleDirPair.getSecond();
+      Set<String> set = dirNameToModulesMap.get(dir);
+      if (set == null) {
+        set = new HashSet<String>();
+        dirNameToModulesMap.put(dir, set);
+      }
+      set.add(moduleDirPair.getFirst());
+    }
+
+    int profileIndex = 0;
+    for (Map.Entry<String, Set<String>> entry : dirNameToModulesMap.entrySet()) {
+      final String dirName = entry.getKey();
+      final ProcessorConfigProfile profile = new ProcessorConfigProfileImpl(myDefaultProcessorsProfile);
+      profile.setName("Profile" + (++profileIndex));
+      profile.setEnabled(isEnabled);
+      profile.setGeneratedSourcesDirectoryName(dirName, false);
+      for (String moduleName : entry.getValue()) {
+        profile.addModuleName(moduleName);
+      }
+      myModuleProcessorProfiles.add(profile);
+    }
+  }
+
+  public void writeExternal(Element parentNode) throws WriteExternalException {
+    DefaultJDOMExternalizer.writeExternal(this, parentNode);
+
+    if (myAddNotNullAssertions != true) {
+      addChild(parentNode, JpsJavaCompilerConfigurationSerializer.ADD_NOTNULL_ASSERTIONS).setAttribute(
+        JpsJavaCompilerConfigurationSerializer.ENABLED, String.valueOf(myAddNotNullAssertions));
+    }
+
+    if(myExcludedEntriesConfiguration.getExcludeEntryDescriptions().length > 0) {
+      myExcludedEntriesConfiguration.writeExternal(addChild(parentNode, JpsJavaCompilerConfigurationSerializer.EXCLUDE_FROM_COMPILE));
+    }
+
+    final Element newChild = addChild(parentNode, JpsJavaCompilerConfigurationSerializer.RESOURCE_EXTENSIONS);
+    for (final String pattern : getRegexpPatterns()) {
+      addChild(newChild, JpsJavaCompilerConfigurationSerializer.ENTRY).setAttribute(JpsJavaCompilerConfigurationSerializer.NAME, pattern);
+    }
+
+    if (myWildcardPatternsInitialized || !myWildcardPatterns.isEmpty()) {
+      final Element wildcardPatterns = addChild(parentNode, JpsJavaCompilerConfigurationSerializer.WILDCARD_RESOURCE_PATTERNS);
+      for (final String wildcardPattern : myWildcardPatterns) {
+        addChild(wildcardPatterns, JpsJavaCompilerConfigurationSerializer.ENTRY).setAttribute(JpsJavaCompilerConfigurationSerializer.NAME, wildcardPattern);
+      }
+    }
+
+    final Element annotationProcessingSettings = addChild(parentNode, JpsJavaCompilerConfigurationSerializer.ANNOTATION_PROCESSING);
+    final Element defaultProfileElem = addChild(annotationProcessingSettings, "profile").setAttribute("default", "true");
+    AnnotationProcessorProfileSerializer.writeExternal(myDefaultProcessorsProfile, defaultProfileElem);
+    for (ProcessorConfigProfile profile : myModuleProcessorProfiles) {
+      final Element profileElem = addChild(annotationProcessingSettings, "profile").setAttribute("default", "false");
+      AnnotationProcessorProfileSerializer.writeExternal(profile, profileElem);
+    }
+
+    if (!StringUtil.isEmpty(myBytecodeTargetLevel) || !myModuleBytecodeTarget.isEmpty()) {
+      final Element bytecodeTarget = addChild(parentNode, JpsJavaCompilerConfigurationSerializer.BYTECODE_TARGET_LEVEL);
+      if (!StringUtil.isEmpty(myBytecodeTargetLevel)) {
+        bytecodeTarget.setAttribute(JpsJavaCompilerConfigurationSerializer.TARGET_ATTRIBUTE, myBytecodeTargetLevel);
+      }
+      if (!myModuleBytecodeTarget.isEmpty()) {
+        final List<String> moduleNames = new ArrayList<String>(myModuleBytecodeTarget.keySet());
+        Collections.sort(moduleNames, String.CASE_INSENSITIVE_ORDER);
+        for (String name : moduleNames) {
+          final Element moduleElement = addChild(bytecodeTarget, JpsJavaCompilerConfigurationSerializer.MODULE);
+          moduleElement.setAttribute(JpsJavaCompilerConfigurationSerializer.NAME, name);
+          final String value = myModuleBytecodeTarget.get(name);
+          moduleElement.setAttribute(JpsJavaCompilerConfigurationSerializer.TARGET_ATTRIBUTE, value != null? value : "");
+        }
+      }
+    }
+  }
+
+  @NotNull @NonNls
+  public String getComponentName() {
+    return "CompilerConfiguration";
+  }
+
+  public BackendCompiler getDefaultCompiler() {
+    createCompilers();
+    return myDefaultJavaCompiler;
+  }
+
+  /**
+   * @param defaultCompiler The compiler that is passed as a parameter to setDefaultCompiler() 
+   * must be one of the registered compilers in compiler configuration.
+   * Otherwise because of lazy compiler initialization, the value of default compiler will point to some other compiler instance
+   */
+  public void setDefaultCompiler(BackendCompiler defaultCompiler) {
+    myDefaultJavaCompiler = defaultCompiler;
+    DEFAULT_COMPILER = defaultCompiler.getId();
+  }
+
+  public void convertPatterns() {
+    if (!needPatternConversion()) {
+      return;
+    }
+    try {
+      boolean ok;
+      try {
+        ok = doConvertPatterns();
+      }
+      catch (MalformedPatternException e) {
+        ok = false;
+      }
+      if (!ok) {
+        final String initialPatternString = patternsToString(getRegexpPatterns());
+        final String message = CompilerBundle.message(
+          "message.resource.patterns.format.changed",
+          ApplicationNamesInfo.getInstance().getProductName(),
+          initialPatternString,
+          CommonBundle.getOkButtonText(),
+          CommonBundle.getCancelButtonText()
+        );
+        final String wildcardPatterns = Messages.showInputDialog(
+          myProject, message, CompilerBundle.message("pattern.conversion.dialog.title"), Messages.getWarningIcon(), initialPatternString, new InputValidator() {
+          public boolean checkInput(String inputString) {
+            return true;
+          }
+          public boolean canClose(String inputString) {
+            final StringTokenizer tokenizer = new StringTokenizer(inputString, ";", false);
+            StringBuilder malformedPatterns = new StringBuilder();
+
+            while (tokenizer.hasMoreTokens()) {
+              String pattern = tokenizer.nextToken();
+              try {
+                addWildcardResourcePattern(pattern);
+              }
+              catch (MalformedPatternException e) {
+                malformedPatterns.append("\n\n");
+                malformedPatterns.append(pattern);
+                malformedPatterns.append(": ");
+                malformedPatterns.append(e.getMessage());
+              }
+            }
+
+            if (malformedPatterns.length() > 0) {
+              Messages.showErrorDialog(CompilerBundle.message("error.bad.resource.patterns", malformedPatterns.toString()),
+                                       CompilerBundle.message("bad.resource.patterns.dialog.title"));
+              removeWildcardPatterns();
+              return false;
+            }
+            return true;
+          }
+        });
+        if (wildcardPatterns == null) { // cancel pressed
+          loadDefaultWildcardPatterns();
+        }
+      }
+    }
+    finally {
+      myWildcardPatternsInitialized = true;
+    }
+  }
+
+  private boolean needPatternConversion() {
+    return !myWildcardPatternsInitialized && !myRegexpResourcePatterns.isEmpty();
+  }
+
+  private boolean doConvertPatterns() throws MalformedPatternException {
+    final String[] regexpPatterns = getRegexpPatterns();
+    final List<String> converted = new ArrayList<String>();
+    final Pattern multipleExtensionsPatternPattern = compilePattern("\\.\\+\\\\\\.\\((\\w+(?:\\|\\w+)*)\\)");
+    final Pattern singleExtensionPatternPattern = compilePattern("\\.\\+\\\\\\.(\\w+)");
+    final Perl5Matcher matcher = new Perl5Matcher();
+    for (final String regexpPattern : regexpPatterns) {
+      //final Matcher multipleExtensionsMatcher = multipleExtensionsPatternPattern.matcher(regexpPattern);
+      if (matcher.matches(regexpPattern, multipleExtensionsPatternPattern)) {
+        final MatchResult match = matcher.getMatch();
+        final StringTokenizer tokenizer = new StringTokenizer(match.group(1), "|", false);
+        while (tokenizer.hasMoreTokens()) {
+          converted.add("?*." + tokenizer.nextToken());
+        }
+      }
+      else {
+        //final Matcher singleExtensionMatcher = singleExtensionPatternPattern.matcher(regexpPattern);
+        if (matcher.matches(regexpPattern, singleExtensionPatternPattern)) {
+          final MatchResult match = matcher.getMatch();
+          converted.add("?*." + match.group(1));
+        }
+        else {
+          return false;
+        }
+      }
+    }
+    for (final String aConverted : converted) {
+      addWildcardResourcePattern(aConverted);
+    }
+    return true;
+  }
+
+  private static String patternsToString(final String[] patterns) {
+    final StringBuilder extensionsString = new StringBuilder();
+    for (int idx = 0; idx < patterns.length; idx++) {
+      if (idx > 0) {
+        extensionsString.append(";");
+      }
+      extensionsString.append(patterns[idx]);
+    }
+    return extensionsString.toString();
+  }
+  
+  private static class CompiledPattern {
+    @NotNull final Pattern fileName;
+    @Nullable final Pattern dir;
+    @Nullable final Pattern srcRoot;
+
+    private CompiledPattern(Pattern fileName, Pattern dir, Pattern srcRoot) {
+      this.fileName = fileName;
+      this.dir = dir;
+      this.srcRoot = srcRoot;
+    }
+  }
+
+  private static Element addChild(Element parent, final String childName) {
+    final Element child = new Element(childName);
+    parent.addContent(child);
+    return child;
+  }
+
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerEncodingService.java b/java/compiler/impl/src/com/intellij/compiler/CompilerEncodingService.java
new file mode 100644
index 0000000..9c88df8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerEncodingService.java
@@ -0,0 +1,56 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.nio.charset.Charset;
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public abstract class CompilerEncodingService {
+  public static CompilerEncodingService getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, CompilerEncodingService.class);
+  }
+
+  @Nullable
+  public static Charset getPreferredModuleEncoding(Chunk<Module> chunk) {
+    CompilerEncodingService service = null;
+    for (Module module : chunk.getNodes()) {
+      if (service == null) {
+        service = getInstance(module.getProject());
+      }
+      final Charset charset = service.getPreferredModuleEncoding(module);
+      if (charset != null) {
+        return charset;
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  public abstract Charset getPreferredModuleEncoding(@NotNull Module module);
+
+  @NotNull
+  public abstract Collection<Charset> getAllModuleEncodings(@NotNull Module module);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerException.java b/java/compiler/impl/src/com/intellij/compiler/CompilerException.java
new file mode 100644
index 0000000..d982f9c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerException.java
@@ -0,0 +1,30 @@
+/*
+ * 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: Oct 15, 2002
+ * Time: 1:55:22 PM
+ */
+package com.intellij.compiler;
+
+public class CompilerException extends Exception {
+
+  public CompilerException(String message, Throwable cause) {
+    super(message, cause);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerIOUtil.java b/java/compiler/impl/src/com/intellij/compiler/CompilerIOUtil.java
new file mode 100644
index 0000000..4616bc9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerIOUtil.java
@@ -0,0 +1,80 @@
+/*
+ * 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.compiler;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class CompilerIOUtil {
+  private final static ThreadLocal<byte[]> myBuffer = new ThreadLocal<byte[]>() {
+    protected byte[] initialValue() {
+      return new byte[1024];
+    }
+  };
+
+  private CompilerIOUtil() {}
+
+  public static String readString(DataInput stream) throws IOException {
+    final int length = stream.readInt();
+    if (length == -1) {
+      return null;
+    }
+
+    if (length == 0) {
+      return "";
+    }
+
+    char[] chars = new char[length];
+    int charsRead = 0;
+
+    final byte[] buff = myBuffer.get();
+    while (charsRead < length) {
+      final int bytesRead = Math.min((length - charsRead) * 2, buff.length);
+      stream.readFully(buff, 0, bytesRead);
+      for (int i = 0 ; i < bytesRead; i += 2) {
+        chars[charsRead++] = (char)((buff[i] << 8) + (buff[i + 1] & 0xFF));
+      }
+    }
+
+    return new String(chars);
+  }
+
+  public static void writeString(String s, DataOutput stream) throws IOException {
+    if (s == null) {
+      stream.writeInt(-1);
+      return;
+    }
+
+    final int len = s.length();
+    stream.writeInt(len);
+    if (len == 0) {
+      return;
+    }
+
+    int charsWritten = 0;
+    final byte[] buff = myBuffer.get();
+    while (charsWritten < len) {
+      final int bytesWritten = Math.min((len - charsWritten) * 2, buff.length);
+      for (int i = 0; i < bytesWritten; i += 2) {
+        char aChar = s.charAt(charsWritten++);
+        buff[i] = (byte)((aChar >>> 8) & 0xFF);
+        buff[i + 1] = (byte)((aChar) & 0xFF);
+      }
+      stream.write(buff, 0, bytesWritten);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerIconLayerProvider.java b/java/compiler/impl/src/com/intellij/compiler/CompilerIconLayerProvider.java
new file mode 100644
index 0000000..3f2b16d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerIconLayerProvider.java
@@ -0,0 +1,66 @@
+/*
+ * Copyright 2000-2011 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.compiler;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.ide.IconLayerProvider;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.FileIndexFacade;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author yole
+ */
+public class CompilerIconLayerProvider implements IconLayerProvider {
+  @Override
+  public Icon getLayerIcon(@NotNull Iconable element, boolean isLocked) {
+    VirtualFile vFile = null;
+    Project project = null;
+    if (element instanceof PsiModifierListOwner) {
+      project = ((PsiModifierListOwner) element).getProject();
+      final PsiFile containingFile = ((PsiModifierListOwner) element).getContainingFile();
+      vFile = containingFile == null ? null : containingFile.getVirtualFile();
+    }
+    else if (element instanceof PsiDirectory) {
+      project = ((PsiDirectory) element).getProject();
+      vFile = ((PsiDirectory) element).getVirtualFile();
+    }
+    if (vFile != null && isExcluded(vFile, project)) {
+      return PlatformIcons.EXCLUDED_FROM_COMPILE_ICON;
+    }
+    return null;
+  }
+
+  @Override
+  public String getLayerDescription() {
+    return CodeInsightBundle.message("node.excluded.flag.tooltip");
+  }
+
+  public static boolean isExcluded(final VirtualFile vFile, final Project project) {
+    return vFile != null
+           && ServiceManager.getService(project, FileIndexFacade.class).isInSource(vFile)
+           && CompilerConfiguration.getInstance(project).isExcludedFromCompilation(vFile);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java
new file mode 100644
index 0000000..f505855
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerManagerImpl.java
@@ -0,0 +1,466 @@
+/*
+ * 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.compiler;
+
+import com.intellij.compiler.impl.*;
+import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
+import com.intellij.compiler.impl.javaCompiler.JavaCompiler;
+import com.intellij.compiler.impl.resourceCompiler.ResourceCompiler;
+import com.intellij.compiler.impl.rmiCompiler.RmicCompiler;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Chunk;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.graph.CachingSemiGraph;
+import com.intellij.util.graph.Graph;
+import com.intellij.util.graph.GraphGenerator;
+import com.intellij.util.messages.MessageBus;
+import com.intellij.util.messages.MessageBusConnection;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.lang.reflect.Array;
+import java.util.*;
+import java.util.concurrent.Semaphore;
+
+public class CompilerManagerImpl extends CompilerManager {
+  private final Project myProject;
+
+  private final List<Compiler> myCompilers = new ArrayList<Compiler>();
+  private final List<TranslatingCompiler> myTranslators = new ArrayList<TranslatingCompiler>();
+
+  private final List<CompileTask> myBeforeTasks = new ArrayList<CompileTask>();
+  private final List<CompileTask> myAfterTasks = new ArrayList<CompileTask>();
+  private final Set<FileType> myCompilableTypes = new HashSet<FileType>();
+  private final CompilationStatusListener myEventPublisher;
+  private final Semaphore myCompilationSemaphore = new Semaphore(1, true);
+  private final Map<Compiler, Set<FileType>> myCompilerToInputTypes = new HashMap<Compiler, Set<FileType>>();
+  private final Map<Compiler, Set<FileType>> myCompilerToOutputTypes = new HashMap<Compiler, Set<FileType>>();
+  private final Set<ModuleType> myValidationDisabledModuleTypes = new HashSet<ModuleType>();
+  private final Set<LocalFileSystem.WatchRequest> myWatchRoots;
+
+  public CompilerManagerImpl(final Project project, CompilerConfigurationImpl compilerConfiguration, MessageBus messageBus) {
+    myProject = project;
+    myEventPublisher = messageBus.syncPublisher(CompilerTopics.COMPILATION_STATUS);
+
+    // predefined compilers
+    addTranslatingCompiler(new AnnotationProcessingCompiler(project), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA, StdFileTypes.CLASS)));
+    addTranslatingCompiler(new JavaCompiler(project), new HashSet<FileType>(Arrays.asList(StdFileTypes.JAVA)), new HashSet<FileType>(Arrays.asList(StdFileTypes.CLASS)));
+    addCompiler(new ResourceCompiler(project, compilerConfiguration));
+    addCompiler(new RmicCompiler());
+
+    for(Compiler compiler: Extensions.getExtensions(Compiler.EP_NAME, myProject)) {
+      addCompiler(compiler);
+    }
+    for(CompilerFactory factory: Extensions.getExtensions(CompilerFactory.EP_NAME, myProject)) {
+      Compiler[] compilers = factory.createCompilers(this);
+      for (Compiler compiler : compilers) {
+        addCompiler(compiler);
+      }
+    }
+
+    addCompilableFileType(StdFileTypes.JAVA);
+
+    final File projectGeneratedSrcRoot = CompilerPaths.getGeneratedDataDirectory(project);
+    projectGeneratedSrcRoot.mkdirs();
+    final LocalFileSystem lfs = LocalFileSystem.getInstance();
+    myWatchRoots = lfs.addRootsToWatch(Collections.singletonList(FileUtil.toCanonicalPath(projectGeneratedSrcRoot.getPath())), true);
+    Disposer.register(project, new Disposable() {
+      public void dispose() {
+        lfs.removeWatchedRoots(myWatchRoots);
+        if (ApplicationManager.getApplication().isUnitTestMode()) {    // force cleanup for created compiler system directory with generated sources
+          FileUtil.delete(CompilerPaths.getCompilerSystemDirectory(project));
+        }
+      }
+    });
+
+    //
+    //addCompiler(new DummyTransformingCompiler()); // this one is for testing purposes only
+    //addCompiler(new DummySourceGeneratingCompiler(myProject)); // this one is for testing purposes only
+    /*
+    // for testing only
+    ApplicationManager.getApplication().invokeLater(new Runnable() {
+      public void run() {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          public void run() {
+            FileTypeManager.getInstance().registerFileType(DummyTranslatingCompiler.INPUT_FILE_TYPE, DummyTranslatingCompiler.FILETYPE_EXTENSION);
+            addTranslatingCompiler(
+              new DummyTranslatingCompiler(),
+              new HashSet<FileType>(Arrays.asList(DummyTranslatingCompiler.INPUT_FILE_TYPE)),
+              new HashSet<FileType>(Arrays.asList( StdFileTypes.JAVA))
+            );
+          }
+        });
+
+      }
+    });
+    */
+  }
+
+  public Semaphore getCompilationSemaphore() {
+    return myCompilationSemaphore;
+  }
+
+  public boolean isCompilationActive() {
+    return myCompilationSemaphore.availablePermits() == 0;
+  }
+
+  public void addTranslatingCompiler(@NotNull final TranslatingCompiler compiler, final Set<FileType> inputTypes, final Set<FileType> outputTypes) {
+    myTranslators.add(compiler);
+    myCompilerToInputTypes.put(compiler, inputTypes);
+    myCompilerToOutputTypes.put(compiler, outputTypes);
+
+    final List<Chunk<Compiler>> chunks = ModuleCompilerUtil.getSortedChunks(createCompilerGraph((List<Compiler>)(List)myTranslators));
+
+    myTranslators.clear();
+    for (Chunk<Compiler> chunk : chunks) {
+      for (Compiler chunkCompiler : chunk.getNodes()) {
+        myTranslators.add((TranslatingCompiler)chunkCompiler);
+      }
+    }
+  }
+
+  @NotNull
+  public Set<FileType> getRegisteredInputTypes(@NotNull final TranslatingCompiler compiler) {
+    final Set<FileType> inputs = myCompilerToInputTypes.get(compiler);
+    return inputs != null? Collections.unmodifiableSet(inputs) : Collections.<FileType>emptySet();
+  }
+
+  @NotNull
+  public Set<FileType> getRegisteredOutputTypes(@NotNull final TranslatingCompiler compiler) {
+    final Set<FileType> outs = myCompilerToOutputTypes.get(compiler);
+    return outs != null? Collections.unmodifiableSet(outs) : Collections.<FileType>emptySet();
+  }
+
+  public final void addCompiler(@NotNull Compiler compiler) {
+    if (compiler instanceof TranslatingCompiler) {
+      myTranslators.add((TranslatingCompiler)compiler);
+    }
+    else {
+      myCompilers.add(compiler);
+      // supporting file instrumenting compilers and validators for external build
+      // Since these compilers are IDE-specific and use PSI, it is ok to run them before and after the build in the IDE
+      if (compiler instanceof SourceInstrumentingCompiler) {
+        addBeforeTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
+      }
+      else if (compiler instanceof Validator) {
+        addAfterTask(new FileProcessingCompilerAdapterTask((FileProcessingCompiler)compiler));
+      }
+    }
+  }
+
+  public final void removeCompiler(@NotNull Compiler compiler) {
+    if (compiler instanceof TranslatingCompiler) {
+      myTranslators.remove(compiler);
+    }
+    else {
+      if (myCompilers.remove(compiler)) {
+        for (List<CompileTask> tasks : Arrays.asList(myBeforeTasks, myAfterTasks)) {
+          for (Iterator<CompileTask> iterator = tasks.iterator(); iterator.hasNext(); ) {
+            CompileTask task = iterator.next();
+            if (task instanceof FileProcessingCompilerAdapterTask && ((FileProcessingCompilerAdapterTask)task).getCompiler() == compiler) {
+              iterator.remove();
+            }
+          }
+        }
+      }
+    }
+    myCompilerToInputTypes.remove(compiler);
+    myCompilerToOutputTypes.remove(compiler);
+  }
+
+  @NotNull
+  public <T  extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass) {
+    return getCompilers(compilerClass, CompilerFilter.ALL);
+  }
+
+  @NotNull
+  public <T extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass, CompilerFilter filter) {
+    final List<T> compilers = new ArrayList<T>(myCompilers.size());
+    for (final Compiler item : myCompilers) {
+      if (compilerClass.isAssignableFrom(item.getClass()) && filter.acceptCompiler(item)) {
+        compilers.add((T)item);
+      }
+    }
+    for (final Compiler item : myTranslators) {
+      if (compilerClass.isAssignableFrom(item.getClass()) && filter.acceptCompiler(item)) {
+        compilers.add((T)item);
+      }
+    }
+    final T[] array = (T[])Array.newInstance(compilerClass, compilers.size());
+    return compilers.toArray(array);
+  }
+
+  public void addCompilableFileType(@NotNull FileType type) {
+    myCompilableTypes.add(type);
+  }
+
+  public void removeCompilableFileType(@NotNull FileType type) {
+    myCompilableTypes.remove(type);
+  }
+
+  public boolean isCompilableFileType(@NotNull FileType type) {
+    return myCompilableTypes.contains(type);
+  }
+
+  public final void addBeforeTask(@NotNull CompileTask task) {
+    myBeforeTasks.add(task);
+  }
+
+  public final void addAfterTask(@NotNull CompileTask task) {
+    myAfterTasks.add(task);
+  }
+
+  @NotNull
+  public CompileTask[] getBeforeTasks() {
+    return myBeforeTasks.toArray(new CompileTask[myBeforeTasks.size()]);
+  }
+
+  @NotNull
+  public CompileTask[] getAfterTasks() {
+    return myAfterTasks.toArray(new CompileTask[myAfterTasks.size()]);
+  }
+
+  public void compile(@NotNull VirtualFile[] files, CompileStatusNotification callback) {
+    compile(createFilesCompileScope(files), callback);
+  }
+
+  public void compile(@NotNull Module module, CompileStatusNotification callback) {
+    new CompileDriver(myProject).compile(createModuleCompileScope(module, false), new ListenerNotificator(callback), true);
+  }
+
+  public void compile(@NotNull CompileScope scope, CompileStatusNotification callback) {
+    new CompileDriver(myProject).compile(scope, new ListenerNotificator(callback), false);
+  }
+
+  public void make(CompileStatusNotification callback) {
+    new CompileDriver(myProject).make(createProjectCompileScope(myProject), new ListenerNotificator(callback));
+  }
+
+  public void make(@NotNull Module module, CompileStatusNotification callback) {
+    new CompileDriver(myProject).make(createModuleCompileScope(module, true), new ListenerNotificator(callback));
+  }
+
+  public void make(@NotNull Project project, @NotNull Module[] modules, CompileStatusNotification callback) {
+    new CompileDriver(myProject).make(createModuleGroupCompileScope(project, modules, true), new ListenerNotificator(callback));
+  }
+
+  public void make(@NotNull CompileScope scope, CompileStatusNotification callback) {
+    new CompileDriver(myProject).make(scope, new ListenerNotificator(callback));
+  }
+
+  public void make(@NotNull CompileScope scope, CompilerFilter filter, @Nullable CompileStatusNotification callback) {
+    final CompileDriver compileDriver = new CompileDriver(myProject);
+    compileDriver.setCompilerFilter(filter);
+    compileDriver.make(scope, new ListenerNotificator(callback));
+  }
+
+  public boolean isUpToDate(@NotNull final CompileScope scope) {
+    return new CompileDriver(myProject).isUpToDate(scope);
+  }
+
+  public void rebuild(CompileStatusNotification callback) {
+    new CompileDriver(myProject).rebuild(new ListenerNotificator(callback));
+  }
+
+  public void executeTask(@NotNull CompileTask task, @NotNull CompileScope scope, String contentName, Runnable onTaskFinished) {
+    final CompileDriver compileDriver = new CompileDriver(myProject);
+    compileDriver.executeCompileTask(task, scope, contentName, onTaskFinished);
+  }
+
+  private final Map<CompilationStatusListener, MessageBusConnection> myListenerAdapters = new HashMap<CompilationStatusListener, MessageBusConnection>();
+
+  public void addCompilationStatusListener(@NotNull final CompilationStatusListener listener) {
+    final MessageBusConnection connection = myProject.getMessageBus().connect();
+    myListenerAdapters.put(listener, connection);
+    connection.subscribe(CompilerTopics.COMPILATION_STATUS, listener);
+  }
+
+  @Override
+  public void addCompilationStatusListener(@NotNull CompilationStatusListener listener, @NotNull Disposable parentDisposable) {
+    final MessageBusConnection connection = myProject.getMessageBus().connect(parentDisposable);
+    connection.subscribe(CompilerTopics.COMPILATION_STATUS, listener);
+  }
+
+  public void removeCompilationStatusListener(@NotNull final CompilationStatusListener listener) {
+    final MessageBusConnection connection = myListenerAdapters.remove(listener);
+    if (connection != null) {
+      connection.disconnect();
+    }
+  }
+
+  // Compiler tests support
+
+  private static List<String> ourDeletedPaths;
+  private static List<String> ourRecompiledPaths;
+  private static List<String> ourCompiledPaths;
+
+  public static void testSetup() {
+    ourDeletedPaths = new ArrayList<String>();
+    ourRecompiledPaths = new ArrayList<String>();
+    ourCompiledPaths = new ArrayList<String>();
+  }
+
+  public static void addDeletedPath(String path) {
+    ourDeletedPaths.add(path);
+  }
+
+  public static void addRecompiledPath(String path) {
+    ourRecompiledPaths.add(path);
+  }
+
+  public static void addCompiledPath(String path) {
+    ourCompiledPaths.add(path);
+  }
+
+  public static String[] getPathsToDelete() {
+    return ArrayUtil.toStringArray(ourDeletedPaths);
+  }
+
+  public static String[] getPathsToRecompile() {
+    return ArrayUtil.toStringArray(ourRecompiledPaths);
+  }
+
+  public static String[] getPathsToCompile() {
+    return ArrayUtil.toStringArray(ourCompiledPaths);
+  }
+
+  public static void clearPathsToCompile() {
+    if (ourCompiledPaths != null) {
+      ourCompiledPaths.clear();
+    }
+  }
+
+  public boolean isExcludedFromCompilation(@NotNull VirtualFile file) {
+    return CompilerConfiguration.getInstance(myProject).isExcludedFromCompilation(file);
+  }
+
+  private static final OutputToSourceMapping OUTPUT_TO_SOURCE_MAPPING = new OutputToSourceMapping() {
+    public String getSourcePath(final String outputPath) {
+      final LocalFileSystem lfs = LocalFileSystem.getInstance();
+      final VirtualFile outputFile = lfs.findFileByPath(outputPath);
+
+      final VirtualFile sourceFile = outputFile != null ? TranslatingCompilerFilesMonitor.getSourceFileByOutput(outputFile) : null;
+      return sourceFile != null? sourceFile.getPath() : null;
+    }
+  };
+  @NotNull
+  public OutputToSourceMapping getJavaCompilerOutputMapping() {
+    return OUTPUT_TO_SOURCE_MAPPING;
+  }
+
+  @NotNull
+  public CompileScope createFilesCompileScope(@NotNull final VirtualFile[] files) {
+    CompileScope[] scopes = new CompileScope[files.length];
+    for(int i = 0; i < files.length; i++){
+      scopes[i] = new OneProjectItemCompileScope(myProject, files[i]);
+    }
+    return new CompositeScope(scopes);
+  }
+
+  @NotNull
+  public CompileScope createModuleCompileScope(@NotNull final Module module, final boolean includeDependentModules) {
+    return new ModuleCompileScope(module, includeDependentModules);
+  }
+
+  @NotNull
+  public CompileScope createModulesCompileScope(@NotNull final Module[] modules, final boolean includeDependentModules) {
+    return new ModuleCompileScope(myProject, modules, includeDependentModules);
+  }
+
+  @NotNull
+  public CompileScope createModuleGroupCompileScope(@NotNull final Project project, @NotNull final Module[] modules, final boolean includeDependentModules) {
+    return new ModuleCompileScope(project, modules, includeDependentModules);
+  }
+
+  @NotNull
+  public CompileScope createProjectCompileScope(@NotNull final Project project) {
+    return new ProjectCompileScope(project);
+  }
+
+  @Override
+  public void setValidationEnabled(ModuleType moduleType, boolean enabled) {
+    if (enabled) {
+      myValidationDisabledModuleTypes.remove(moduleType);
+    }
+    else {
+      myValidationDisabledModuleTypes.add(moduleType);
+    }
+  }
+
+  @Override
+  public boolean isValidationEnabled(Module module) {
+    if (myValidationDisabledModuleTypes.isEmpty()) {
+      return true; // optimization
+    }
+    return !myValidationDisabledModuleTypes.contains(ModuleType.get(module));
+  }
+
+  private Graph<Compiler> createCompilerGraph(final List<Compiler> compilers) {
+    return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Compiler>() {
+      public Collection<Compiler> getNodes() {
+        return compilers;
+      }
+
+      public Iterator<Compiler> getIn(Compiler compiler) {
+        final Set<FileType> compilerInput = myCompilerToInputTypes.get(compiler);
+        if (compilerInput == null || compilerInput.isEmpty()) {
+          return Collections.<Compiler>emptySet().iterator();
+        }
+
+        final Set<Compiler> inCompilers = new HashSet<Compiler>();
+
+        for (Map.Entry<Compiler, Set<FileType>> entry : myCompilerToOutputTypes.entrySet()) {
+          final Set<FileType> outputs = entry.getValue();
+          Compiler comp = entry.getKey();
+          if (outputs != null && ContainerUtil.intersects(compilerInput, outputs)) {
+            inCompilers.add(comp);
+          }
+        }
+        return inCompilers.iterator();
+      }
+    }));
+  }
+  
+  private class ListenerNotificator implements CompileStatusNotification {
+    private final @Nullable CompileStatusNotification myDelegate;
+
+    private ListenerNotificator(@Nullable CompileStatusNotification delegate) {
+      myDelegate = delegate;
+    }
+
+    public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
+      myEventPublisher.compilationFinished(aborted, errors, warnings, compileContext);
+      if (myDelegate != null) {
+        myDelegate.finished(aborted, errors, warnings, compileContext);
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java b/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java
new file mode 100644
index 0000000..bb15576
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/CompilerMessageImpl.java
@@ -0,0 +1,133 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessage;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.Nullable;
+
+public final class CompilerMessageImpl implements CompilerMessage {
+
+  private final Project myProject;
+  private final CompilerMessageCategory myCategory;
+  @Nullable private Navigatable myNavigatable;
+  private final String myMessage;
+  private VirtualFile myFile;
+  private final int myRow;
+  private final int myColumn;
+
+  public CompilerMessageImpl(Project project, CompilerMessageCategory category, String message) {
+    this(project, category, message, null, -1, -1, null);
+  }
+
+  public CompilerMessageImpl(Project project,
+                             CompilerMessageCategory category,
+                             String message,
+                             @Nullable final VirtualFile file,
+                             int row,
+                             int column,
+                             @Nullable final Navigatable navigatable) {
+    myProject = project;
+    myCategory = category;
+    myNavigatable = navigatable;
+    myMessage = message == null ? "" : message;
+    myRow = row;
+    myColumn = column;
+    myFile = file;
+  }
+
+  public CompilerMessageCategory getCategory() {
+    return myCategory;
+  }
+
+  public String getMessage() {
+    return myMessage;
+  }
+
+  public Navigatable getNavigatable() {
+    if (myNavigatable != null) {
+      return myNavigatable;
+    }
+    final VirtualFile virtualFile = getVirtualFile();
+    if (virtualFile != null && virtualFile.isValid()) {
+      final int line = getLine() - 1; // editor lines are zero-based
+      if (line >= 0) {
+        return myNavigatable = new OpenFileDescriptor(myProject, virtualFile, line, Math.max(0, getColumn()-1));
+      }
+    }
+    return null;
+  }
+
+  public VirtualFile getVirtualFile() {
+    return myFile;
+  }
+
+  public String getExportTextPrefix() {
+    if (getLine() >= 0) {
+      return CompilerBundle.message("compiler.results.export.text.prefix", getLine());
+    }
+    return "";
+  }
+
+  public String getRenderTextPrefix() {
+    if (getLine() >= 0) {
+      return "(" + getLine() + ", " + getColumn() + ")";
+    }
+    return "";
+  }
+
+  public int getLine() {
+    return myRow;
+  }
+
+  public int getColumn() {
+    return myColumn;
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof CompilerMessage)) return false;
+
+    final CompilerMessageImpl compilerMessage = (CompilerMessageImpl)o;
+
+    if (myColumn != compilerMessage.myColumn) return false;
+    if (myRow != compilerMessage.myRow) return false;
+    if (!myCategory.equals(compilerMessage.myCategory)) return false;
+    if (myFile != null ? !myFile.equals(compilerMessage.myFile) : compilerMessage.myFile != null) return false;
+    if (!myMessage.equals(compilerMessage.myMessage)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = myCategory.hashCode();
+    result = 29 * result + myMessage.hashCode();
+    result = 29 * result + (myFile != null ? myFile.hashCode() : 0);
+    result = 29 * result + myRow;
+    result = 29 * result + myColumn;
+    return result;
+  }
+
+  public String toString() {
+    return myMessage;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.java
new file mode 100644
index 0000000..3907eb8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/DependencyProcessor.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.compiler;
+
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.compiler.make.CachingSearcher;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Aug 19, 2008
+ */
+public interface DependencyProcessor {
+  ExtensionPointName<DependencyProcessor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.makeDependencyProcessor");
+  
+  void processDependencies(CompileContext context, int classQualifiedName, CachingSearcher searcher) throws CacheCorruptedException;
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/HelpID.java b/java/compiler/impl/src/com/intellij/compiler/HelpID.java
new file mode 100644
index 0000000..9b34a51
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/HelpID.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2011 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.compiler;
+
+import org.jetbrains.annotations.NonNls;
+
+public interface HelpID {
+  @NonNls  String  COMPILER = "reference.toolWindows.messages";
+  @NonNls  String  GENERATE_ANT_BUILD = "editing.generateAntBuild";
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/OutputParser.java b/java/compiler/impl/src/com/intellij/compiler/OutputParser.java
new file mode 100644
index 0000000..37f6882
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/OutputParser.java
@@ -0,0 +1,72 @@
+/*
+ * 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.compiler;
+
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public abstract class OutputParser {
+  protected final List<ParserAction> myParserActions = new ArrayList<ParserAction>(10);
+
+  public interface Callback {
+    @NonNls String getNextLine();        
+    @NonNls String getCurrentLine();
+    void pushBack(String line);
+    void setProgressText(String text);
+    void fileProcessed(@NonNls String path);
+    void fileGenerated(@NonNls FileObject path);
+    void message(CompilerMessageCategory category, String message, @NonNls String url, int lineNum, int columnNum);
+  }
+
+  public boolean processMessageLine(Callback callback) {
+    final String line = callback.getNextLine();
+    if(line == null) {
+      return false;
+    }
+    // common statistics messages (javac & jikes)
+    for (ParserAction action : myParserActions) {
+      if (action.execute(line, callback)) {
+        return true;
+      }
+    }
+    if (StringUtil.startsWithChar(line, '[') && StringUtil.endsWithChar(line, ']')) {
+      // at this point any meaningful output surrounded with '[' and ']' characters is processed, so
+      // suppress messages like "[total 4657ms]" or "[search path for source files: []]"
+      return true;
+    }
+    return false;
+  }
+
+  protected static void addMessage(Callback callback, CompilerMessageCategory type, String message) {
+    if(message == null || message.trim().length() == 0) {
+      return;
+    }
+    addMessage(callback, type, message, null, -1, -1);
+  }
+
+  protected static void addMessage(Callback callback, CompilerMessageCategory type, String text, String url, int line, int column){
+    callback.message(type, text, url, line, column);
+  }
+
+  public boolean isTrimLines() {
+    return true;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/ParserAction.java b/java/compiler/impl/src/com/intellij/compiler/ParserAction.java
new file mode 100644
index 0000000..d9b0c29
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ParserAction.java
@@ -0,0 +1,26 @@
+/*
+ * 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.compiler;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Sep 24, 2005
+ */
+public abstract class ParserAction {
+  public abstract boolean execute(@NonNls String line, final OutputParser.Callback callback);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ProblemsView.java b/java/compiler/impl/src/com/intellij/compiler/ProblemsView.java
new file mode 100644
index 0000000..3948ac7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ProblemsView.java
@@ -0,0 +1,93 @@
+/*
+ * 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.compiler;
+
+import com.intellij.compiler.progress.CompilerTask;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessage;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+import java.util.UUID;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 9/18/12
+ */
+public abstract class ProblemsView {
+
+  private final Project myProject;
+
+  public static class SERVICE {
+    private SERVICE() {
+    }
+
+    public static ProblemsView getInstance(Project project) {
+      return ServiceManager.getService(project, ProblemsView.class);
+    }
+  }
+
+  protected ProblemsView(Project project) {
+    myProject = project;
+  }
+
+  public abstract void clearOldMessages(CompileScope scope, UUID currentSessionId);
+
+  public abstract void addMessage(int type, @NotNull String[] text, @Nullable String groupName, @Nullable Navigatable navigatable, @Nullable String exportTextPrefix, @Nullable String rendererTextPrefix, @NotNull UUID sessionId);
+
+  public final void addMessage(CompilerMessage message, @NotNull UUID sessionId) {
+    final VirtualFile file = message.getVirtualFile();
+    Navigatable navigatable = message.getNavigatable();
+    if (navigatable == null && file != null) {
+      navigatable = new OpenFileDescriptor(myProject, file, -1, -1);
+    }
+    final CompilerMessageCategory category = message.getCategory();
+    final int type = CompilerTask.translateCategory(category);
+    final String[] text = convertMessage(message);
+    final String groupName = file != null? file.getPresentableUrl() : category.getPresentableText();
+    addMessage(type, text, groupName, navigatable, message.getExportTextPrefix(), message.getRenderTextPrefix(), sessionId);
+  }
+
+  public abstract void setProgress(String text, float fraction);
+  
+  public abstract void setProgress(String text);
+
+  public abstract void clearProgress();
+
+  private static String[] convertMessage(final CompilerMessage message) {
+    String text = message.getMessage();
+    if (!text.contains("\n")) {
+      return new String[]{text};
+    }
+    final List<String> lines = new ArrayList<String>();
+    StringTokenizer tokenizer = new StringTokenizer(text, "\n", false);
+    while (tokenizer.hasMoreTokens()) {
+      lines.add(tokenizer.nextToken());
+    }
+    return ArrayUtil.toStringArray(lines);
+  }
+  
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java b/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java
new file mode 100644
index 0000000..61d1e05
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/PsiClassWriter.java
@@ -0,0 +1,88 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.util.ClassUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.asm4.ClassWriter;
+
+/**
+ * @author yole
+ */
+public class PsiClassWriter extends ClassWriter {
+  private final Project myProject;
+
+  public PsiClassWriter(final Project project, boolean isJava6) {
+    super(isJava6 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS);
+    myProject = project;
+  }
+
+  public PsiClassWriter(final Module module) {
+    this(module.getProject(), isJdk6(module));
+  }
+
+  private static boolean isJdk6(final Module module) {
+    final Sdk projectJdk = ModuleRootManager.getInstance(module).getSdk();
+    if (projectJdk == null) return false;
+    return JavaSdk.getInstance().isOfVersionOrHigher(projectJdk, JavaSdkVersion.JDK_1_6);
+  }
+
+  protected String getCommonSuperClass(final String type1, final String type2) {
+    //PsiManager.getInstance(myProject).findClass(type1.replace('/', '.').replace('$', '.'), myProject.getAllScope());
+    return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      @NonNls
+      public String compute() {
+        final PsiManager manager = PsiManager.getInstance(myProject);
+        PsiClass c = ClassUtil.findPsiClassByJVMName(manager, type1);
+        if (c == null) {
+          return "java/lang/Object";
+        }
+        PsiClass d = ClassUtil.findPsiClassByJVMName(manager, type2);
+        if (d == null) {
+          return "java/lang/Object";
+        }
+        if (c.isInheritor(d, true)) {
+          return ClassUtil.getJVMClassName(d).replace('.', '/');
+        }
+        if (d.isInheritor(c, true)) {
+          return ClassUtil.getJVMClassName(c).replace('.', '/');
+        }
+        if (c.isInterface() || d.isInterface()) {
+          return "java/lang/Object";
+        }
+        do {
+          c = c.getSuperClass();
+        }
+        while (c != null && !d.isInheritor(c, true));
+        if (c == null) {
+          return "java/lang/Object";
+        }
+        return ClassUtil.getJVMClassName(c).replace('.', '/');
+      }
+    });
+  }
+
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/SymbolTable.java b/java/compiler/impl/src/com/intellij/compiler/SymbolTable.java
new file mode 100644
index 0000000..48603f5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/SymbolTable.java
@@ -0,0 +1,121 @@
+/*
+ * 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: Mar 3, 2003
+ * Time: 12:34:44 PM
+ */
+package com.intellij.compiler;
+
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.SLRUCache;
+import com.intellij.util.io.PersistentEnumerator;
+import com.intellij.util.io.PersistentStringEnumerator;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+
+public class SymbolTable {
+  private final PersistentStringEnumerator myTrie;
+
+  // both caches should have equal size
+  private static final int STRING_CACHE_SIZE = 1024;
+
+  private final SLRUCache<Integer, String> myIndexStringCache = new SLRUCache<Integer, String>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
+    @NotNull
+    public String createValue(Integer key) {
+      try {
+        return myTrie.valueOf(key.intValue());
+      }
+      catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  };
+  
+  private final SLRUCache<String, Integer> myStringIndexCache = new SLRUCache<String, Integer>(STRING_CACHE_SIZE * 2, STRING_CACHE_SIZE) {
+    @NotNull
+    public Integer createValue(String key) {
+      try {
+        return myTrie.enumerate(key);
+      }
+      catch (IOException e) {
+        throw new RuntimeException(e);
+      }
+    }
+  };
+
+
+  public SymbolTable(File file) throws CacheCorruptedException {
+    try {
+      if (!file.exists()) {
+        FileUtil.createIfDoesntExist(file);
+      }
+      myTrie = new PersistentStringEnumerator(file);
+    }
+    catch (PersistentEnumerator.CorruptedException e) {
+      throw new CacheCorruptedException(CompilerBundle.message("error.compiler.caches.corrupted"), e);
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public synchronized int getId(@NotNull String symbol) throws CacheCorruptedException {
+    if (symbol.length() == 0) {
+      return -1;
+    }
+    try {
+      return myStringIndexCache.get(symbol);
+    }
+    catch (RuntimeException e) {
+      if (e.getCause() instanceof IOException) {
+        throw new CacheCorruptedException(e.getCause());
+      }
+      throw e;
+    }
+  }
+
+  public synchronized String getSymbol(int id) throws CacheCorruptedException {
+    if (id == -1) {
+      return "";
+    }
+    try {
+      return myIndexStringCache.get(id);
+    }
+    catch (RuntimeException e) {
+      if (e.getCause() instanceof IOException) {
+        throw new CacheCorruptedException(e.getCause());
+      }
+      throw e;
+    }
+  }
+
+  public synchronized void dispose() throws CacheCorruptedException {
+    try {
+      myIndexStringCache.clear();
+      myStringIndexCache.clear();
+      myTrie.close(); // will call "flush()" if needed
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/AntBuildForm.form b/java/compiler/impl/src/com/intellij/compiler/actions/AntBuildForm.form
new file mode 100644
index 0000000..da94634
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/AntBuildForm.form
@@ -0,0 +1,113 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.actions.GenerateAntBuildDialog">
+  <grid id="3d49c" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="52" y="58" width="727" height="229"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="770dc" layout-manager="GridLayoutManager" row-count="3" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="7d65" class="javax.swing.JRadioButton" binding="myRbGenerateMultipleFilesBuild">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.generate.multiple.files"/>
+            </properties>
+          </component>
+          <component id="f1821" class="javax.swing.JRadioButton" binding="myRbGenerateSingleFileBuild">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.single.file"/>
+            </properties>
+          </component>
+          <component id="81381" class="javax.swing.JRadioButton" binding="myRbBackupFiles">
+            <constraints>
+              <grid row="0" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.backup.files"/>
+            </properties>
+          </component>
+          <component id="a019e" class="javax.swing.JRadioButton" binding="myRbOverwriteFiles">
+            <constraints>
+              <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.overwrite.files"/>
+            </properties>
+          </component>
+          <component id="cd13a" class="javax.swing.JTextField" binding="myOutputFileNameField">
+            <constraints>
+              <grid row="2" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+          <component id="3a774" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.filename"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <component id="ec5e9" class="javax.swing.JCheckBox" binding="myCbEnableUIFormsCompilation">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="9" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.enable.ui.forms.compilation"/>
+        </properties>
+      </component>
+      <xy id="6f3e8" binding="myChunksPanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </xy>
+      <component id="c9ba" class="javax.swing.JCheckBox" binding="myCbForceTargetJdk">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.use.jdk.definitions"/>
+        </properties>
+      </component>
+      <component id="ca33b" class="javax.swing.JCheckBox" binding="myCbInlineRuntimeClasspath">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.inline.runtime.classpaths"/>
+        </properties>
+      </component>
+      <component id="c612c" class="javax.swing.JCheckBox" binding="myGenerateIdeaHomeProperty" default-binding="true">
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="false"/>
+          <text resource-bundle="messages/CompilerBundle" key="label.generate.ant.script.generate.idea.home"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/ArtifactAwareProjectSettingsService.java b/java/compiler/impl/src/com/intellij/compiler/actions/ArtifactAwareProjectSettingsService.java
new file mode 100644
index 0000000..f84bc59
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/ArtifactAwareProjectSettingsService.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2011 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.compiler.actions;
+
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ArtifactAwareProjectSettingsService {
+  void openArtifactSettings(@Nullable Artifact artifact);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java
new file mode 100644
index 0000000..6f660d1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/BuildArtifactAction.java
@@ -0,0 +1,369 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.notification.NotificationGroup;
+import com.intellij.notification.NotificationType;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonShortcuts;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.keymap.KeymapUtil;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.ui.popup.ListSeparator;
+import com.intellij.openapi.ui.popup.MultiSelectionListPopupStep;
+import com.intellij.openapi.ui.popup.PopupStep;
+import com.intellij.openapi.ui.popup.util.BaseListPopupStep;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
+import com.intellij.packaging.impl.compiler.ArtifactsWorkspaceSettings;
+import com.intellij.ui.popup.list.ListPopupImpl;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.EmptyIcon;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class BuildArtifactAction extends DumbAwareAction {
+  private static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.balloonGroup("Clean artifact");
+
+  public BuildArtifactAction() {
+    super("Build Artifacts...", "Select and build artifacts configured in the project", null);
+  }
+  @Override
+  public void update(AnActionEvent e) {
+    final Project project = getEventProject(e);
+    final Presentation presentation = e.getPresentation();
+    presentation.setEnabled(project != null && !ArtifactUtil.getArtifactWithOutputPaths(project).isEmpty());
+  }
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    final Project project = getEventProject(e);
+    if (project == null) return;
+
+    final List<Artifact> artifacts = ArtifactUtil.getArtifactWithOutputPaths(project);
+    if (artifacts.isEmpty()) return;
+
+    List<ArtifactPopupItem> items = new ArrayList<ArtifactPopupItem>();
+    if (artifacts.size() > 1) {
+      items.add(0, new ArtifactPopupItem(null, "All Artifacts", EmptyIcon.ICON_16));
+    }
+    Set<Artifact> selectedArtifacts = new HashSet<Artifact>(ArtifactsWorkspaceSettings.getInstance(project).getArtifactsToBuild());
+    TIntArrayList selectedIndices = new TIntArrayList();
+    if (Comparing.haveEqualElements(artifacts, selectedArtifacts) && selectedArtifacts.size() > 1) {
+      selectedIndices.add(0);
+      selectedArtifacts.clear();
+    }
+    
+    for (Artifact artifact : artifacts) {
+      final ArtifactPopupItem item = new ArtifactPopupItem(artifact, artifact.getName(), artifact.getArtifactType().getIcon());
+      if (selectedArtifacts.contains(artifact)) {
+        selectedIndices.add(items.size());
+      }
+      items.add(item);
+    }
+    
+    final ProjectSettingsService projectSettingsService = ProjectSettingsService.getInstance(project);
+    final ArtifactAwareProjectSettingsService settingsService = projectSettingsService instanceof ArtifactAwareProjectSettingsService ? (ArtifactAwareProjectSettingsService)projectSettingsService : null;
+    
+    final ChooseArtifactStep step = new ChooseArtifactStep(items, artifacts.get(0), project, settingsService);
+    step.setDefaultOptionIndices(selectedIndices.toNativeArray());
+
+    final ListPopupImpl popup = (ListPopupImpl)JBPopupFactory.getInstance().createListPopup(step);
+    final KeyStroke editKeyStroke = KeymapUtil.getKeyStroke(CommonShortcuts.getEditSource());
+    if (settingsService != null && editKeyStroke != null) {
+      popup.registerAction("editArtifact", editKeyStroke, new AbstractAction() {
+        @Override
+        public void actionPerformed(ActionEvent e) {
+          Object[] values = popup.getSelectedValues();
+          popup.cancel();
+          settingsService.openArtifactSettings(values.length > 0 ? ((ArtifactPopupItem)values[0]).getArtifact() : null);
+        }
+      });
+    }
+    popup.showCenteredInCurrentWindow(project);
+  }
+
+  protected static void doBuild(@NotNull Project project, final @NotNull List<ArtifactPopupItem> items, boolean rebuild) {
+    final Set<Artifact> artifacts = getArtifacts(items, project);
+    final CompileScope scope = ArtifactCompileScope.createArtifactsScope(project, artifacts);
+
+    ArtifactsWorkspaceSettings.getInstance(project).setArtifactsToBuild(artifacts);
+    if (!rebuild) {
+      CompilerManager.getInstance(project).make(scope, null);
+    }
+    else {
+      CompilerManager.getInstance(project).compile(scope, null);
+    }
+  }
+
+  private static Set<Artifact> getArtifacts(final List<ArtifactPopupItem> items, final Project project) {
+    Set<Artifact> artifacts = new LinkedHashSet<Artifact>();
+    for (ArtifactPopupItem item : items) {
+      artifacts.addAll(item.getArtifacts(project));
+    }
+    return artifacts;
+  }
+
+  private static class BuildArtifactItem extends ArtifactActionItem {
+    private BuildArtifactItem(List<ArtifactPopupItem> item, Project project) {
+      super(item, project, "Build");
+    }
+
+    @Override
+    public void run() {
+      doBuild(myProject, myArtifactPopupItems, false);
+    }
+  }
+
+  private static class CleanArtifactItem extends ArtifactActionItem {
+    private CleanArtifactItem(@NotNull List<ArtifactPopupItem> item, @NotNull Project project) {
+      super(item, project, "Clean");
+    }
+
+    @Override
+    public void run() {
+      Set<VirtualFile> parents = new HashSet<VirtualFile>();
+      final VirtualFile[] roots = ProjectRootManager.getInstance(myProject).getContentSourceRoots();
+      for (VirtualFile root : roots) {
+        VirtualFile parent = root;
+        while (parent != null && !parents.contains(parent)) {
+          parents.add(parent);
+          parent = parent.getParent();
+        }
+      }
+
+      Map<String, String> outputPathContainingSourceRoots = new HashMap<String, String>();
+      final List<Pair<File, Artifact>> toClean = new ArrayList<Pair<File, Artifact>>();
+      Set<Artifact> artifacts = getArtifacts(myArtifactPopupItems, myProject);
+      for (Artifact artifact : artifacts) {
+        String outputPath = artifact.getOutputFilePath();
+        if (outputPath != null) {
+          toClean.add(Pair.create(new File(FileUtil.toSystemDependentName(outputPath)), artifact));
+          final VirtualFile outputFile = LocalFileSystem.getInstance().findFileByPath(outputPath);
+          if (parents.contains(outputFile)) {
+            outputPathContainingSourceRoots.put(artifact.getName(), outputPath);
+          }
+        }
+      }
+
+      if (!outputPathContainingSourceRoots.isEmpty()) {
+        final String message;
+        if (outputPathContainingSourceRoots.size() == 1 && outputPathContainingSourceRoots.values().size() == 1) {
+          final String name = ContainerUtil.getFirstItem(outputPathContainingSourceRoots.keySet());
+          final String output = outputPathContainingSourceRoots.get(name);
+          message = "The output directory '" + output + "' of '" + name + "' artifact contains source roots of the project. Do you want to continue and clear it?";
+        }
+        else {
+          StringBuilder info = new StringBuilder();
+          for (String name : outputPathContainingSourceRoots.keySet()) {
+            info.append(" '").append(name).append("' artifact ('").append(outputPathContainingSourceRoots.get(name)).append("')\n");
+          }
+          message = "The output directories of the following artifacts contains source roots:\n" +
+                    info + "Do you want to continue and clear these directories?";
+        }
+        final int answer = Messages.showYesNoDialog(myProject, message, "Clean Artifacts", null);
+        if (answer != 0) {
+          return;
+        }
+      }
+
+      new Task.Backgroundable(myProject, "Cleaning artifacts...", true) {
+        @Override
+        public void run(@NotNull ProgressIndicator indicator) {
+          List<File> deleted = new ArrayList<File>();
+          for (Pair<File, Artifact> pair : toClean) {
+            indicator.checkCanceled();
+            File file = pair.getFirst();
+            if (!FileUtil.delete(file)) {
+              NOTIFICATION_GROUP.createNotification("Cannot clean '" + pair.getSecond().getName() + "' artifact", "cannot delete '" + file.getAbsolutePath() + "'", NotificationType.ERROR, null).notify(myProject);
+            }
+            else {
+              deleted.add(file);
+            }
+          }
+          LocalFileSystem.getInstance().refreshIoFiles(deleted, true, true, null);
+        }
+      }.queue();
+    }
+  }
+
+  private static class RebuildArtifactItem extends ArtifactActionItem {
+    private RebuildArtifactItem(List<ArtifactPopupItem> item, Project project) {
+      super(item, project, "Rebuild");
+    }
+
+    @Override
+    public void run() {
+      doBuild(myProject, myArtifactPopupItems, true);
+    }
+  }
+
+  private static class EditArtifactItem extends ArtifactActionItem {
+    private final ArtifactAwareProjectSettingsService mySettingsService;
+
+    private EditArtifactItem(List<ArtifactPopupItem> item, Project project, final ArtifactAwareProjectSettingsService projectSettingsService) {
+      super(item, project, "Edit...");
+      mySettingsService = projectSettingsService;
+    }
+
+    @Override
+    public void run() {
+      mySettingsService.openArtifactSettings(myArtifactPopupItems.get(0).getArtifact());
+    }
+  }
+
+  private static abstract class ArtifactActionItem implements Runnable {
+    protected final List<ArtifactPopupItem> myArtifactPopupItems;
+    protected final Project myProject;
+    private String myActionName;
+
+    protected ArtifactActionItem(@NotNull List<ArtifactPopupItem> item, @NotNull Project project, @NotNull String name) {
+      myArtifactPopupItems = item;
+      myProject = project;
+      myActionName = name;
+    }
+
+    public String getActionName() {
+      return myActionName;
+    }
+  }
+
+  private static class ArtifactPopupItem {
+    @Nullable private final Artifact myArtifact;
+    private final String myText;
+    private final Icon myIcon;
+
+    private ArtifactPopupItem(@Nullable Artifact artifact, String text, Icon icon) {
+      myArtifact = artifact;
+      myText = text;
+      myIcon = icon;
+    }
+
+    @Nullable
+    public Artifact getArtifact() {
+      return myArtifact;
+    }
+
+    public String getText() {
+      return myText;
+    }
+
+    public Icon getIcon() {
+      return myIcon;
+    }
+
+    public List<Artifact> getArtifacts(Project project) {
+      final Artifact artifact = getArtifact();
+      return artifact != null ? Collections.singletonList(artifact) : ArtifactUtil.getArtifactWithOutputPaths(project);
+    }
+  }
+  
+  private static class ChooseArtifactStep extends MultiSelectionListPopupStep<ArtifactPopupItem> {
+    private final Artifact myFirst;
+    private final Project myProject;
+    private ArtifactAwareProjectSettingsService mySettingsService;
+
+    public ChooseArtifactStep(List<ArtifactPopupItem> artifacts,
+                              Artifact first,
+                              Project project, final ArtifactAwareProjectSettingsService settingsService) {
+      super("Build Artifact", artifacts);
+      myFirst = first;
+      myProject = project;
+      mySettingsService = settingsService;
+    }
+
+    @Override
+    public boolean isSpeedSearchEnabled() {
+      return true;
+    }
+
+    @Override
+    public Icon getIconFor(ArtifactPopupItem aValue) {
+      return aValue.getIcon();
+    }
+
+    @NotNull
+    @Override
+    public String getTextFor(ArtifactPopupItem value) {
+      return value.getText();
+    }
+
+    @Override
+    public boolean hasSubstep(List<ArtifactPopupItem> selectedValues) {
+      return true;
+    }
+
+    @Override
+    public ListSeparator getSeparatorAbove(ArtifactPopupItem value) {
+      return myFirst.equals(value.getArtifact()) ? new ListSeparator() : null;
+    }
+
+    @Override
+    public PopupStep<?> onChosen(final List<ArtifactPopupItem> selectedValues, boolean finalChoice) {
+      if (finalChoice) {
+        return doFinalStep(new Runnable() {
+          @Override
+          public void run() {
+            doBuild(myProject, selectedValues, false);
+          }
+        });
+      }
+      final List<ArtifactActionItem> actions = new ArrayList<ArtifactActionItem>();
+      actions.add(new BuildArtifactItem(selectedValues, myProject));
+      actions.add(new RebuildArtifactItem(selectedValues, myProject));
+      actions.add(new CleanArtifactItem(selectedValues, myProject));
+      if (mySettingsService != null) {
+        actions.add(new EditArtifactItem(selectedValues, myProject, mySettingsService));
+      }
+      return new BaseListPopupStep<ArtifactActionItem>(selectedValues.size() == 1 ? "Action" : "Action for " + selectedValues.size() + " artifacts", actions) {
+        @NotNull
+        @Override
+        public String getTextFor(ArtifactActionItem value) {
+          return value.getActionName();
+        }
+
+        @Override
+        public PopupStep onChosen(ArtifactActionItem selectedValue, boolean finalChoice) {
+          return doFinalStep(selectedValue);
+        }
+      };
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileAction.java
new file mode 100644
index 0000000..2fe4bcd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileAction.java
@@ -0,0 +1,196 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.idea.ActionsBundle;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.artifacts.ArtifactBySourceFileFinder;
+import com.intellij.psi.*;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class CompileAction extends CompileActionBase {
+  protected void doAction(DataContext dataContext, Project project) {
+    final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
+    if (module != null) {
+      CompilerManager.getInstance(project).compile(module, null);
+    }
+    else {
+      VirtualFile[] files = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
+      if (files.length > 0) {
+        CompilerManager.getInstance(project).compile(files, null);
+      }
+    }
+
+  }
+
+  public void update(AnActionEvent event) {
+    super.update(event);
+    Presentation presentation = event.getPresentation();
+    if (!presentation.isEnabled()) {
+      return;
+    }
+    DataContext dataContext = event.getDataContext();
+
+    presentation.setText(ActionsBundle.actionText(IdeActions.ACTION_COMPILE));
+    presentation.setVisible(true);
+
+    Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+    if (project == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
+    final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
+
+    final VirtualFile[] files = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
+    if (module == null && files.length == 0) {
+      presentation.setEnabled(false);
+      presentation.setVisible(!ActionPlaces.isPopupPlace(event.getPlace()));
+      return;
+    }
+
+    String elementDescription = null;
+    if (module != null) {
+      elementDescription = CompilerBundle.message("action.compile.description.module", module.getName());
+    }
+    else {
+      PsiPackage aPackage = null;
+      if (files.length == 1) {
+        final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(files[0]);
+        if (directory != null) {
+          aPackage = JavaDirectoryService.getInstance().getPackage(directory);
+        }
+      }
+      else {
+        PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
+        if (element instanceof PsiPackage) {
+          aPackage = (PsiPackage)element;
+        }
+      }
+
+      if (aPackage != null) {
+        String name = aPackage.getQualifiedName();
+        if (name.length() == 0) {
+          //noinspection HardCodedStringLiteral
+          name = "<default>";
+        }
+        elementDescription = "'" + name + "'";
+      }
+      else if (files.length == 1) {
+        final VirtualFile file = files[0];
+        FileType fileType = file.getFileType();
+        if (CompilerManager.getInstance(project).isCompilableFileType(fileType) || isCompilableResourceFile(project, compilerConfiguration, file)) {
+          elementDescription = "'" + file.getName() + "'";
+        }
+        else {
+          if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) {
+            // the action should be invisible in popups for non-java files
+            presentation.setEnabled(false);
+            presentation.setVisible(false);
+            return;
+          }
+        }
+      }
+      else {
+        elementDescription = CompilerBundle.message("action.compile.description.selected.files");
+      }
+    }
+
+    if (elementDescription == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    presentation.setText(createPresentationText(elementDescription), true);
+    presentation.setEnabled(true);
+  }
+
+  private static String createPresentationText(String elementDescription) {
+    StringBuffer buffer = new StringBuffer(40);
+    buffer.append(ActionsBundle.actionText(IdeActions.ACTION_COMPILE)).append(" ");
+    int length = elementDescription.length();
+    if (length > 23) {
+      if (StringUtil.startsWithChar(elementDescription, '\'')) {
+        buffer.append("'");
+      }
+      buffer.append("...");
+      buffer.append(elementDescription.substring(length - 20, length));
+    }
+    else {
+      buffer.append(elementDescription);
+    }
+    return buffer.toString();
+  }
+
+  private static VirtualFile[] getCompilableFiles(Project project, VirtualFile[] files) {
+    if (files == null || files.length == 0) {
+      return VirtualFile.EMPTY_ARRAY;
+    }
+    final PsiManager psiManager = PsiManager.getInstance(project);
+    final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
+    final FileTypeManager typeManager = FileTypeManager.getInstance();
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    final CompilerManager compilerManager = CompilerManager.getInstance(project);
+    final List<VirtualFile> filesToCompile = new ArrayList<VirtualFile>();
+    for (final VirtualFile file : files) {
+      if (!fileIndex.isInSourceContent(file)) {
+        continue;
+      }
+      if (!file.isInLocalFileSystem()) {
+        continue;
+      }
+      if (file.isDirectory()) {
+        final PsiDirectory directory = psiManager.findDirectory(file);
+        if (directory == null || JavaDirectoryService.getInstance().getPackage(directory) == null) {
+          continue;
+        }
+      }
+      else {
+        FileType fileType = file.getFileType();
+        if (!(compilerManager.isCompilableFileType(fileType) || isCompilableResourceFile(project, compilerConfiguration, file))) {
+          continue;
+        }
+      }
+      filesToCompile.add(file);
+    }
+    return VfsUtil.toVirtualFileArray(filesToCompile);
+  }
+
+  private static boolean isCompilableResourceFile(final Project project, final CompilerConfiguration compilerConfiguration, final VirtualFile file) {
+    if (!compilerConfiguration.isResourceFile(file)) {
+      return false;
+    }
+    final Collection<? extends Artifact> artifacts = ArtifactBySourceFileFinder.getInstance(project).findArtifacts(file);
+    return artifacts.isEmpty();
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java
new file mode 100644
index 0000000..905dd92
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileActionBase.java
@@ -0,0 +1,54 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.psi.PsiFile;
+
+public abstract class CompileActionBase extends AnAction implements DumbAware {
+  public void actionPerformed(AnActionEvent e) {
+    final DataContext dataContext = e.getDataContext();
+    final Project project = e.getData(PlatformDataKeys.PROJECT);
+    if (project == null) {
+      return;
+    }
+    Editor editor = e.getData(PlatformDataKeys.EDITOR);
+    PsiFile file = e.getData(LangDataKeys.PSI_FILE);
+    if (file != null && editor != null && !DumbService.getInstance(project).isDumb()) {
+      DaemonCodeAnalyzer.getInstance(project).autoImportReferenceAtCursor(editor, file); //let autoimport complete
+    }
+    doAction(dataContext, project);
+  }
+
+  protected abstract void doAction(final DataContext dataContext, final Project project);
+
+  public void update(final AnActionEvent e) {
+    super.update(e);
+    final Project project = e.getData(PlatformDataKeys.PROJECT);
+    if (project == null) {
+      e.getPresentation().setEnabled(false);
+    }
+    else {
+      e.getPresentation().setEnabled(!CompilerManager.getInstance(project).isCompilationActive());
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java
new file mode 100644
index 0000000..8bea288
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileDirtyAction.java
@@ -0,0 +1,39 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.project.Project;
+
+public class CompileDirtyAction extends CompileActionBase {
+
+  protected void doAction(DataContext dataContext, Project project) {
+    CompilerManager.getInstance(project).make(null);
+  }
+
+  public void update(AnActionEvent event){
+    super.update(event);
+    Presentation presentation = event.getPresentation();
+    if (!presentation.isEnabled()) {
+      return;
+    }
+    presentation.setEnabled(PlatformDataKeys.PROJECT.getData(event.getDataContext()) != null);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.java
new file mode 100644
index 0000000..fde4f55
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/CompileProjectAction.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.compiler.actions;
+
+import com.intellij.history.LocalHistory;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.project.Project;
+
+public class CompileProjectAction extends CompileActionBase {
+  protected void doAction(DataContext dataContext, final Project project) {
+    CompilerManager.getInstance(project).rebuild(new CompileStatusNotification() {
+      public void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
+        if (aborted) return;
+
+        String text = getTemplatePresentation().getText();
+        LocalHistory.getInstance().putSystemLabel(project, errors == 0
+                                       ? CompilerBundle.message("rebuild.lvcs.label.no.errors", text)
+                                       : CompilerBundle.message("rebuild.lvcs.label.with.errors", text));
+      }
+    });
+  }
+
+  public void update(AnActionEvent event) {
+    super.update(event);
+    Presentation presentation = event.getPresentation();
+    if (!presentation.isEnabled()) {
+      return;
+    }
+    Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext());
+    presentation.setEnabled(project != null);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildAction.java
new file mode 100644
index 0000000..8af49a5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildAction.java
@@ -0,0 +1,359 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.ant.*;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.ReadonlyStatusHandler;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+import java.util.*;
+
+public class GenerateAntBuildAction extends CompileActionBase {
+  @NonNls private static final String XML_EXTENSION = ".xml";
+
+  protected void doAction(DataContext dataContext, final Project project) {
+    ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).convertPatterns();
+    final GenerateAntBuildDialog dialog = new GenerateAntBuildDialog(project);
+    dialog.show();
+    if (dialog.isOK()) {
+      final String[] names = dialog.getRepresentativeModuleNames();
+      final GenerationOptionsImpl[] genOptions = {null};
+      Runnable runnable = new Runnable() {
+        public void run() {
+          genOptions[0] = new GenerationOptionsImpl(project, dialog.isGenerateSingleFileBuild(), dialog.isFormsCompilationEnabled(),
+                                                    dialog.isBackupFiles(), dialog.isForceTargetJdk(), dialog.isRuntimeClasspathInlined(),
+                                                    dialog.isIdeaHomeGenerated(), names, dialog.getOutputFileName());
+        }
+      };
+      if (!ProgressManager.getInstance().runProcessWithProgressSynchronously(runnable, "Analyzing project structure...", true, project)) {
+        return;
+      }
+      if (!validateGenOptions(project, genOptions[0])) {
+        return;
+      }
+      generate(project, genOptions[0]);
+    }
+  }
+
+  /**
+   * Validate generation options and notify user about possible problems
+   *
+   * @param project    a context project
+   * @param genOptions a generation optiosn
+   * @return true if the generator should proceed with current options or if there is not conflict.
+   */
+  private static boolean validateGenOptions(Project project, GenerationOptionsImpl genOptions) {
+    final Collection<String> EMPTY = Collections.emptyList();
+    Collection<String> conflicts = EMPTY;
+    for (ModuleChunk chunk : genOptions.getModuleChunks()) {
+      final ChunkCustomCompilerExtension[] customeCompilers = chunk.getCustomCompilers();
+      if (customeCompilers.length > 1) {
+        if (conflicts == EMPTY) {
+          conflicts = new LinkedList<String>();
+        }
+        conflicts.add(chunk.getName());
+      }
+    }
+    if (!conflicts.isEmpty()) {
+      StringBuilder msg = new StringBuilder();
+      for (String conflictingChunk : conflicts) {
+        msg.append(CompilerBundle.message("generate.ant.build.custom.compiler.conflict.message.row", conflictingChunk));
+      }
+      int rc = Messages
+        .showOkCancelDialog(project, CompilerBundle.message("generate.ant.build.custom.compiler.conflict.message", msg.toString()),
+                            CompilerBundle.message("generate.ant.build.custom.compiler.conflict.title"), Messages.getErrorIcon());
+      if (rc != 0) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void update(AnActionEvent event) {
+    Presentation presentation = event.getPresentation();
+    Project project = PlatformDataKeys.PROJECT.getData(event.getDataContext());
+    presentation.setEnabled(project != null);
+  }
+
+  private void generate(final Project project, final GenerationOptions genOptions) {
+    ApplicationManager.getApplication().saveAll();
+    final List<File> filesToRefresh = new ArrayList<File>();
+    final IOException[] _ex = new IOException[]{null};
+    final List<File> _generated = new ArrayList<File>();
+
+    try {
+      if (genOptions.generateSingleFile) {
+        final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
+        final File destFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
+        final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
+
+        ensureFilesWritable(project, new File[]{destFile, propertiesFile});
+      }
+      else {
+        final List<File> allFiles = new ArrayList<File>();
+
+        final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
+        allFiles.add(new File(projectBuildFileDestDir, genOptions.getBuildFileName()));
+        allFiles.add(new File(projectBuildFileDestDir, genOptions.getPropertiesFileName()));
+
+        final ModuleChunk[] chunks = genOptions.getModuleChunks();
+        for (final ModuleChunk chunk : chunks) {
+          final File chunkBaseDir = BuildProperties.getModuleChunkBaseDir(chunk);
+          allFiles.add(new File(chunkBaseDir, BuildProperties.getModuleChunkBuildFileName(chunk) + XML_EXTENSION));
+        }
+
+        ensureFilesWritable(project, allFiles.toArray(new File[allFiles.size()]));
+      }
+
+      new Task.Modal(project, CompilerBundle.message("generate.ant.build.title"), false) {
+        public void run(@NotNull final ProgressIndicator indicator) {
+          indicator.setIndeterminate(true);
+          indicator.setText(CompilerBundle.message("generate.ant.build.progress.message"));
+          try {
+            final File[] generated;
+            if (genOptions.generateSingleFile) {
+              generated = generateSingleFileBuild(project, genOptions, filesToRefresh);
+            }
+            else {
+              generated = generateMultipleFileBuild(project, genOptions, filesToRefresh);
+            }
+            if (generated != null) {
+              ContainerUtil.addAll(_generated, generated);
+            }
+          }
+          catch (IOException e) {
+            _ex[0] = e;
+          }
+        }
+      }.queue();
+
+    }
+    catch (IOException e) {
+      _ex[0] = e;
+    }
+
+    if (_ex[0] != null) {
+      Messages.showErrorDialog(project, CompilerBundle.message("error.ant.files.generate.failed", _ex[0].getMessage()),
+                               CompilerBundle.message("generate.ant.build.title"));
+    }
+    else {
+      StringBuffer filesString = new StringBuffer();
+      for (int idx = 0; idx < _generated.size(); idx++) {
+        final File file = _generated.get(idx);
+        if (idx > 0) {
+          filesString.append(",\n");
+        }
+        filesString.append(file.getPath());
+      }
+      Messages.showInfoMessage(project, CompilerBundle.message("message.ant.files.generated.ok", filesString.toString()),
+                               CompilerBundle.message("generate.ant.build.title"));
+    }
+
+    if (filesToRefresh.size() > 0) {
+      CompilerUtil.refreshIOFiles(filesToRefresh);
+    }
+  }
+
+  private boolean backup(final File file, final Project project, GenerationOptions genOptions, List<File> filesToRefresh) {
+    if (!genOptions.backupPreviouslyGeneratedFiles || !file.exists()) {
+      return true;
+    }
+    final String path = file.getPath();
+    final int extensionIndex = path.lastIndexOf(".");
+    final String extension = path.substring(extensionIndex, path.length());
+    //noinspection HardCodedStringLiteral
+    final String backupPath = path.substring(0, extensionIndex) +
+                              "_" +
+                              new Date(file.lastModified()).toString().replaceAll("\\s+", "_").replaceAll(":", "-") +
+                              extension;
+    final File backupFile = new File(backupPath);
+    boolean ok;
+    try {
+      FileUtil.rename(file, backupFile);
+      ok = true;
+    }
+    catch (IOException e) {
+      Messages.showErrorDialog(project, CompilerBundle.message("error.ant.files.backup.failed", path),
+                               CompilerBundle.message("generate.ant.build.title"));
+      ok = false;
+    }
+    filesToRefresh.add(backupFile);
+    return ok;
+  }
+
+  private File[] generateSingleFileBuild(Project project, GenerationOptions genOptions, List<File> filesToRefresh) throws IOException {
+    final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
+    projectBuildFileDestDir.mkdirs();
+    final File destFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
+    final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
+
+    if (!backup(destFile, project, genOptions, filesToRefresh)) {
+      return null;
+    }
+    if (!backup(propertiesFile, project, genOptions, filesToRefresh)) {
+      return null;
+    }
+
+    generateSingleFileBuild(project, genOptions, destFile, propertiesFile);
+
+    filesToRefresh.add(destFile);
+    filesToRefresh.add(propertiesFile);
+    return new File[]{destFile, propertiesFile};
+  }
+
+  public static void generateSingleFileBuild(final Project project,
+                                             final GenerationOptions genOptions,
+                                             final File buildxmlFile,
+                                             final File propertiesFile) throws IOException {
+    FileUtil.createIfDoesntExist(buildxmlFile);
+    FileUtil.createIfDoesntExist(propertiesFile);
+    final PrintWriter dataOutput = makeWriter(buildxmlFile);
+    try {
+      new SingleFileProjectBuild(project, genOptions).generate(dataOutput);
+    }
+    finally {
+      dataOutput.close();
+    }
+    final PrintWriter propertiesOut = makeWriter(propertiesFile);
+    try {
+      new PropertyFileGeneratorImpl(project, genOptions).generate(propertiesOut);
+    }
+    finally {
+      propertiesOut.close();
+    }
+  }
+
+  /**
+   * Create print writer over file with UTF-8 encoding
+   *
+   * @param buildxmlFile a file to write to
+   * @return a created print writer
+   * @throws UnsupportedEncodingException if endcoding not found
+   * @throws FileNotFoundException        if file not found
+   */
+  private static PrintWriter makeWriter(final File buildxmlFile) throws UnsupportedEncodingException, FileNotFoundException {
+    return new PrintWriter(new OutputStreamWriter(new FileOutputStream(buildxmlFile), "UTF-8"));
+  }
+
+  private void ensureFilesWritable(Project project, File[] files) throws IOException {
+    final List<VirtualFile> toCheck = new ArrayList<VirtualFile>(files.length);
+    final LocalFileSystem lfs = LocalFileSystem.getInstance();
+    for (File file : files) {
+      final VirtualFile vFile = lfs.findFileByIoFile(file);
+      if (vFile != null) {
+        toCheck.add(vFile);
+      }
+    }
+    final ReadonlyStatusHandler.OperationStatus status =
+      ReadonlyStatusHandler.getInstance(project).ensureFilesWritable(VfsUtil.toVirtualFileArray(toCheck));
+    if (status.hasReadonlyFiles()) {
+      throw new IOException(status.getReadonlyFilesMessage());
+    }
+  }
+
+  public File[] generateMultipleFileBuild(Project project, GenerationOptions genOptions, List<File> filesToRefresh) throws IOException {
+    final File projectBuildFileDestDir = VfsUtil.virtualToIoFile(project.getBaseDir());
+    projectBuildFileDestDir.mkdirs();
+    final List<File> generated = new ArrayList<File>();
+    final File projectBuildFile = new File(projectBuildFileDestDir, genOptions.getBuildFileName());
+    final File propertiesFile = new File(projectBuildFileDestDir, genOptions.getPropertiesFileName());
+    final ModuleChunk[] chunks = genOptions.getModuleChunks();
+
+    final File[] chunkFiles = new File[chunks.length];
+    for (int idx = 0; idx < chunks.length; idx++) {
+      final ModuleChunk chunk = chunks[idx];
+      final File chunkBaseDir = BuildProperties.getModuleChunkBaseDir(chunk);
+      chunkFiles[idx] = new File(chunkBaseDir, BuildProperties.getModuleChunkBuildFileName(chunk) + XML_EXTENSION);
+    }
+
+    if (!backup(projectBuildFile, project, genOptions, filesToRefresh)) {
+      return null;
+    }
+    if (!backup(propertiesFile, project, genOptions, filesToRefresh)) {
+      return null;
+    }
+
+    FileUtil.createIfDoesntExist(projectBuildFile);
+    final PrintWriter mainDataOutput = makeWriter(projectBuildFile);
+    try {
+      final MultipleFileProjectBuild build = new MultipleFileProjectBuild(project, genOptions);
+      build.generate(mainDataOutput);
+      generated.add(projectBuildFile);
+
+      // the sequence in which modules are imported is important cause output path properties for dependent modules should be defined first
+
+      for (int idx = 0; idx < chunks.length; idx++) {
+        final ModuleChunk chunk = chunks[idx];
+        final File chunkBuildFile = chunkFiles[idx];
+        final File chunkBaseDir = chunkBuildFile.getParentFile();
+        if (chunkBaseDir != null) {
+          chunkBaseDir.mkdirs();
+        }
+        final boolean moduleBackupOk = backup(chunkBuildFile, project, genOptions, filesToRefresh);
+        if (!moduleBackupOk) {
+          return null;
+        }
+
+        FileUtil.createIfDoesntExist(chunkBuildFile);
+        final PrintWriter out = makeWriter(chunkBuildFile);
+        try {
+          new ModuleChunkAntProject(project, chunk, genOptions).generate(out);
+          generated.add(chunkBuildFile);
+        }
+        finally {
+          out.close();
+        }
+      }
+    }
+    finally {
+      mainDataOutput.close();
+    }
+    // properties
+    final PrintWriter propertiesOut = makeWriter(propertiesFile);
+    try {
+      new PropertyFileGeneratorImpl(project, genOptions).generate(propertiesOut);
+      generated.add(propertiesFile);
+    }
+    finally {
+      propertiesOut.close();
+    }
+
+    filesToRefresh.addAll(generated);
+    return generated.toArray(new File[generated.size()]);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildDialog.java b/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildDialog.java
new file mode 100644
index 0000000..1cd1c39
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/GenerateAntBuildDialog.java
@@ -0,0 +1,360 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.compiler.HelpID;
+import com.intellij.compiler.ModuleCompilerUtil;
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.help.HelpManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.MultiLineLabelUI;
+import com.intellij.openapi.util.Pair;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Chunk;
+import com.intellij.util.ListWithSelection;
+import com.intellij.util.ui.ComboBoxTableCellEditor;
+import com.intellij.util.ui.Table;
+import org.jetbrains.annotations.NonNls;
+
+import javax.swing.*;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableColumn;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.Iterator;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 29, 2004
+ */
+public class GenerateAntBuildDialog extends DialogWrapper {
+  private JPanel myPanel;
+  private JRadioButton myRbGenerateSingleFileBuild;
+  private JRadioButton myRbGenerateMultipleFilesBuild;
+  private JCheckBox myCbEnableUIFormsCompilation;
+  private JRadioButton myRbBackupFiles;
+  private JRadioButton myRbOverwriteFiles;
+  private JCheckBox myCbForceTargetJdk;
+  private JCheckBox myCbInlineRuntimeClasspath;
+  private JPanel myChunksPanel;
+  private JCheckBox myGenerateIdeaHomeProperty;
+  private JTextField myOutputFileNameField;
+  private final Project myProject;
+  @NonNls private static final String SINGLE_FILE_PROPERTY = "GenerateAntBuildDialog.generateSingleFile";
+  @NonNls private static final String UI_FORM_PROPERTY = "GenerateAntBuildDialog.enableUiFormCompile";
+  @NonNls private static final String FORCE_TARGET_JDK_PROPERTY = "GenerateAntBuildDialog.forceTargetJdk";
+  @NonNls private static final String BACKUP_FILES_PROPERTY = "GenerateAntBuildDialog.backupFiles";
+  @NonNls private static final String INLINE_RUNTIME_CLASSPATH_PROPERTY = "GenerateAntBuildDialog.inclineRuntiemClasspath";
+  @NonNls private static final String GENERATE_IDEA_HOME_PROPERTY = "GenerateAntBuildDialog.generateIdeaHomeProperty";
+  @NonNls private static final String OUTPUT_FILE_NAME_PROPERTY = "GenerateAntBuildDialog.outputFileNameProperty";
+  private MyTableModel myTableModel;
+  private Table myTable;
+
+  public GenerateAntBuildDialog(Project project) {
+    super(project, false);
+    myProject = project;
+    setTitle(CompilerBundle.message("generate.ant.build.title"));
+    init();
+    loadSettings();
+  }
+
+  private List<Chunk<Module>> getCycleChunks() {
+    List<Chunk<Module>> chunks =
+      ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
+    for (Iterator<Chunk<Module>> it = chunks.iterator(); it.hasNext();) {
+      final Chunk<Module> chunk = it.next();
+      if (chunk.getNodes().size() == 1) {
+        it.remove();
+      }
+    }
+    return chunks;
+  }
+
+  private void loadSettings() {
+    final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
+    if (properties.isValueSet(SINGLE_FILE_PROPERTY)) {
+      final boolean singleFile = properties.isTrueValue(SINGLE_FILE_PROPERTY);
+      myRbGenerateSingleFileBuild.setSelected(singleFile);
+      myRbGenerateMultipleFilesBuild.setSelected(!singleFile);
+    }
+    if (properties.isValueSet(UI_FORM_PROPERTY)) {
+      myCbEnableUIFormsCompilation.setSelected(properties.isTrueValue(UI_FORM_PROPERTY));
+    }
+    if (properties.isValueSet(FORCE_TARGET_JDK_PROPERTY)) {
+      myCbForceTargetJdk.setSelected(properties.isTrueValue(FORCE_TARGET_JDK_PROPERTY));
+    }
+    if (properties.isValueSet(BACKUP_FILES_PROPERTY)) {
+      final boolean backup = properties.isTrueValue(BACKUP_FILES_PROPERTY);
+      myRbBackupFiles.setSelected(backup);
+      myRbOverwriteFiles.setSelected(!backup);
+    }
+    if (properties.isValueSet(INLINE_RUNTIME_CLASSPATH_PROPERTY)) {
+      myCbInlineRuntimeClasspath.setSelected(properties.isTrueValue(INLINE_RUNTIME_CLASSPATH_PROPERTY));
+    }
+    if (properties.isValueSet(GENERATE_IDEA_HOME_PROPERTY)) {
+      myGenerateIdeaHomeProperty.setSelected(properties.isTrueValue(GENERATE_IDEA_HOME_PROPERTY));
+    }
+    if (properties.isValueSet(OUTPUT_FILE_NAME_PROPERTY)) {
+      myOutputFileNameField.setText(properties.getValue(OUTPUT_FILE_NAME_PROPERTY));
+    }
+    else {
+      myOutputFileNameField.setText(BuildProperties.getProjectBuildFileName(myProject));
+    }
+  }
+
+  private void saveSettings() {
+    final PropertiesComponent properties = PropertiesComponent.getInstance(myProject);
+    properties.setValue(SINGLE_FILE_PROPERTY, Boolean.toString(myRbGenerateSingleFileBuild.isSelected()));
+    properties.setValue(UI_FORM_PROPERTY, Boolean.toString(myCbEnableUIFormsCompilation.isSelected()));
+    properties.setValue(FORCE_TARGET_JDK_PROPERTY, Boolean.toString(myCbForceTargetJdk.isSelected()));
+    properties.setValue(BACKUP_FILES_PROPERTY, Boolean.toString(myRbBackupFiles.isSelected()));
+    properties.setValue(INLINE_RUNTIME_CLASSPATH_PROPERTY, Boolean.toString(myCbInlineRuntimeClasspath.isSelected()));
+    properties.setValue(GENERATE_IDEA_HOME_PROPERTY, Boolean.toString(myGenerateIdeaHomeProperty.isSelected()));
+    final String outputFileName = getOutputFileName();
+    if (outputFileName.length() > 0) {
+      properties.setValue(OUTPUT_FILE_NAME_PROPERTY, outputFileName);
+    }
+    else {
+      properties.unsetValue(OUTPUT_FILE_NAME_PROPERTY);
+    }
+  }
+
+  public void dispose() {
+    saveSettings();
+    super.dispose();
+  }
+
+  protected JComponent createCenterPanel() {
+    final ButtonGroup group = new ButtonGroup();
+    group.add(myRbGenerateMultipleFilesBuild);
+    group.add(myRbGenerateSingleFileBuild);
+
+    final ButtonGroup group1 = new ButtonGroup();
+    group1.add(myRbBackupFiles);
+    group1.add(myRbOverwriteFiles);
+
+    myRbGenerateMultipleFilesBuild.setSelected(true);
+    myRbBackupFiles.setSelected(true);
+    myCbEnableUIFormsCompilation.setSelected(true);
+    myCbForceTargetJdk.setSelected(true);
+    myCbInlineRuntimeClasspath.setSelected(false);
+
+    initChunksPanel();
+
+    return myPanel;
+  }
+
+  private void initChunksPanel() {
+    List<Chunk<Module>> chunks = getCycleChunks();
+    if (chunks.isEmpty()) {
+      return;
+    }
+    myChunksPanel.setLayout(new BorderLayout());
+    myChunksPanel.setBorder(
+      IdeBorderFactory.createTitledBorder(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.title"),
+                                          true));
+    JLabel textLabel = new JLabel(CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.description"));
+    textLabel.setUI(new MultiLineLabelUI());
+    textLabel.setBorder(IdeBorderFactory.createEmptyBorder(4, 4, 6, 4));
+    myChunksPanel.add(textLabel, BorderLayout.NORTH);
+
+    myTableModel = new MyTableModel(chunks);
+    myTable = new Table(myTableModel);
+    final MyTableCellRenderer cellRenderer = new MyTableCellRenderer();
+    final TableColumn nameColumn = myTable.getColumnModel().getColumn(MyTableModel.NAME_COLUMN);
+    nameColumn.setCellEditor(ComboBoxTableCellEditor.INSTANCE);
+    nameColumn.setCellRenderer(cellRenderer);
+    final TableColumn labelColumn = myTable.getColumnModel().getColumn(MyTableModel.NUMBER_COLUMN);
+    labelColumn.setCellRenderer(cellRenderer);
+
+    final Dimension preferredSize = new Dimension(myTable.getPreferredSize());
+    preferredSize.height = (myTableModel.getRowCount() + 2) * myTable.getRowHeight() + myTable.getTableHeader().getHeight();
+
+    final JScrollPane scrollPane = ScrollPaneFactory.createScrollPane(myTable);
+    scrollPane.setPreferredSize(preferredSize);
+    myChunksPanel.add(scrollPane, BorderLayout.CENTER);
+  }
+
+  protected void doOKAction() {
+    if (myTable != null) {
+      TableCellEditor cellEditor = myTable.getCellEditor();
+      if (cellEditor != null) {
+        cellEditor.stopCellEditing();
+      }
+    }
+    super.doOKAction();
+  }
+
+  public boolean isGenerateSingleFileBuild() {
+    return myRbGenerateSingleFileBuild.isSelected();
+  }
+
+  public boolean isFormsCompilationEnabled() {
+    return myCbEnableUIFormsCompilation.isSelected();
+  }
+
+  public boolean isForceTargetJdk() {
+    return myCbForceTargetJdk.isSelected();
+  }
+
+  public boolean isBackupFiles() {
+    return myRbBackupFiles.isSelected();
+  }
+
+  public boolean isRuntimeClasspathInlined() {
+    return myCbInlineRuntimeClasspath.isSelected();
+  }
+
+  public String[] getRepresentativeModuleNames() {
+    return myTableModel != null ? myTableModel.getModuleRepresentatives() : ArrayUtil.EMPTY_STRING_ARRAY;
+  }
+
+  /**
+   * @return true if user has selected to generate IDEA_HOME property
+   */
+  public boolean isIdeaHomeGenerated() {
+    return myGenerateIdeaHomeProperty.isSelected();
+  }
+  
+  public String getOutputFileName() {
+    return myOutputFileNameField.getText().trim();
+  }
+  
+  private static class MyTableModel extends AbstractTableModel {
+    private static final int NUMBER_COLUMN = 0;
+    private static final int NAME_COLUMN = 1;
+
+    private final List<Pair<String, ListWithSelection>> myItems = new ArrayList<Pair<String, ListWithSelection>>();
+
+    private MyTableModel(List<Chunk<Module>> chunks) {
+      for (final Chunk<Module> chunk : chunks) {
+        final ListWithSelection<String> item = new ListWithSelection<String>();
+        for (final Module module : chunk.getNodes()) {
+          item.add(module.getName());
+        }
+        item.selectFirst();
+        myItems.add(new Pair<String, ListWithSelection>(createCycleName(chunk), item));
+      }
+    }
+
+    private static String createCycleName(Chunk<Module> chunk) {
+      final StringBuilder buf = new StringBuilder();
+      for (Module module : chunk.getNodes()) {
+        if (buf.length() > 0) {
+          buf.append(", ");
+        }
+        buf.append(module.getName());
+      }
+      buf.insert(0, "[");
+      buf.append("]");
+      return buf.toString();
+    }
+
+    public String[] getModuleRepresentatives() {
+      final String[] names = new String[myItems.size()];
+      int index = 0;
+      for (final Pair<String, ListWithSelection> pair : myItems) {
+        names[index++] = (String)pair.getSecond().getSelection();
+      }
+      return names;
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    public int getRowCount() {
+      return myItems.size();
+    }
+
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      return columnIndex == 1;
+    }
+
+    public Class getColumnClass(int columnIndex) {
+      switch (columnIndex) {
+        case NUMBER_COLUMN:
+          return String.class;
+        case NAME_COLUMN:
+          return ListWithSelection.class;
+        default:
+          return super.getColumnClass(columnIndex);
+      }
+    }
+
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      switch (columnIndex) {
+        case NUMBER_COLUMN:
+          return myItems.get(rowIndex).getFirst();
+        case NAME_COLUMN:
+          return myItems.get(rowIndex).getSecond();
+        default:
+          return null;
+      }
+    }
+
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+      if (columnIndex == NAME_COLUMN) {
+        myItems.get(rowIndex).getSecond().select(aValue);
+      }
+    }
+
+    public String getColumnName(int columnIndex) {
+      switch (columnIndex) {
+        case NUMBER_COLUMN:
+          return CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.number.column.header");
+        case NAME_COLUMN:
+          return CompilerBundle.message("generate.ant.build.dialog.cyclic.modules.table.name.column.header");
+      }
+      return super.getColumnName(columnIndex);
+    }
+  }
+
+  private static class MyTableCellRenderer extends DefaultTableCellRenderer {
+    public Component getTableCellRendererComponent(JTable table,
+                                                   Object value,
+                                                   boolean isSelected,
+                                                   boolean hasFocus,
+                                                   int row,
+                                                   int column) {
+      if (value instanceof ListWithSelection) {
+        value = ((ListWithSelection)value).getSelection();
+      }
+      final JLabel component = (JLabel)super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      component.setHorizontalAlignment(SwingConstants.CENTER);
+      return component;
+    }
+  }
+
+  protected Action[] createActions() {
+    return new Action[]{getOKAction(), getCancelAction(), getHelpAction()};
+  }
+
+  protected void doHelpAction() {
+    HelpManager.getInstance().invokeHelp(HelpID.GENERATE_ANT_BUILD);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java
new file mode 100644
index 0000000..08b85a8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/MakeModuleAction.java
@@ -0,0 +1,84 @@
+/*
+ * 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.compiler.actions;
+
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+
+public class MakeModuleAction extends CompileActionBase {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.actions.MakeModuleAction");
+
+  protected void doAction(DataContext dataContext, Project project) {
+    Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext);
+    Module module;
+    if (modules == null) {
+      module = LangDataKeys.MODULE.getData(dataContext);
+      if (module == null) {
+        return;
+      }
+      modules = new Module[]{module};
+    }
+    try {
+      CompilerManager.getInstance(project).make(modules[0].getProject(), modules, null);
+    }
+    catch (Exception e) {
+      LOG.error(e);
+    }
+  }
+
+  public void update(AnActionEvent event){
+    super.update(event);
+    Presentation presentation = event.getPresentation();
+    if (!presentation.isEnabled()) {
+      return;
+    }
+    final DataContext dataContext = event.getDataContext();
+    final Module module = LangDataKeys.MODULE.getData(dataContext);
+    Module[] modules = LangDataKeys.MODULE_CONTEXT_ARRAY.getData(dataContext);
+    final boolean isEnabled = module != null || modules != null;
+    presentation.setEnabled(isEnabled);
+    final String actionName = getTemplatePresentation().getTextWithMnemonic();
+
+    String presentationText;
+    if (modules != null) {
+      String text = actionName;
+      for (int i = 0; i < modules.length; i++) {
+        if (text.length() > 30) {
+          text = CompilerBundle.message("action.make.selected.modules.text");
+          break;
+        }
+        Module toMake = modules[i];
+        if (i!=0) {
+          text += ",";
+        }
+        text += " '" + toMake.getName() + "'";
+      }
+      presentationText = text;
+    }
+    else if (module != null) {
+      presentationText = actionName + " '" + module.getName() + "'";
+    }
+    else {
+      presentationText = actionName;
+    }
+    presentation.setText(presentationText);
+    presentation.setVisible(isEnabled || !ActionPlaces.PROJECT_VIEW_POPUP.equals(event.getPlace()));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/actions/ProcessAnnotationsAction.java b/java/compiler/impl/src/com/intellij/compiler/actions/ProcessAnnotationsAction.java
new file mode 100644
index 0000000..bb59707
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/actions/ProcessAnnotationsAction.java
@@ -0,0 +1,203 @@
+/*
+ * 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.compiler.actions;
+
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.impl.FileSetCompileScope;
+import com.intellij.compiler.impl.ModuleCompileScope;
+import com.intellij.compiler.impl.javaCompiler.AnnotationProcessingCompiler;
+import com.intellij.compiler.impl.resourceCompiler.ResourceCompiler;
+import com.intellij.idea.ActionsBundle;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerFilter;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.text.MessageFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ProcessAnnotationsAction extends CompileActionBase {
+
+  protected void doAction(DataContext dataContext, Project project) {
+    final Module module = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
+    final CompilerFilter filter = new CompilerFilter() {
+      public boolean acceptCompiler(com.intellij.openapi.compiler.Compiler compiler) {
+        // EclipseLink CanonicalModelProcessor reads input from output hence adding ResourcesCompiler
+        return compiler instanceof AnnotationProcessingCompiler || compiler instanceof ResourceCompiler;
+      }
+    };
+    if (module != null) {
+      CompilerManager.getInstance(project).make(new ModuleCompileScope(module, false), filter, null);
+    }
+    else {
+      final FileSetCompileScope scope = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
+      if (scope != null) {
+        CompilerManager.getInstance(project).make(scope, filter, null);
+      }
+    }
+  }
+
+  public void update(AnActionEvent event) {
+    super.update(event);
+    Presentation presentation = event.getPresentation();
+    if (!presentation.isEnabled()) {
+      return;
+    }
+    DataContext dataContext = event.getDataContext();
+    presentation.setVisible(false);
+
+    Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+    if (project == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(project);
+    final Module module = LangDataKeys.MODULE.getData(dataContext);
+    final Module moduleContext = LangDataKeys.MODULE_CONTEXT.getData(dataContext);
+
+    if (module == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+    final AnnotationProcessingConfiguration profile = compilerConfiguration.getAnnotationProcessingConfiguration(module);
+    if (!profile.isEnabled() || (!profile.isObtainProcessorsFromClasspath() && profile.getProcessors().isEmpty())) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    presentation.setVisible(true);
+    presentation.setText(createPresentationText(""), true);
+    final FileSetCompileScope scope = getCompilableFiles(project, PlatformDataKeys.VIRTUAL_FILE_ARRAY.getData(dataContext));
+    if (moduleContext == null && scope == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    String elementDescription = null;
+    if (moduleContext != null) {
+      elementDescription = CompilerBundle.message("action.compile.description.module", moduleContext.getName());
+    }
+    else {
+      PsiPackage aPackage = null;
+      final Collection<VirtualFile> files = scope.getRootFiles();
+      if (files.size() == 1) {
+        final PsiDirectory directory = PsiManager.getInstance(project).findDirectory(files.iterator().next());
+        if (directory != null) {
+          aPackage = JavaDirectoryService.getInstance().getPackage(directory);
+        }
+      }
+      else {
+        PsiElement element = LangDataKeys.PSI_ELEMENT.getData(dataContext);
+        if (element instanceof PsiPackage) {
+          aPackage = (PsiPackage)element;
+        }
+      }
+
+      if (aPackage != null) {
+        String name = aPackage.getQualifiedName();
+        if (name.length() == 0) {
+          //noinspection HardCodedStringLiteral
+          name = "<default>";
+        }
+        elementDescription = "'" + name + "'";
+      }
+      else if (files.size() == 1) {
+        final VirtualFile file = files.iterator().next();
+        FileType fileType = file.getFileType();
+        if (CompilerManager.getInstance(project).isCompilableFileType(fileType)) {
+          elementDescription = "'" + file.getName() + "'";
+        }
+        else {
+          if (!ActionPlaces.MAIN_MENU.equals(event.getPlace())) {
+            // the action should be invisible in popups for non-java files
+            presentation.setEnabled(false);
+            presentation.setVisible(false);
+            return;
+          }
+        }
+      }
+      else {
+        elementDescription = CompilerBundle.message("action.compile.description.selected.files");
+      }
+    }
+
+    if (elementDescription == null) {
+      presentation.setEnabled(false);
+      return;
+    }
+
+    presentation.setText(createPresentationText(elementDescription), true);
+    presentation.setEnabled(true);
+  }
+
+  private static String createPresentationText(final String elementDescription) {
+    int length = elementDescription.length();
+    String target = length > 23 ? (StringUtil.startsWithChar(elementDescription, '\'') ? "'..." : "...") + elementDescription.substring(length - 20, length) : elementDescription;
+    return MessageFormat.format(ActionsBundle.actionText(StringUtil.isEmpty(target)? "RunAPT" : "RunAPT.1"), target);
+  }
+
+  @Nullable
+  private static FileSetCompileScope getCompilableFiles(Project project, VirtualFile[] files) {
+    if (files == null || files.length == 0) {
+      return null;
+    }
+    final PsiManager psiManager = PsiManager.getInstance(project);
+    final FileTypeManager typeManager = FileTypeManager.getInstance();
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    final CompilerManager compilerManager = CompilerManager.getInstance(project);
+    final List<VirtualFile> filesToCompile = new ArrayList<VirtualFile>();
+    final List<Module> affectedModules = new ArrayList<Module>();
+    for (final VirtualFile file : files) {
+      if (!fileIndex.isInSourceContent(file)) {
+        continue;
+      }
+      if (!file.isInLocalFileSystem()) {
+        continue;
+      }
+      if (file.isDirectory()) {
+        final PsiDirectory directory = psiManager.findDirectory(file);
+        if (directory == null || JavaDirectoryService.getInstance().getPackage(directory) == null) {
+          continue;
+        }
+      }
+      else {
+        FileType fileType = file.getFileType();
+        if (!(compilerManager.isCompilableFileType(fileType))) {
+          continue;
+        }
+      }
+      filesToCompile.add(file);
+      ContainerUtil.addIfNotNull(fileIndex.getModuleForFile(file), affectedModules);
+    }
+    if (filesToCompile.isEmpty()) return null;
+    return new FileSetCompileScope(filesToCompile, affectedModules.toArray(new Module[affectedModules.size()]));
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/BuildPropertiesImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/BuildPropertiesImpl.java
new file mode 100644
index 0000000..d89cd15
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/BuildPropertiesImpl.java
@@ -0,0 +1,188 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.*;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ex.ProjectEx;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+// todo: move path variables properties and jdk home properties into te generated property file
+public class BuildPropertiesImpl extends BuildProperties {
+
+  public BuildPropertiesImpl(Project project, final GenerationOptions genOptions) {
+    add(new Property(genOptions.getPropertiesFileName()));
+
+    //noinspection HardCodedStringLiteral
+    add(new Comment(CompilerBundle.message("generated.ant.build.disable.tests.property.comment"),
+                    new Property(PROPERTY_SKIP_TESTS, "true")));
+    final JpsJavaCompilerOptions javacSettings = JavacConfiguration.getOptions(project, JavacConfiguration.class);
+    add(new Comment(CompilerBundle.message("generated.ant.build.compiler.options.comment")), 1);
+    //noinspection HardCodedStringLiteral
+    add(new Property(PROPERTY_COMPILER_GENERATE_DEBUG_INFO, javacSettings.DEBUGGING_INFO ? "on" : "off"), 1);
+    //noinspection HardCodedStringLiteral
+    add(new Property(PROPERTY_COMPILER_GENERATE_NO_WARNINGS, javacSettings.GENERATE_NO_WARNINGS ? "on" : "off"));
+    add(new Property(PROPERTY_COMPILER_ADDITIONAL_ARGS, javacSettings.ADDITIONAL_OPTIONS_STRING));
+    //noinspection HardCodedStringLiteral
+    add(new Property(PROPERTY_COMPILER_MAX_MEMORY, Integer.toString(javacSettings.MAXIMUM_HEAP_SIZE) + "m"));
+
+    add(new IgnoredFiles());
+
+    if (CompilerExcludes.isAvailable(project)) {
+      add(new CompilerExcludes(project, genOptions));
+    }
+
+    if (!genOptions.expandJarDirectories) {
+      add(new LibraryPatterns(project, genOptions));
+    }
+
+    add(new CompilerResourcePatterns(project));
+
+    if (genOptions.forceTargetJdk) {
+      createJdkGenerators(project);
+    }
+
+    LibraryDefinitionsGeneratorFactory factory = new LibraryDefinitionsGeneratorFactory((ProjectEx)project, genOptions);
+
+    final LibraryTablesRegistrar registrar = LibraryTablesRegistrar.getInstance();
+    final Generator projectLibs = factory.create(registrar.getLibraryTable(project), getProjectBaseDir(project),
+                                                 CompilerBundle.message("generated.ant.build.project.libraries.comment"));
+    if (projectLibs != null) {
+      add(projectLibs);
+    }
+
+    final Generator globalLibs =
+      factory.create(registrar.getLibraryTable(), null, CompilerBundle.message("generated.ant.build.global.libraries.comment"));
+    if (globalLibs != null) {
+      add(globalLibs);
+    }
+
+    for (final LibraryTable table : registrar.getCustomLibraryTables()) {
+      if (table.getLibraries().length != 0) {
+        final Generator appServerLibs = factory.create(table, null, table.getPresentation().getDisplayName(true));
+        if (appServerLibs != null) {
+          add(appServerLibs);
+        }
+      }
+    }
+
+    final ChunkCustomCompilerExtension[] customCompilers = genOptions.getCustomCompilers();
+    if (genOptions.enableFormCompiler || customCompilers.length > 0) {
+      add(new Comment(CompilerBundle.message("generated.ant.build.custom.compilers.comment")));
+      Target register = new Target(TARGET_REGISTER_CUSTOM_COMPILERS, null, null, null);
+      if (genOptions.enableFormCompiler) {
+        //noinspection HardCodedStringLiteral
+        add(new Property(PROPERTY_JAVAC2_HOME, propertyRelativePath(PROPERTY_IDEA_HOME, "lib")));
+        Path javac2 = new Path(PROPERTY_JAVAC2_CLASSPATH_ID);
+        javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "javac2.jar")));
+        javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "jdom.jar")));
+        javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "asm4-all.jar")));
+        javac2.add(new PathElement(propertyRelativePath(PROPERTY_JAVAC2_HOME, "jgoodies-forms.jar")));
+        add(javac2);
+        //noinspection HardCodedStringLiteral
+        register.add(new Tag("taskdef", Pair.create("name", "javac2"), Pair.create("classname", "com.intellij.ant.Javac2"),
+                    Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
+        register.add(new Tag("taskdef", Pair.create("name", "instrumentIdeaExtensions"),
+                    Pair.create("classname", "com.intellij.ant.InstrumentIdeaExtensions"),
+                    Pair.create("classpathref", PROPERTY_JAVAC2_CLASSPATH_ID)));
+      }
+      if (customCompilers.length > 0) {
+        for (ChunkCustomCompilerExtension ext : customCompilers) {
+          ext.generateCustomCompilerTaskRegistration(project, genOptions, register);
+        }
+      }
+      add(register);
+    }
+  }
+
+  protected void createJdkGenerators(final Project project) {
+    final Sdk[] jdks = getUsedJdks(project);
+
+    if (jdks.length > 0) {
+      add(new Comment(CompilerBundle.message("generated.ant.build.jdk.definitions.comment")), 1);
+
+      for (final Sdk jdk : jdks) {
+        if (jdk.getHomeDirectory() == null) {
+          continue;
+        }
+        final SdkTypeId sdkType = jdk.getSdkType();
+        if (!(sdkType instanceof JavaSdkType) || ((JavaSdkType)sdkType).getBinPath(jdk) == null) {
+          continue;
+        }
+        final File home = VfsUtil.virtualToIoFile(jdk.getHomeDirectory());
+        File homeDir;
+        try {
+          // use canonical path in order to resolve symlinks
+          homeDir = home.getCanonicalFile();
+        }
+        catch (IOException e) {
+          homeDir = home;
+        }
+        final String jdkName = jdk.getName();
+        final String jdkHomeProperty = getJdkHomeProperty(jdkName);
+        final FileSet fileSet = new FileSet(propertyRef(jdkHomeProperty));
+        final String[] urls = jdk.getRootProvider().getUrls(OrderRootType.CLASSES);
+        for (String url : urls) {
+          final String path = GenerationUtils.trimJarSeparator(VirtualFileManager.extractPath(url));
+          final File pathElement = new File(path);
+          final String relativePath = FileUtil.getRelativePath(homeDir, pathElement);
+          if (relativePath != null) {
+            fileSet.add(new Include(relativePath.replace(File.separatorChar, '/')));
+          }
+        }
+
+        final File binPath = toCanonicalFile(new File(((JavaSdkType)sdkType).getBinPath(jdk)));
+        final String relativePath = FileUtil.getRelativePath(homeDir, binPath);
+        if (relativePath != null) {
+          add(new Property(BuildProperties.getJdkBinProperty(jdkName),
+                           propertyRef(jdkHomeProperty) + "/" + FileUtil.toSystemIndependentName(relativePath)), 1);
+        }
+        else {
+          add(new Property(BuildProperties.getJdkBinProperty(jdkName), FileUtil.toSystemIndependentName(binPath.getPath())), 1);
+        }
+
+        final Path jdkPath = new Path(getJdkPathId(jdkName));
+        jdkPath.add(fileSet);
+        add(jdkPath);
+      }
+    }
+
+    final Sdk projectJdk = ProjectRootManager.getInstance(project).getProjectSdk();
+    add(new Property(PROPERTY_PROJECT_JDK_HOME, projectJdk != null ? propertyRef(getJdkHomeProperty(projectJdk.getName())) : ""), 1);
+    add(new Property(PROPERTY_PROJECT_JDK_BIN, projectJdk != null ? propertyRef(getJdkBinProperty(projectJdk.getName())) : ""));
+    add(new Property(PROPERTY_PROJECT_JDK_CLASSPATH, projectJdk != null ? getJdkPathId(projectJdk.getName()) : ""));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/BuildTargetsFactoryImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/BuildTargetsFactoryImpl.java
new file mode 100644
index 0000000..0db7086
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/BuildTargetsFactoryImpl.java
@@ -0,0 +1,38 @@
+/*
+ * 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2006
+ */
+package com.intellij.compiler.ant;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.TestOnly;
+
+public class BuildTargetsFactoryImpl extends BuildTargetsFactory {
+
+
+  public Generator createComment(final String comment) {
+    return new Comment(comment);
+  }
+
+  @TestOnly
+  public GenerationOptions getDefaultOptions(Project project) {
+    return new GenerationOptionsImpl(project, true, false, false, true, ArrayUtil.EMPTY_STRING_ARRAY);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ChunkBuild.java b/java/compiler/impl/src/com/intellij/compiler/ant/ChunkBuild.java
new file mode 100644
index 0000000..cd20b1c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ChunkBuild.java
@@ -0,0 +1,84 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Path;
+import com.intellij.compiler.ant.taskdefs.Property;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.vfs.VirtualFileManager;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 22, 2004
+ */
+public class ChunkBuild extends CompositeGenerator{
+
+  public ChunkBuild(Project project, ModuleChunk chunk, GenerationOptions genOptions) {
+    final File chunkBaseDir = chunk.getBaseDir();
+    if (genOptions.forceTargetJdk) {
+      if (chunk.isJdkInherited()) {
+        add(new Property(BuildProperties.getModuleChunkJdkHomeProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_PROJECT_JDK_HOME)));
+        add(new Property(BuildProperties.getModuleChunkJdkBinProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_PROJECT_JDK_BIN)));
+        add(new Property(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_PROJECT_JDK_CLASSPATH)));
+      }
+      else {
+        final Sdk jdk = chunk.getJdk();
+        add(new Property(BuildProperties.getModuleChunkJdkHomeProperty(chunk.getName()), jdk != null? BuildProperties.propertyRef(BuildProperties.getJdkHomeProperty(jdk.getName())): ""));
+        add(new Property(BuildProperties.getModuleChunkJdkBinProperty(chunk.getName()), jdk != null? BuildProperties.propertyRef(BuildProperties.getJdkBinProperty(jdk.getName())): ""));
+        add(new Property(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()), jdk != null? BuildProperties.getJdkPathId(jdk.getName()) : ""));
+      }
+    }
+
+    add(new Property(BuildProperties.getModuleChunkCompilerArgsProperty(chunk.getName()), BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_ADDITIONAL_ARGS)), 1);
+
+    final String outputPathUrl = chunk.getOutputDirUrl();
+    String location = outputPathUrl != null?
+                      GenerationUtils.toRelativePath(VirtualFileManager.extractPath(outputPathUrl), chunkBaseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions) :
+                      CompilerBundle.message("value.undefined");
+    add(new Property(BuildProperties.getOutputPathProperty(chunk.getName()), location), 1);
+
+    final String testOutputPathUrl = chunk.getTestsOutputDirUrl();
+    if (testOutputPathUrl != null) {
+      location = GenerationUtils.toRelativePath(VirtualFileManager.extractPath(testOutputPathUrl), chunkBaseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions);
+    }
+    add(new Property(BuildProperties.getOutputPathForTestsProperty(chunk.getName()), location));
+
+    add(createBootclasspath(chunk), 1);
+    add(new ModuleChunkClasspath(chunk, genOptions, false, false), 1);
+    add(new ModuleChunkClasspath(chunk, genOptions, true, false), 1);
+    add(new ModuleChunkClasspath(chunk, genOptions, false, true), 1);
+    add(new ModuleChunkClasspath(chunk, genOptions, true, true), 1);
+
+    final ModuleChunkSourcePath moduleSources = new ModuleChunkSourcePath(project, chunk, genOptions);
+    add(moduleSources, 1);
+    add(new CompileModuleChunkTarget(project, chunk, moduleSources.getSourceRoots(), moduleSources.getTestSourceRoots(), chunkBaseDir, genOptions), 1);
+    add(new CleanModule(chunk), 1);
+
+    ChunkBuildExtension.process(this, chunk, genOptions);
+  }
+
+  private static Generator createBootclasspath(ModuleChunk chunk) {
+    final Path bootclasspath = new Path(BuildProperties.getBootClasspathProperty(chunk.getName()));
+    bootclasspath.add(new Comment(CompilerBundle.message("generated.ant.build.bootclasspath.comment")));
+    return bootclasspath;
+  }
+
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/CleanModule.java b/java/compiler/impl/src/com/intellij/compiler/ant/CleanModule.java
new file mode 100644
index 0000000..0b27fac
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/CleanModule.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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Delete;
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.openapi.compiler.CompilerBundle;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 24, 2004
+ */
+public class CleanModule extends Target {
+  public CleanModule(ModuleChunk chunk) {
+    super(BuildProperties.getModuleCleanTargetName(chunk.getName()), null,
+          CompilerBundle.message("generated.ant.build.cleanup.module.task.comment"), null);
+    final String chunkName = chunk.getName();
+    add(new Delete(BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunkName))));
+    add(new Delete(BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunkName))));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/CleanProject.java b/java/compiler/impl/src/com/intellij/compiler/ant/CleanProject.java
new file mode 100644
index 0000000..5613da9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/CleanProject.java
@@ -0,0 +1,54 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.artifacts.ArtifactsGenerator;
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 24, 2004
+ */
+public class CleanProject extends Generator {
+  private final Target myTarget;
+
+  public CleanProject(Project project, @NotNull GenerationOptions genOptions, @NotNull ArtifactsGenerator artifactsGenerator) {
+    List<String> dependencies = new ArrayList<String>();
+    final ModuleChunk[] chunks = genOptions.getModuleChunks();
+    for (ModuleChunk chunk : chunks) {
+      dependencies.add(BuildProperties.getModuleCleanTargetName(chunk.getName()));
+    }
+    dependencies.addAll(artifactsGenerator.getCleanTargetNames());
+    for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) {
+      dependencies.addAll(extension.getCleanTargetNames(project, genOptions));
+    }
+    myTarget = new Target(BuildProperties.TARGET_CLEAN, StringUtil.join(dependencies, ", "),
+                          CompilerBundle.message("generated.ant.build.clean.all.task.comment"), null);
+  }
+
+  public void generate(PrintWriter out) throws IOException {
+    myTarget.generate(out);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/Comment.java b/java/compiler/impl/src/com/intellij/compiler/ant/Comment.java
new file mode 100644
index 0000000..146d256
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/Comment.java
@@ -0,0 +1,59 @@
+/*
+ * 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.compiler.ant;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Comment extends Generator{
+  private final String myComment;
+  private final Generator myCommentedData;
+
+  public Comment(String comment) {
+    this(comment, null);
+  }
+
+  public Comment(Generator commentedData) {
+    this(null, commentedData);
+  }
+
+  public Comment(String comment, Generator commentedData) {
+    myComment = comment;
+    myCommentedData = commentedData;
+  }
+
+  public void generate(PrintWriter out) throws IOException {
+    if (myComment != null) {
+      out.print("<!-- ");
+      out.print(myComment);
+      out.print(" -->");
+      if (myCommentedData != null) {
+        crlf(out);
+      }
+    }
+    if (myCommentedData != null) {
+      out.print("<!-- ");
+      crlf(out);
+      myCommentedData.generate(out);
+      crlf(out);
+      out.print(" -->");
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/CompileModuleChunkTarget.java b/java/compiler/impl/src/com/intellij/compiler/ant/CompileModuleChunkTarget.java
new file mode 100644
index 0000000..e08040b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/CompileModuleChunkTarget.java
@@ -0,0 +1,213 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.*;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class CompileModuleChunkTarget extends CompositeGenerator {
+
+  public CompileModuleChunkTarget(final Project project,
+                                  ModuleChunk moduleChunk,
+                                  VirtualFile[] sourceRoots,
+                                  VirtualFile[] testSourceRoots,
+                                  File baseDir,
+                                  GenerationOptions genOptions) {
+    final String moduleChunkName = moduleChunk.getName();
+    //noinspection HardCodedStringLiteral
+    final Tag compilerArgs = new Tag("compilerarg", Pair.create("line", BuildProperties.propertyRef(
+      BuildProperties.getModuleChunkCompilerArgsProperty(moduleChunkName))));
+    //noinspection HardCodedStringLiteral
+    final Pair<String, String> classpathRef = Pair.create("refid", BuildProperties.getClasspathProperty(moduleChunkName));
+    final Tag classpathTag = new Tag("classpath", classpathRef);
+    //noinspection HardCodedStringLiteral
+    final Tag bootclasspathTag =
+      new Tag("bootclasspath", Pair.create("refid", BuildProperties.getBootClasspathProperty(moduleChunkName)));
+    final PatternSetRef compilerExcludes = new PatternSetRef(BuildProperties.getExcludedFromCompilationProperty(moduleChunkName));
+
+    final String mainTargetName = BuildProperties.getCompileTargetName(moduleChunkName);
+    final @NonNls String productionTargetName = mainTargetName + ".production";
+    final @NonNls String testsTargetName = mainTargetName + ".tests";
+
+    final ChunkCustomCompilerExtension[] customCompilers = moduleChunk.getCustomCompilers();
+    final String customCompilersDependency = customCompilers.length != 0 || genOptions.enableFormCompiler ?
+                                             BuildProperties.TARGET_REGISTER_CUSTOM_COMPILERS : "";
+    final int modulesCount = moduleChunk.getModules().length;
+    Target mainTarget = new Target(mainTargetName, productionTargetName + "," + testsTargetName,
+                                   CompilerBundle.message("generated.ant.build.compile.modules.main.target.comment", modulesCount,
+                                                          moduleChunkName), null);
+    String dependenciesProduction = getChunkDependenciesString(moduleChunk);
+    if (customCompilersDependency.length() > 0) {
+      if (dependenciesProduction != null && dependenciesProduction.length() > 0) {
+        dependenciesProduction = customCompilersDependency + "," + dependenciesProduction;
+      }
+      else {
+        dependenciesProduction = customCompilersDependency;
+      }
+    }
+    Target productionTarget = new Target(productionTargetName, dependenciesProduction,
+                                         CompilerBundle.message("generated.ant.build.compile.modules.production.classes.target.comment",
+                                                                modulesCount, moduleChunkName), null);
+    String dependenciesTests = (customCompilersDependency.length() != 0 ? customCompilersDependency + "," : "") + productionTargetName;
+    Target testsTarget = new Target(testsTargetName, dependenciesTests,
+                                    CompilerBundle.message("generated.ant.build.compile.modules.tests.target.comment", modulesCount,
+                                                           moduleChunkName), BuildProperties.PROPERTY_SKIP_TESTS);
+
+    if (sourceRoots.length > 0) {
+      final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(moduleChunkName));
+      final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getSourcepathProperty(moduleChunkName)));
+      productionTarget.add(new Mkdir(outputPathRef));
+      createCustomCompilerTasks(project, moduleChunk, genOptions, false, customCompilers, compilerArgs, bootclasspathTag,
+                                classpathTag, compilerExcludes, srcTag, outputPathRef, productionTarget);
+      if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
+        final Javac javac = new Javac(genOptions, moduleChunk, outputPathRef);
+        javac.add(compilerArgs);
+        javac.add(bootclasspathTag);
+        javac.add(classpathTag);
+        javac.add(srcTag);
+        javac.add(compilerExcludes);
+        productionTarget.add(javac);
+      }
+      productionTarget.add(createCopyTask(project, moduleChunk, sourceRoots, outputPathRef, baseDir, genOptions));
+    }
+
+    if (testSourceRoots.length > 0) {
+
+      final String testOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(moduleChunkName));
+      final Tag srcTag = new Tag("src", Pair.create("refid", BuildProperties.getTestSourcepathProperty(moduleChunkName)));
+      final Pair<String, String> testClasspathRef = Pair.create("refid", BuildProperties.getTestClasspathProperty(moduleChunkName));
+      final Tag testClassPath = new Tag("classpath", testClasspathRef);
+      testsTarget.add(new Mkdir(testOutputPathRef));
+      createCustomCompilerTasks(project, moduleChunk, genOptions, true, customCompilers, compilerArgs, bootclasspathTag,
+                                testClassPath, compilerExcludes, srcTag, testOutputPathRef, testsTarget);
+      if (customCompilers.length == 0 || genOptions.enableFormCompiler) {
+        final Javac javac = new Javac(genOptions, moduleChunk, testOutputPathRef);
+        javac.add(compilerArgs);
+        javac.add(bootclasspathTag);
+        javac.add(testClassPath);
+        javac.add(srcTag);
+        javac.add(compilerExcludes);
+        testsTarget.add(javac);
+      }
+      testsTarget.add(createCopyTask(project, moduleChunk, testSourceRoots, testOutputPathRef, baseDir, genOptions));
+    }
+
+    add(mainTarget);
+    add(productionTarget, 1);
+    add(testsTarget, 1);
+  }
+
+  /**
+   * Create custom compiler tasks
+   *
+   * @param project          the project
+   * @param moduleChunk      the module chunk
+   * @param genOptions       generation options
+   * @param compileTests     if true tests are being compiled
+   * @param customCompilers  an array of custom compilers for this chunk
+   * @param compilerArgs     the javac compiler arguments
+   * @param bootclasspathTag the boot classpath element for the javac compiler
+   * @param classpathTag     the classpath tag for the javac compiler
+   * @param compilerExcludes the compiler excluded tag
+   * @param srcTag           the source tag
+   * @param outputPathRef    the output path references
+   * @param target           the target where to add custom compiler
+   */
+  private static void createCustomCompilerTasks(Project project,
+                                                ModuleChunk moduleChunk,
+                                                GenerationOptions genOptions,
+                                                boolean compileTests,
+                                                ChunkCustomCompilerExtension[] customCompilers,
+                                                Tag compilerArgs,
+                                                Tag bootclasspathTag,
+                                                Tag classpathTag,
+                                                PatternSetRef compilerExcludes,
+                                                Tag srcTag,
+                                                String outputPathRef,
+                                                Target target) {
+    if (customCompilers.length > 1) {
+      target.add(new Tag("fail", Pair.create("message", CompilerBundle.message(
+        "generated.ant.build.compile.modules.fail.custom.compilers"))));
+    }
+    for (ChunkCustomCompilerExtension ext : customCompilers) {
+      ext.generateCustomCompile(project, moduleChunk, genOptions, compileTests, target, compilerArgs, bootclasspathTag,
+                                classpathTag, compilerExcludes, srcTag, outputPathRef);
+    }
+  }
+
+  private static String getChunkDependenciesString(ModuleChunk moduleChunk) {
+    final StringBuffer moduleDependencies = new StringBuffer();
+    final ModuleChunk[] dependencies = moduleChunk.getDependentChunks();
+    for (int idx = 0; idx < dependencies.length; idx++) {
+      final ModuleChunk dependency = dependencies[idx];
+      if (idx > 0) {
+        moduleDependencies.append(",");
+      }
+      moduleDependencies.append(BuildProperties.getCompileTargetName(dependency.getName()));
+    }
+    return moduleDependencies.toString();
+  }
+
+  private static Generator createCopyTask(final Project project,
+                                          ModuleChunk chunk,
+                                          VirtualFile[] sourceRoots,
+                                          String toDir,
+                                          File baseDir,
+                                          final GenerationOptions genOptions) {
+    //noinspection HardCodedStringLiteral
+    final Tag filesSelector = new Tag("type", Pair.create("type", "file"));
+    final PatternSetRef excludes = CompilerExcludes.isAvailable(project) ? new PatternSetRef(
+      BuildProperties.getExcludedFromCompilationProperty(chunk.getName())) : null;
+    final PatternSetRef resourcePatternsPatternSet = new PatternSetRef(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS);
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    final CompositeGenerator composite = new CompositeGenerator();
+    final Map<String, Copy> outputDirToTaskMap = new HashMap<String, Copy>();
+    for (final VirtualFile root : sourceRoots) {
+      final String packagePrefix = fileIndex.getPackageNameByDirectory(root);
+      final String targetDir =
+        packagePrefix != null && packagePrefix.length() > 0 ? toDir + "/" + packagePrefix.replace('.', '/') : toDir;
+      Copy copy = outputDirToTaskMap.get(targetDir);
+      if (copy == null) {
+        copy = new Copy(targetDir);
+        outputDirToTaskMap.put(targetDir, copy);
+        composite.add(copy);
+      }
+      final FileSet fileSet = new FileSet(
+        GenerationUtils.toRelativePath(root, baseDir, BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions));
+      fileSet.add(resourcePatternsPatternSet);
+      fileSet.add(filesSelector);
+      if (excludes != null) {
+        fileSet.add(excludes);
+      }
+      copy.add(fileSet);
+    }
+    return composite;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/CompilerExcludes.java b/java/compiler/impl/src/com/intellij/compiler/ant/CompilerExcludes.java
new file mode 100644
index 0000000..538fee9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/CompilerExcludes.java
@@ -0,0 +1,74 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.ant.taskdefs.Exclude;
+import com.intellij.compiler.ant.taskdefs.PatternSet;
+import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
+import com.intellij.openapi.project.Project;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class CompilerExcludes extends Generator {
+  private final PatternSet myPatternSet;
+
+  public CompilerExcludes(Project project, GenerationOptions genOptions) {
+    final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    final ExcludeEntryDescription[] excludeEntryDescriptions =
+      compilerConfiguration.getExcludedEntriesConfiguration().getExcludeEntryDescriptions();
+    myPatternSet = new PatternSet(BuildProperties.PROPERTY_COMPILER_EXCLUDES);
+    for (final ExcludeEntryDescription entry : excludeEntryDescriptions) {
+      final String path = GenerationUtils
+        .toRelativePath(entry.getVirtualFile(), BuildProperties.getProjectBaseDir(project), BuildProperties.getProjectBaseDirProperty(),
+                        genOptions);
+      if (path == null) {
+        // entry is invalid, skip it
+        continue;
+      }
+      if (entry.isFile()) {
+        myPatternSet.add(new Exclude(path));
+      }
+      else {
+        if (entry.isIncludeSubdirectories()) {
+          myPatternSet.add(new Exclude(path + "/**"));
+        }
+        else {
+          myPatternSet.add(new Exclude(path + "/*"));
+        }
+      }
+    }
+  }
+
+
+  public void generate(PrintWriter out) throws IOException {
+    myPatternSet.generate(out);
+  }
+
+  public static boolean isAvailable(Project project) {
+    final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    final ExcludeEntryDescription[] excludeEntryDescriptions =
+      compilerConfiguration.getExcludedEntriesConfiguration().getExcludeEntryDescriptions();
+    return excludeEntryDescriptions.length > 0;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/CompilerResourcePatterns.java b/java/compiler/impl/src/com/intellij/compiler/ant/CompilerResourcePatterns.java
new file mode 100644
index 0000000..d63966b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/CompilerResourcePatterns.java
@@ -0,0 +1,55 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.ant.taskdefs.Exclude;
+import com.intellij.compiler.ant.taskdefs.Include;
+import com.intellij.compiler.ant.taskdefs.PatternSet;
+import com.intellij.openapi.project.Project;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class CompilerResourcePatterns extends Generator {
+  private final PatternSet myPatternSet;
+
+  public CompilerResourcePatterns(Project project) {
+    final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    final String[] patterns = compilerConfiguration.getResourceFilePatterns();
+    myPatternSet = new PatternSet(BuildProperties.PROPERTY_COMPILER_RESOURCE_PATTERNS);
+    for (String pattern : patterns) {
+      if (CompilerConfigurationImpl.isPatternNegated(pattern)) {
+        myPatternSet.add(new Exclude("**/" + pattern.substring(1)));
+      }
+      else {
+        myPatternSet.add(new Include("**/" + pattern));
+      }
+    }
+  }
+
+
+  public void generate(PrintWriter out) throws IOException {
+    myPatternSet.generate(out);
+  }
+
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntApplication.java b/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntApplication.java
new file mode 100644
index 0000000..5a2fa70
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntApplication.java
@@ -0,0 +1,125 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.compiler.actions.GenerateAntBuildAction;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.ex.ApplicationEx;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ex.ProjectManagerEx;
+import com.intellij.openapi.roots.impl.DirectoryIndex;
+import com.intellij.openapi.roots.impl.DirectoryIndexImpl;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author max
+ */
+public class GenerateAntApplication {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.ex.InspectionApplication");
+
+  public String myProjectPath = null;
+  public String myOutPath = null;
+  private Project myProject;
+  private int myVerboseLevel = 0;
+
+  public void startup() {
+    if (myProjectPath == null || myOutPath == null) {
+      GenerateAntMain.printHelp();
+    }
+
+    SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        ApplicationEx application = ApplicationManagerEx.getApplicationEx();
+        try {
+          logMessage(0, "Starting app... ");
+          application.doNotSave();
+          application.load(PathManager.getOptionsPath());
+          logMessageLn(0, "done");
+
+          GenerateAntApplication.this.run();
+        }
+        catch (Exception e) {
+          GenerateAntApplication.LOG.error(e);
+        }
+        finally {
+          application.exit(true);
+        }
+      }
+    });
+  }
+
+  public void run() {
+    try {
+      myProjectPath = myProjectPath.replace(File.separatorChar, '/');
+      VirtualFile vfsProject = LocalFileSystem.getInstance().findFileByPath(myProjectPath);
+      if (vfsProject == null) {
+        logError(InspectionsBundle.message("inspection.application.file.cannot.be.found", myProjectPath));
+        GenerateAntMain.printHelp();
+      }
+
+      logMessage(0, "Loading project...");
+      myProject = ProjectManagerEx.getInstanceEx().loadProject(myProjectPath);
+
+      DirectoryIndexImpl dirIndex = (DirectoryIndexImpl)DirectoryIndex.getInstance(myProject);
+      dirIndex.initialize();
+
+      logMessageLn(0, " done");
+
+      GenerateAntBuildAction.generateSingleFileBuild(myProject,
+                                                     new GenerationOptionsImpl(myProject, true, true, false, false, new String[] {}),
+                                                     new File("/Users/max/build/build.xml"),
+                                                     new File("/Users/max/build/build.properties"));
+
+      logMessage(0, "Hello!");
+    }
+    catch (IOException e) {
+      GenerateAntApplication.LOG.error(e);
+      GenerateAntMain.printHelp();
+    }
+    catch (Exception e) {
+      GenerateAntApplication.LOG.error(e);
+      System.exit(1);
+    }
+  }
+
+  public void setVerboseLevel(int verboseLevel) {
+    myVerboseLevel = verboseLevel;
+  }
+
+  private void logMessage(int minVerboseLevel, String message) {
+    if (myVerboseLevel >= minVerboseLevel) {
+      System.out.print(message);
+    }
+  }
+
+  private void logError(String message) {
+    System.err.println(message);
+  }
+
+  private void logMessageLn(int minVerboseLevel, String message) {
+    if (myVerboseLevel >= minVerboseLevel) {
+      System.out.println(message);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntMain.java b/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntMain.java
new file mode 100644
index 0000000..b705a97
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/GenerateAntMain.java
@@ -0,0 +1,48 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.application.ApplicationStarter;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author max
+ */
+public class GenerateAntMain implements ApplicationStarter {
+  private GenerateAntApplication myApplication;
+
+  @NonNls
+  public String getCommandName() {
+    return "ant";
+  }
+
+  public void premain(String[] args) {
+    System.setProperty("idea.load.plugins", "false");
+    myApplication = new GenerateAntApplication();
+
+    myApplication.myProjectPath = args[1];
+    myApplication.myOutPath = args[2];    
+  }
+
+  public void main(String[] args) {
+    myApplication.startup();
+  }
+
+  public static void printHelp() {
+    System.out.println("Wrong params");
+    System.exit(1);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/GenerationOptionsImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/GenerationOptionsImpl.java
new file mode 100644
index 0000000..61158d5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/GenerationOptionsImpl.java
@@ -0,0 +1,326 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.application.options.ReplacePathToMacroMap;
+import com.intellij.compiler.ModuleCompilerUtil;
+import com.intellij.openapi.application.PathMacros;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.util.Chunk;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.graph.CachingSemiGraph;
+import com.intellij.util.graph.Graph;
+import com.intellij.util.graph.GraphGenerator;
+
+import javax.naming.OperationNotSupportedException;
+import java.io.File;
+import java.util.*;
+
+/**
+ * Implementation class for Ant generation options
+ *
+ * @author Eugene Zhuravlev
+ *         Date: Mar 25, 2004
+ */
+public class GenerationOptionsImpl extends GenerationOptions {
+
+  /**
+   * from absolute path to macro substitutions
+   */
+  private final ReplacePathToMacroMap myMacroReplacementMap;
+  /**
+   * from absolute path to macro substitutions
+   */
+  private final Map<String, String> myOutputUrlToPropertyRefMap;
+  /**
+   * module chunks
+   */
+  private final ModuleChunk[] myModuleChunks;
+  /**
+   * the project to be converted
+   */
+  private final Project myProject;
+  private final boolean myGenerateIdeaHomeProperty;
+  private final String myOutputFileName;
+  private Set<String> myJdkUrls;
+  /**
+   * Custom compilers used in the ant build.
+   */
+  private final Set<ChunkCustomCompilerExtension> myCustomCompilers = new HashSet<ChunkCustomCompilerExtension>();
+  /**
+   * map from modules to chunks
+   */
+  private final Map<Module, ModuleChunk> myModuleToChunkMap = new HashMap<Module, ModuleChunk>();
+
+  /**
+   * A constructor
+   *
+   * @param project                        a project to generate
+   * @param generateSingleFile             a value of corresponding option
+   * @param enableFormCompiler             a value of corresponding option
+   * @param backupPreviouslyGeneratedFiles a value of corresponding option
+   * @param forceTargetJdk                 a value of corresponding option
+   * @param inlineRuntimeClasspath         if true a runtiem classpaths are inlined
+   * @param representativeModuleNames      a module name that represents module chunks.
+   * @param outputFileName                 a name for the output file
+   */
+  public GenerationOptionsImpl(Project project,
+                               boolean generateSingleFile,
+                               boolean enableFormCompiler,
+                               boolean backupPreviouslyGeneratedFiles,
+                               boolean forceTargetJdk,
+                               boolean inlineRuntimeClasspath,
+                               boolean generateIdeaHomeProperty,
+                               String[] representativeModuleNames, String outputFileName) {
+    super(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, inlineRuntimeClasspath);
+    myProject = project;
+    myGenerateIdeaHomeProperty = generateIdeaHomeProperty;
+    myOutputFileName = outputFileName;
+    myMacroReplacementMap = createReplacementMap();
+    myModuleChunks = createModuleChunks(representativeModuleNames);
+    myOutputUrlToPropertyRefMap = createOutputUrlToPropertyRefMap(myModuleChunks);
+  }
+
+  /**
+   * A constructor
+   *
+   * @param project                        a project to generate
+   * @param forceTargetJdk                 a value of corresponding option
+   * @param generateSingleFile             a value of corresponding option
+   * @param enableFormCompiler             a value of corresponding option
+   * @param backupPreviouslyGeneratedFiles a value of corresponding option
+   * @param representativeModuleNames      a module name that represents module chunks.
+   */
+  @Deprecated
+  public GenerationOptionsImpl(Project project,
+                               boolean generateSingleFile,
+                               boolean enableFormCompiler,
+                               boolean backupPreviouslyGeneratedFiles,
+                               boolean forceTargetJdk,
+                               String[] representativeModuleNames) {
+    this(project, forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, false, false,
+         representativeModuleNames, null);
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public boolean isIdeaHomeGenerated() {
+    return myGenerateIdeaHomeProperty;
+  }
+
+  public String getBuildFileName() {
+    return getOutputFileName() + ".xml";
+  }
+
+  public String getPropertiesFileName() {
+    return getOutputFileName() + ".properties";
+  }
+
+  private String getOutputFileName() {
+    if (myOutputFileName == null || myOutputFileName.length() == 0) {
+      return BuildProperties.getProjectBuildFileName(myProject);
+    }
+    return myOutputFileName;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  @Override
+  public ModuleChunk getChunkByModule(final Module module) {
+    if (myModuleToChunkMap.isEmpty()) {
+      for (ModuleChunk c : myModuleChunks) {
+        for (Module m : c.getModules()) {
+          myModuleToChunkMap.put(m, c);
+        }
+      }
+    }
+    return myModuleToChunkMap.get(module);
+  }
+
+  @Override
+  public String subsitutePathWithMacros(String path) {
+    return myMacroReplacementMap.substitute(path, SystemInfo.isFileSystemCaseSensitive);
+  }
+
+  public String getPropertyRefForUrl(String url) {
+    return myOutputUrlToPropertyRefMap.get(url);
+  }
+
+  private static ReplacePathToMacroMap createReplacementMap() {
+    final PathMacros pathMacros = PathMacros.getInstance();
+    final Set<String> macroNames = pathMacros.getUserMacroNames();
+    final ReplacePathToMacroMap map = new ReplacePathToMacroMap();
+    for (final String macroName : macroNames) {
+      map.put(GenerationUtils.normalizePath(pathMacros.getValue(macroName)),
+              BuildProperties.propertyRef(BuildProperties.getPathMacroProperty(macroName)));
+    }
+    map.put(GenerationUtils.normalizePath(PathManager.getHomePath()), BuildProperties.propertyRef(BuildProperties.PROPERTY_IDEA_HOME));
+    return map;
+  }
+
+  private static Map<String, String> createOutputUrlToPropertyRefMap(ModuleChunk[] chunks) {
+    final Map<String, String> map = new HashMap<String, String>();
+
+    for (final ModuleChunk chunk : chunks) {
+      final String outputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathProperty(chunk.getName()));
+      final String testsOutputPathRef = BuildProperties.propertyRef(BuildProperties.getOutputPathForTestsProperty(chunk.getName()));
+
+      final Module[] modules = chunk.getModules();
+      for (final Module module : modules) {
+        final String outputPathUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrl();
+        if (outputPathUrl != null) {
+          map.put(outputPathUrl, outputPathRef);
+        }
+        final String outputPathForTestsUrl = CompilerModuleExtension.getInstance(module).getCompilerOutputUrlForTests();
+        if (outputPathForTestsUrl != null) {
+          if (outputPathUrl == null || !outputPathForTestsUrl.equals(outputPathUrl)) {
+            map.put(outputPathForTestsUrl, testsOutputPathRef);
+          }
+        }
+      }
+    }
+    return map;
+  }
+
+  @Override
+  public ModuleChunk[] getModuleChunks() {
+    return myModuleChunks;
+  }
+
+  private ModuleChunk[] createModuleChunks(String[] representativeModuleNames) {
+    final Set<String> mainModuleNames = new HashSet<String>(Arrays.asList(representativeModuleNames));
+    final Graph<Chunk<Module>> chunkGraph = ModuleCompilerUtil.toChunkGraph(ModuleManager.getInstance(myProject).moduleGraph());
+    final Map<Chunk<Module>, ModuleChunk> map = new HashMap<Chunk<Module>, ModuleChunk>();
+    final Map<ModuleChunk, Chunk<Module>> reverseMap = new HashMap<ModuleChunk, Chunk<Module>>();
+    for (final Chunk<Module> chunk : chunkGraph.getNodes()) {
+      final Set<Module> modules = chunk.getNodes();
+      final ModuleChunk moduleChunk = new ModuleChunk(modules.toArray(new Module[modules.size()]));
+      for (final Module module : modules) {
+        if (mainModuleNames.contains(module.getName())) {
+          moduleChunk.setMainModule(module);
+          break;
+        }
+      }
+      map.put(chunk, moduleChunk);
+      reverseMap.put(moduleChunk, chunk);
+    }
+
+    final Graph<ModuleChunk> moduleChunkGraph =
+      GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<ModuleChunk>() {
+        public Collection<ModuleChunk> getNodes() {
+          return map.values();
+        }
+
+        public Iterator<ModuleChunk> getIn(ModuleChunk n) {
+          final Chunk<Module> chunk = reverseMap.get(n);
+          final Iterator<Chunk<Module>> in = chunkGraph.getIn(chunk);
+          return new Iterator<ModuleChunk>() {
+            public boolean hasNext() {
+              return in.hasNext();
+            }
+
+            public ModuleChunk next() {
+              return map.get(in.next());
+            }
+
+            public void remove() {
+              new OperationNotSupportedException();
+            }
+          };
+        }
+      }));
+    final Collection<ModuleChunk> nodes = moduleChunkGraph.getNodes();
+    final ModuleChunk[] moduleChunks = nodes.toArray(new ModuleChunk[nodes.size()]);
+    for (ModuleChunk moduleChunk : moduleChunks) {
+      final Iterator<ModuleChunk> depsIterator = moduleChunkGraph.getIn(moduleChunk);
+      List<ModuleChunk> deps = new ArrayList<ModuleChunk>();
+      while (depsIterator.hasNext()) {
+        deps.add(depsIterator.next());
+      }
+      moduleChunk.setDependentChunks(deps.toArray(new ModuleChunk[deps.size()]));
+      ContainerUtil.addAll(myCustomCompilers, moduleChunk.getCustomCompilers());
+    }
+    Arrays.sort(moduleChunks, new ChunksComparator());
+    if (generateSingleFile) {
+      final File baseDir = BuildProperties.getProjectBaseDir(myProject);
+      for (ModuleChunk chunk : moduleChunks) {
+        chunk.setBaseDir(baseDir);
+      }
+    }
+    return moduleChunks;
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public ChunkCustomCompilerExtension[] getCustomCompilers() {
+    ChunkCustomCompilerExtension[] sorted = myCustomCompilers.toArray(new ChunkCustomCompilerExtension[myCustomCompilers.size()]);
+    Arrays.sort(sorted, ChunkCustomCompilerExtension.COMPARATOR);
+    return sorted;
+  }
+
+  Set<String> getAllJdkUrls() {
+    if (myJdkUrls != null) {
+      return myJdkUrls;
+    }
+    final Sdk[] projectJdks = ProjectJdkTable.getInstance().getAllJdks();
+    myJdkUrls = new HashSet<String>();
+    for (Sdk jdk : projectJdks) {
+      ContainerUtil.addAll(myJdkUrls, jdk.getRootProvider().getUrls(OrderRootType.CLASSES));
+    }
+    return myJdkUrls;
+  }
+
+  private static class ChunksComparator implements Comparator<ModuleChunk> {
+    final Map<ModuleChunk, Integer> myCachedLevels = new HashMap<ModuleChunk, Integer>();
+
+    public int compare(final ModuleChunk o1, final ModuleChunk o2) {
+      final int level1 = getChunkLevel(o1);
+      final int level2 = getChunkLevel(o2);
+      return (level1 == level2) ? o1.getName().compareToIgnoreCase(o2.getName()) : (level1 - level2);
+    }
+
+    private int getChunkLevel(ModuleChunk chunk) {
+      Integer level = myCachedLevels.get(chunk);
+      if (level == null) {
+        final ModuleChunk[] chunks = chunk.getDependentChunks();
+        if (chunks.length > 0) {
+          int maxLevel = 0;
+          for (ModuleChunk dependent : chunks) {
+            maxLevel = Math.max(maxLevel, getChunkLevel(dependent));
+          }
+          level = 1 + maxLevel;
+        }
+        else {
+          level = 0;
+        }
+        myCachedLevels.put(chunk, level);
+      }
+      return level.intValue();
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/IgnoredFiles.java b/java/compiler/impl/src/com/intellij/compiler/ant/IgnoredFiles.java
new file mode 100644
index 0000000..069ee94
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/IgnoredFiles.java
@@ -0,0 +1,47 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Exclude;
+import com.intellij.compiler.ant.taskdefs.PatternSet;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.StringTokenizer;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class IgnoredFiles extends Generator{
+  private final PatternSet myPatternSet;
+
+  public IgnoredFiles() {
+    myPatternSet = new PatternSet(BuildProperties.PROPERTY_IGNORED_FILES);
+    final StringTokenizer tokenizer = new StringTokenizer(FileTypeManager.getInstance().getIgnoredFilesList(), ";", false);
+    while(tokenizer.hasMoreTokens()) {
+      final String filemask = tokenizer.nextToken();
+      myPatternSet.add(new Exclude("**/" + filemask + "/**"));
+    }
+  }
+
+
+
+  public void generate(PrintWriter out) throws IOException {
+    myPatternSet.generate(out);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java
new file mode 100644
index 0000000..5565f21
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryDefinitionsGeneratorFactory.java
@@ -0,0 +1,181 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.FileSet;
+import com.intellij.compiler.ant.taskdefs.Path;
+import com.intellij.compiler.ant.taskdefs.PathElement;
+import com.intellij.compiler.ant.taskdefs.PatternSetRef;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.ex.ProjectEx;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Nov 25, 2004
+ */
+public class LibraryDefinitionsGeneratorFactory {
+  private final ProjectEx myProject;
+  private final GenerationOptions myGenOptions;
+  private final Set<String> myUsedLibraries = new HashSet<String>();
+
+  public LibraryDefinitionsGeneratorFactory(ProjectEx project, GenerationOptions genOptions) {
+    myProject = project;
+    myGenOptions = genOptions;
+    final ModuleManager moduleManager = ModuleManager.getInstance(project);
+    final Module[] modules = moduleManager.getModules();
+    for (Module module : modules) {
+      ModuleRootManager.getInstance(module).orderEntries().forEachLibrary(new Processor<Library>() {
+        @Override
+        public boolean process(Library library) {
+          final String name = library.getName();
+          if (name != null) {
+            myUsedLibraries.add(name);
+          }
+          return true;
+        }
+      });
+    }
+  }
+
+  /**
+   * Create a generator for the specified libary type. It generates a list of library definitions.
+   *
+   * @param libraryTable a library table to examine
+   * @param baseDir      base directory for ant build script
+   * @param comment      a comment to use for the library
+   * @return the created generator or null if there is a nothing to generate
+   */
+  @Nullable
+  public Generator create(LibraryTable libraryTable, File baseDir, final String comment) {
+    final Library[] libraries = libraryTable.getLibraries();
+    if (libraries.length == 0) {
+      return null;
+    }
+
+    final CompositeGenerator gen = new CompositeGenerator();
+
+    gen.add(new Comment(comment), 1);
+    // sort libraries to ensure stable order of them.
+    TreeMap<String, Library> sortedLibs = new TreeMap<String, Library>();
+    for (final Library library : libraries) {
+      final String libraryName = library.getName();
+      if (!myUsedLibraries.contains(libraryName)) {
+        continue;
+      }
+      sortedLibs.put(BuildProperties.getLibraryPathId(libraryName), library);
+    }
+    for (final Library library : sortedLibs.values()) {
+      final String libraryName = library.getName();
+      final Path libraryPath = new Path(BuildProperties.getLibraryPathId(libraryName));
+      genLibraryContent(myProject, myGenOptions, library, baseDir, libraryPath);
+      gen.add(libraryPath, 1);
+    }
+    return gen.getGeneratorCount() > 0 ? gen : null;
+  }
+
+  /**
+   * Generate library content
+   *
+   * @param project     the context project
+   * @param genOptions  the generation options
+   * @param library     the library which content is generated
+   * @param baseDir     the base directory
+   * @param libraryPath the composite generator to update
+   */
+  public static void genLibraryContent(final ProjectEx project,
+                                       final GenerationOptions genOptions,
+                                       final Library library,
+                                       final File baseDir,
+                                       final CompositeGenerator libraryPath) {
+    genLibraryContent(genOptions, library, OrderRootType.CLASSES, baseDir, libraryPath);
+  }
+
+  public static void genLibraryContent(final GenerationOptions genOptions,
+                                       final Library library,
+                                       final OrderRootType rootType, final File baseDir,
+                                       final CompositeGenerator libraryPath) {
+    if (genOptions.expandJarDirectories) {
+      final VirtualFile[] files = library.getFiles(rootType);
+      // note that it is assumed that directory entries inside library path are unordered
+      TreeSet<String> visitedPaths = new TreeSet<String>();
+      for (final VirtualFile file : files) {
+        final String path = GenerationUtils
+          .toRelativePath(file, baseDir, BuildProperties.getProjectBaseDirProperty(), genOptions);
+        visitedPaths.add(path);
+      }
+      for (final String path : visitedPaths) {
+        libraryPath.add(new PathElement(path));
+      }
+    }
+    else {
+      TreeSet<String> urls = new TreeSet<String>(Arrays.asList(library.getUrls(rootType)));
+      for (String url : urls) {
+        File file = fileFromUrl(url);
+        final String path = GenerationUtils
+          .toRelativePath(file.getPath(), baseDir, BuildProperties.getProjectBaseDirProperty(), genOptions);
+        if (url.startsWith(JarFileSystem.PROTOCOL_PREFIX)) {
+          libraryPath.add(new PathElement(path));
+        }
+        else if (url.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) {
+          if (library.isJarDirectory(url, rootType)) {
+            final FileSet fileSet = new FileSet(path);
+            fileSet.add(new PatternSetRef(BuildProperties.PROPERTY_LIBRARIES_PATTERNS));
+            libraryPath.add(fileSet);
+          }
+          else {
+            libraryPath.add(new PathElement(path));
+          }
+        }
+        else {
+          throw new IllegalStateException("Unknown url type: " + url);
+        }
+      }
+    }
+  }
+
+  /**
+   * Gets file from jar of file URL
+   *
+   * @param url an url to parse
+   * @return
+   */
+  private static File fileFromUrl(String url) {
+    final String filePart;
+    if (url.startsWith(JarFileSystem.PROTOCOL_PREFIX) && url.endsWith(JarFileSystem.JAR_SEPARATOR)) {
+      filePart = url.substring(JarFileSystem.PROTOCOL_PREFIX.length(), url.length() - JarFileSystem.JAR_SEPARATOR.length());
+    }
+    else if (url.startsWith(LocalFileSystem.PROTOCOL_PREFIX)) {
+      filePart = url.substring(JarFileSystem.PROTOCOL_PREFIX.length());
+    }
+    else {
+      throw new IllegalArgumentException("Unknown url type: " + url);
+    }
+    return new File(filePart.replace('/', File.separatorChar));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/LibraryPatterns.java b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryPatterns.java
new file mode 100644
index 0000000..ee6ada4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/LibraryPatterns.java
@@ -0,0 +1,65 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Include;
+import com.intellij.compiler.ant.taskdefs.PatternSet;
+import com.intellij.openapi.fileTypes.*;
+import com.intellij.openapi.project.Project;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * Library pattern generation (based on {@link FileTypes#ARCHIVE} file type).
+ */
+public class LibraryPatterns extends Generator {
+  /**
+   * A pattern set to use
+   */
+  private final PatternSet myPatternSet;
+
+  /**
+   * A constructor
+   *
+   * @param project    a context project
+   * @param genOptions a generation options
+   */
+  public LibraryPatterns(Project project, GenerationOptions genOptions) {
+    myPatternSet = new PatternSet(BuildProperties.PROPERTY_LIBRARIES_PATTERNS);
+    final FileType type = FileTypes.ARCHIVE;
+    final List<FileNameMatcher> matchers = FileTypeManager.getInstance().getAssociations(type);
+    for (FileNameMatcher m : matchers) {
+      if (m instanceof ExactFileNameMatcher) {
+        final String path = GenerationUtils
+          .toRelativePath(m.getPresentableString(), BuildProperties.getProjectBaseDir(project), BuildProperties.getProjectBaseDirProperty(),
+                          genOptions);
+        myPatternSet.add(new Include(path));
+      }
+      else {
+        myPatternSet.add(new Include(m.getPresentableString()));
+      }
+    }
+  }
+
+  /**
+   * {@inheritDoc}
+   */
+  public void generate(final PrintWriter out) throws IOException {
+    myPatternSet.generate(out);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkAntProject.java b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkAntProject.java
new file mode 100644
index 0000000..8408931
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkAntProject.java
@@ -0,0 +1,45 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.AntProject;
+import com.intellij.compiler.ant.taskdefs.Dirname;
+import com.intellij.openapi.project.Project;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+public class ModuleChunkAntProject extends Generator{
+  private final AntProject myAntProject;
+
+  public ModuleChunkAntProject(Project project, ModuleChunk moduleChunk, GenerationOptions genOptions) {
+    myAntProject = new AntProject(BuildProperties.getModuleChunkBuildFileName(moduleChunk), BuildProperties.getCompileTargetName(moduleChunk.getName()));
+    myAntProject.add(new Dirname(BuildProperties.getModuleChunkBasedirProperty(moduleChunk), BuildProperties.propertyRef("ant.file." + BuildProperties.getModuleChunkBuildFileName(moduleChunk))));
+    myAntProject.add(new ChunkBuild(project, moduleChunk, genOptions));
+
+  }
+
+  public void generate(PrintWriter out) throws IOException {
+    writeXmlHeader(out);
+    myAntProject.generate(out);
+  }
+
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
new file mode 100644
index 0000000..0883913
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkClasspath.java
@@ -0,0 +1,364 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Path;
+import com.intellij.compiler.ant.taskdefs.PathElement;
+import com.intellij.compiler.ant.taskdefs.PathRef;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.ex.ProjectEx;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.OrderedSet;
+
+import java.io.File;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * Generator of module chunk classspath. The class used to generate both runtime and compile time classpaths.
+ *
+ * @author Eugene Zhuravlev
+ */
+public class ModuleChunkClasspath extends Path {
+
+  /**
+   * A constructor
+   *
+   * @param chunk                    a chunk to process
+   * @param genOptions               a generation options
+   * @param generateRuntimeClasspath if true, runtime classpath is being generated. Otherwise a compile time classpath is constructed
+   * @param generateTestClasspath    if true, a test classpath is generated.
+   */
+  @SuppressWarnings({"unchecked"})
+  public ModuleChunkClasspath(final ModuleChunk chunk,
+                              final GenerationOptions genOptions,
+                              final boolean generateRuntimeClasspath,
+                              final boolean generateTestClasspath) {
+    super(generateClasspathName(chunk, generateRuntimeClasspath, generateTestClasspath));
+
+    final OrderedSet<ClasspathItem> pathItems =
+      new OrderedSet<ClasspathItem>();
+    final String moduleChunkBasedirProperty = BuildProperties.getModuleChunkBasedirProperty(chunk);
+    final Module[] modules = chunk.getModules();
+    // processed chunks (used only in runtime classpath), every chunk is referenced exactly once
+    final Set<ModuleChunk> processedChunks = new HashSet<ModuleChunk>();
+    // pocessed modules
+    final Set<Module> processedModules = new HashSet<Module>();
+    for (final Module module : modules) {
+      new Object() {
+        /**
+         * Process the module. The logic is different for compile-time case and runtime case.
+         * In the case of runtime, only directly referenced objects are included in classpath.
+         * Indirectly referenced are
+         *
+         * @param module a module to process.
+         * @param dependencyLevel is increased with every of recursion.
+         * @param isModuleExported if true the module is exported from the previous level
+         */
+        public void processModule(final Module module, final int dependencyLevel, final boolean isModuleExported) {
+          if (processedModules.contains(module)) {
+            // the module is already processed, nothing should be done
+            return;
+          }
+          if (dependencyLevel > 1 && !isModuleExported && !(genOptions.inlineRuntimeClasspath && generateRuntimeClasspath)) {
+            // the module is not in exports and it is not directly included skip it in the case of library pathgeneration
+            return;
+          }
+          processedModules.add(module);
+          final ProjectEx project = (ProjectEx)chunk.getProject();
+          final File baseDir = BuildProperties.getProjectBaseDir(project);
+          OrderEnumerator enumerator = ModuleRootManager.getInstance(module).orderEntries();
+          if (generateRuntimeClasspath) {
+            enumerator = enumerator.runtimeOnly();
+          }
+          else {
+            enumerator = enumerator.compileOnly();
+            if (!generateTestClasspath && (dependencyLevel == 0 || chunk.contains(module))) {
+              // this is the entry for outpath of the currently processed module
+              // the root module is never included
+              enumerator = enumerator.withoutModuleSourceEntries();
+            }
+          }
+          if (!generateTestClasspath) {
+            enumerator = enumerator.productionOnly();
+          }
+          enumerator.forEach(new Processor<OrderEntry>() {
+            @Override
+            public boolean process(OrderEntry orderEntry) {
+              if (!orderEntry.isValid()) {
+                return true;
+              }
+
+              if (!generateRuntimeClasspath &&
+                  !(orderEntry instanceof ModuleOrderEntry) &&
+                  !(orderEntry instanceof ModuleSourceOrderEntry)) {
+                // needed for compilation classpath only
+                final boolean isExported = (orderEntry instanceof ExportableOrderEntry) && ((ExportableOrderEntry)orderEntry).isExported();
+                if (dependencyLevel > 0 && !isExported) {
+                  // non-exported dependencies are excluded and not processed
+                  return true;
+                }
+              }
+
+              if (orderEntry instanceof JdkOrderEntry) {
+                if (genOptions.forceTargetJdk && !generateRuntimeClasspath) {
+                  pathItems
+                    .add(new PathRefItem(BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkClasspathProperty(chunk.getName()))));
+                }
+              }
+              else if (orderEntry instanceof ModuleOrderEntry) {
+                final ModuleOrderEntry moduleOrderEntry = (ModuleOrderEntry)orderEntry;
+                final Module dependentModule = moduleOrderEntry.getModule();
+                if (!chunk.contains(dependentModule)) {
+                  if (generateRuntimeClasspath && !genOptions.inlineRuntimeClasspath) {
+                    // in case of runtime classpath, just an referenced to corresponding classpath is created
+                    final ModuleChunk depChunk = genOptions.getChunkByModule(dependentModule);
+                    if (!processedChunks.contains(depChunk)) {
+                      // chunk references are included in the runtime classpath only once
+                      processedChunks.add(depChunk);
+                      String property = generateTestClasspath ? BuildProperties.getTestRuntimeClasspathProperty(depChunk.getName())
+                                                              : BuildProperties.getRuntimeClasspathProperty(depChunk.getName());
+                      pathItems.add(new PathRefItem(property));
+                    }
+                  }
+                  else {
+                    // in case of compile classpath or inlined runtime classpath,
+                    // the referenced module is processed recursively
+                    processModule(dependentModule, dependencyLevel + 1, moduleOrderEntry.isExported());
+                  }
+                }
+              }
+              else if (orderEntry instanceof LibraryOrderEntry) {
+                final LibraryOrderEntry libraryOrderEntry = (LibraryOrderEntry)orderEntry;
+                final String libraryName = libraryOrderEntry.getLibraryName();
+                if (((LibraryOrderEntry)orderEntry).isModuleLevel()) {
+                  CompositeGenerator gen = new CompositeGenerator();
+                  gen.setHasLeadingNewline(false);
+                  LibraryDefinitionsGeneratorFactory.genLibraryContent(project, genOptions, libraryOrderEntry.getLibrary(), baseDir, gen);
+                  pathItems.add(new GeneratorItem(libraryName, gen));
+                }
+                else {
+                  pathItems.add(new PathRefItem(BuildProperties.getLibraryPathId(libraryName)));
+                }
+              }
+              else if (orderEntry instanceof ModuleSourceOrderEntry) {
+                // Module source entry?
+                for (String url : getCompilationClasses(module, ((GenerationOptionsImpl)genOptions), generateRuntimeClasspath,
+                                                        generateTestClasspath, dependencyLevel == 0)) {
+                  if (url.endsWith(JarFileSystem.JAR_SEPARATOR)) {
+                    url = url.substring(0, url.length() - JarFileSystem.JAR_SEPARATOR.length());
+                  }
+                  final String propertyRef = genOptions.getPropertyRefForUrl(url);
+                  if (propertyRef != null) {
+                    pathItems.add(new PathElementItem(propertyRef));
+                  }
+                  else {
+                    final String path = VirtualFileManager.extractPath(url);
+                    pathItems.add(new PathElementItem(
+                      GenerationUtils.toRelativePath(path, chunk.getBaseDir(), moduleChunkBasedirProperty, genOptions)));
+                  }
+                }
+              }
+              else {
+                // Unknown order entry type. If it is actually encountered, extension point should be implemented
+                pathItems.add(new GeneratorItem(orderEntry.getClass().getName(),
+                                                new Comment("Unknown OrderEntryType: " + orderEntry.getClass().getName())));
+              }
+              return true;
+            }
+          });
+        }
+      }.processModule(module, 0, false);
+    }
+    // convert path items to generators
+    for (final ClasspathItem pathItem : pathItems) {
+      add(pathItem.toGenerator());
+    }
+  }
+
+  /**
+   * Generate classpath name
+   *
+   * @param chunk                    a chunk
+   * @param generateRuntimeClasspath
+   * @param generateTestClasspath
+   * @return a name for the classpath
+   */
+  private static String generateClasspathName(ModuleChunk chunk, boolean generateRuntimeClasspath, boolean generateTestClasspath) {
+    if (generateTestClasspath) {
+      return generateRuntimeClasspath
+             ? BuildProperties.getTestRuntimeClasspathProperty(chunk.getName())
+             : BuildProperties.getTestClasspathProperty(chunk.getName());
+    }
+    else {
+      return generateRuntimeClasspath
+             ? BuildProperties.getRuntimeClasspathProperty(chunk.getName())
+             : BuildProperties.getClasspathProperty(chunk.getName());
+    }
+  }
+
+  private static String[] getCompilationClasses(final Module module,
+                                                final GenerationOptionsImpl options,
+                                                final boolean forRuntime,
+                                                final boolean forTest,
+                                                final boolean firstLevel) {
+    final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+    if (extension == null) return ArrayUtil.EMPTY_STRING_ARRAY;
+
+    if (!forRuntime) {
+      if (forTest) {
+        return extension.getOutputRootUrls(!firstLevel);
+      }
+      else {
+        return firstLevel ? ArrayUtil.EMPTY_STRING_ARRAY : extension.getOutputRootUrls(false);
+      }
+    }
+    final Set<String> jdkUrls = options.getAllJdkUrls();
+
+    final OrderedSet<String> urls = new OrderedSet<String>();
+    ContainerUtil.addAll(urls, extension.getOutputRootUrls(forTest));
+    urls.removeAll(jdkUrls);
+    return ArrayUtil.toStringArray(urls);
+  }
+
+  /**
+   * The base class for an item in the class path. Instances of the subclasses are used instead
+   * of generators when building the class path content. The subclasses implement {@link Object#equals(Object)}
+   * and {@link Object#hashCode()} methods in order to eliminate duplicates when building classpath.
+   */
+  private abstract static class ClasspathItem {
+    /**
+     * primary reference or path of the element
+     */
+    protected final String myValue;
+
+    /**
+     * A constructor
+     *
+     * @param value primary value of the element
+     */
+    public ClasspathItem(String value) {
+      myValue = value;
+    }
+
+    /**
+     * @return a generator for path elements.
+     */
+    public abstract Generator toGenerator();
+  }
+
+  /**
+   * Class path item that directly embeds generator
+   */
+  private static class GeneratorItem extends ClasspathItem {
+    /**
+     * An embedded generator
+     */
+    final Generator myGenerator;
+
+    /**
+     * A constructor
+     *
+     * @param value     primary value of the element
+     * @param generator a generator to use
+     */
+    public GeneratorItem(String value, final Generator generator) {
+      super(value);
+      myGenerator = generator;
+    }
+
+    public Generator toGenerator() {
+      return myGenerator;
+    }
+  }
+
+  /**
+   * This path element directly references some location.
+   */
+  private static class PathElementItem extends ClasspathItem {
+    /**
+     * A constructor
+     *
+     * @param value a referenced location
+     */
+    public PathElementItem(String value) {
+      super(value);
+    }
+
+    @Override
+    public Generator toGenerator() {
+      return new PathElement(myValue);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (!(o instanceof PathElementItem)) return false;
+
+      final PathElementItem pathElementItem = (PathElementItem)o;
+
+      if (!myValue.equals(pathElementItem.myValue)) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return myValue.hashCode();
+    }
+  }
+
+  /**
+   * This path element references a path
+   */
+  private static class PathRefItem extends ClasspathItem {
+    /**
+     * A constructor
+     *
+     * @param value an indentifier of referenced classpath
+     */
+    public PathRefItem(String value) {
+      super(value);
+    }
+
+    @Override
+    public Generator toGenerator() {
+      return new PathRef(myValue);
+    }
+
+    @Override
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (!(o instanceof PathRefItem)) return false;
+
+      final PathRefItem pathRefItem = (PathRefItem)o;
+
+      if (!myValue.equals(pathRefItem.myValue)) return false;
+
+      return true;
+    }
+
+    @Override
+    public int hashCode() {
+      return myValue.hashCode();
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkSourcePath.java b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkSourcePath.java
new file mode 100644
index 0000000..ebe3f5d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleChunkSourcePath.java
@@ -0,0 +1,183 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.*;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModuleFileIndex;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ * @since Nov 22, 2004
+ */
+public class ModuleChunkSourcePath extends CompositeGenerator{
+  private final VirtualFile[] mySourceRoots;
+  private final VirtualFile[] myTestSourceRoots;
+
+  public ModuleChunkSourcePath(final Project project, ModuleChunk chunk, final GenerationOptions genOptions) {
+    final Path sourcePath = new Path(BuildProperties.getSourcepathProperty(chunk.getName()));
+    final Path testSourcePath = new Path(BuildProperties.getTestSourcepathProperty(chunk.getName()));
+    final PatternSet excludedFromCompilation = new PatternSet(BuildProperties.getExcludedFromCompilationProperty(chunk.getName()));
+    final String moduleChunkBasedirProperty = BuildProperties.getModuleChunkBasedirProperty(chunk);
+    final Module[] modules = chunk.getModules();
+
+    if (CompilerExcludes.isAvailable(project)) {
+      excludedFromCompilation.add(new PatternSetRef(BuildProperties.PROPERTY_COMPILER_EXCLUDES));
+    }
+
+    final List<VirtualFile> sourceRootFiles = new ArrayList<VirtualFile>();
+    final List<VirtualFile> testSourceRootFiles = new ArrayList<VirtualFile>();
+
+    for (final Module module : modules) {
+      final String moduleName = module.getName();
+      final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
+      final ModuleFileIndex moduleFileIndex = rootManager.getFileIndex();
+
+
+      final PatternSet excludedFromModule = new PatternSet(BuildProperties.getExcludedFromModuleProperty(moduleName));
+      excludedFromModule.add(new PatternSetRef(BuildProperties.PROPERTY_IGNORED_FILES));
+
+      final ContentEntry[] contentEntries = rootManager.getContentEntries();
+      for (final ContentEntry contentEntry : contentEntries) {
+        final VirtualFile file = contentEntry.getFile();
+        if (file == null) {
+          continue; // filter invalid entries
+        }
+        if (!file.isInLocalFileSystem()) {
+          continue; // skip content roots inside jar and zip archives
+        }
+        final VirtualFile dirSetRoot = getDirSetRoot(contentEntry);
+
+        final String dirSetRootRelativeToBasedir = GenerationUtils
+          .toRelativePath(dirSetRoot, chunk.getBaseDir(), moduleChunkBasedirProperty, genOptions);
+        final DirSet sourcesDirSet = new DirSet(dirSetRootRelativeToBasedir);
+        final DirSet testSourcesDirSet = new DirSet(dirSetRootRelativeToBasedir);
+
+        final VirtualFile[] sourceRoots = contentEntry.getSourceFolderFiles();
+        for (final VirtualFile root : sourceRoots) {
+          if (!moduleFileIndex.isInContent(root)) {
+            continue; // skip library sources
+          }
+
+          addExcludePatterns(module, root, root, excludedFromModule, true);
+
+          final Include include = new Include(VfsUtilCore.getRelativePath(root, dirSetRoot, '/'));
+          if (moduleFileIndex.isInTestSourceContent(root)) {
+            testSourcesDirSet.add(include);
+            testSourceRootFiles.add(root);
+          }
+          else {
+            sourcesDirSet.add(include);
+            sourceRootFiles.add(root);
+          }
+        }
+        if (sourcesDirSet.getGeneratorCount() > 0) {
+          sourcePath.add(sourcesDirSet);
+        }
+        if (testSourcesDirSet.getGeneratorCount() > 0) {
+          testSourcePath.add(testSourcesDirSet);
+        }
+      }
+
+      if (excludedFromModule.getGeneratorCount() > 0) {
+        add(excludedFromModule);
+        excludedFromCompilation.add(new PatternSetRef(BuildProperties.getExcludedFromModuleProperty(moduleName)));
+      }
+    }
+
+    mySourceRoots = VfsUtilCore.toVirtualFileArray(sourceRootFiles);
+    myTestSourceRoots = VfsUtilCore.toVirtualFileArray(testSourceRootFiles);
+
+    if (excludedFromCompilation.getGeneratorCount() > 0) {
+      add(excludedFromCompilation, 1);
+    }
+    if (sourcePath.getGeneratorCount() > 0) {
+      add(sourcePath, 1);
+    }
+    if (testSourcePath.getGeneratorCount() != 0) {
+      add(testSourcePath, 1);
+    }
+  }
+
+  public VirtualFile[] getSourceRoots() {
+    return mySourceRoots;
+  }
+
+  public VirtualFile[] getTestSourceRoots() {
+    return myTestSourceRoots;
+  }
+
+  private VirtualFile getDirSetRoot(final ContentEntry contentEntry) {
+    final VirtualFile contentRoot = contentEntry.getFile();
+    final VirtualFile[] sourceFolderFiles = contentEntry.getSourceFolderFiles();
+    for (VirtualFile sourceFolderFile : sourceFolderFiles) {
+      if (contentRoot.equals(sourceFolderFile)) {
+        return contentRoot.getParent();
+      }
+    }
+    return contentRoot;
+  }
+
+  private static void addExcludePatterns(Module module,
+                                         final VirtualFile root,
+                                         VirtualFile dir,
+                                         final CompositeGenerator generator,
+                                         final boolean parentIncluded) {
+    final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(module);
+
+    VfsUtilCore.visitChildrenRecursively(dir, new VirtualFileVisitor() {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile dir) {
+        if (!dir.isDirectory() || fileTypeManager.isFileIgnored(dir)) {
+          // ignored files are handled by global 'ignored' pattern set
+          return false;
+        }
+
+        final boolean isIncluded = moduleRootManager.getFileIndex().isInContent(dir);
+        if (isIncluded != parentIncluded) {
+          final String relativePath = VfsUtilCore.getRelativePath(dir, root, '/');
+          if (isIncluded) {
+            generator.add(new Include(relativePath + "/**"));
+          }
+          else {
+            if (!isExcludedByDefault(dir.getName())) {
+              generator.add(new Exclude(relativePath + "/**"));
+            }
+          }
+        }
+
+        return true;
+      }
+    });
+  }
+
+  private static boolean isExcludedByDefault(String name) {
+    //noinspection HardCodedStringLiteral
+    return "CVS".equals(name) || "SCCS".equals(name) || ".DS_Store".equals(name);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ModuleSources.java b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleSources.java
new file mode 100644
index 0000000..d9d6e07
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ModuleSources.java
@@ -0,0 +1,127 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class ModuleSources extends CompositeGenerator{
+  private final VirtualFile[] mySourceRoots = VirtualFile.EMPTY_ARRAY;
+  private final VirtualFile[] myTestSourceRoots = VirtualFile.EMPTY_ARRAY;
+
+  public ModuleSources(Module module, File baseDir, final GenerationOptions genOptions) {
+    /*
+    final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
+    final ModuleFileIndex moduleFileIndex = rootManager.getFileIndex();
+
+    final List<VirtualFile> sourceRootFiles = new ArrayList<VirtualFile>();
+    final List<VirtualFile> testSourceRootFiles = new ArrayList<VirtualFile>();
+
+    final Path sourcepath = new Path(BuildProperties.getSourcepathProperty(module.getName()));
+    final Path testSourcepath = new Path(BuildProperties.getTestSourcepathProperty(module.getName()));
+    final PatternSet excludedFromModule = new PatternSet(BuildProperties.getExcludedFromModuleProperty(module.getName()));
+
+    final ContentEntry[] contentEntries = rootManager.getContentEntries();
+    for (int idx = 0; idx < contentEntries.length; idx++) {
+      final ContentEntry contentEntry = contentEntries[idx];
+      final VirtualFile file = contentEntry.getFile();
+      if (file == null) {
+        continue; // filter invalid entries
+      }
+      if (!(file.getFileSystem() instanceof LocalFileSystem)) {
+        continue; // skip content roots inside jar and zip archives
+      }
+      final VirtualFile dirSetRoot = getDirSetRoot(contentEntry);
+
+      final String dirSetRootRelativeToBasedir = GenerationUtils.toRelativePath(dirSetRoot, baseDir, BuildProperties.getModuleChunkBasedirProperty(module), genOptions, !module.isSavePathsRelative());
+      final DirSet sourcesDirSet = new DirSet(dirSetRootRelativeToBasedir);
+      final DirSet testSourcesDirSet = new DirSet(dirSetRootRelativeToBasedir);
+
+      final VirtualFile[] sourceRoots = contentEntry.getSourceFolderFiles();
+      for (int i = 0; i < sourceRoots.length; i++) {
+        final VirtualFile root = sourceRoots[i];
+        if (!moduleFileIndex.isInContent(root)) {
+          continue; // skip library sources
+        }
+
+        addExcludePatterns(module, root, root, excludedFromModule, true);
+
+        final Include include = new Include(VfsUtil.getRelativePath(root, dirSetRoot, '/'));
+        if (moduleFileIndex.isInTestSourceContent(root)) {
+          testSourcesDirSet.add(include);
+          testSourceRootFiles.add(root);
+        }
+        else {
+          sourcesDirSet.add(include);
+          sourceRootFiles.add(root);
+        }
+      }
+      if (sourcesDirSet.getGeneratorCount() > 0) {
+        sourcepath.add(sourcesDirSet);
+      }
+      if (testSourcesDirSet.getGeneratorCount() > 0) {
+        testSourcepath.add(testSourcesDirSet);
+      }
+    }
+
+    mySourceRoots = sourceRootFiles.toArray(new VirtualFile[sourceRootFiles.size()]);
+    myTestSourceRoots = testSourceRootFiles.toArray(new VirtualFile[testSourceRootFiles.size()]);
+
+    final String moduleName = module.getName();
+
+    add(excludedFromModule);
+
+    final PatternSet excludedFromCompilation = new PatternSet(BuildProperties.getExcludedFromCompilationProperty(moduleName));
+    excludedFromCompilation.add(new PatternSetRef(BuildProperties.getExcludedFromModuleProperty(moduleName)));
+    excludedFromCompilation.add(new PatternSetRef(BuildProperties.PROPERTY_COMPILER_EXCLUDES));
+    add(excludedFromCompilation, 1);
+
+    if (sourcepath.getGeneratorCount() > 0) {
+      add(sourcepath, 1);
+    }
+    if (testSourcepath.getGeneratorCount() != 0) {
+      add(testSourcepath, 1);
+    }
+    */
+  }
+
+  private VirtualFile getDirSetRoot(final ContentEntry contentEntry) {
+    final VirtualFile contentRoot = contentEntry.getFile();
+    final VirtualFile[] sourceFolderFiles = contentEntry.getSourceFolderFiles();
+    for (VirtualFile sourceFolderFile : sourceFolderFiles) {
+      if (contentRoot.equals(sourceFolderFile)) {
+        return contentRoot.getParent();
+      }
+    }
+    return contentRoot;
+  }
+
+  public VirtualFile[] getSourceRoots() {
+    return mySourceRoots;
+  }
+
+  public VirtualFile[] getTestSourceRoots() {
+    return myTestSourceRoots;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/MultipleFileProjectBuild.java b/java/compiler/impl/src/com/intellij/compiler/ant/MultipleFileProjectBuild.java
new file mode 100644
index 0000000..9916ee0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/MultipleFileProjectBuild.java
@@ -0,0 +1,41 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Import;
+import com.intellij.openapi.project.Project;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+public class MultipleFileProjectBuild extends ProjectBuild{
+  public MultipleFileProjectBuild(Project project, GenerationOptions genOptions) {
+    super(project, genOptions);
+  }
+
+  protected Generator createModuleBuildGenerator(ModuleChunk chunk, GenerationOptions genOptions) {
+    //noinspection HardCodedStringLiteral
+    final String chunkBuildFile = BuildProperties.getModuleChunkBaseDir(chunk).getPath() + File.separator + BuildProperties.getModuleChunkBuildFileName(chunk) + ".xml";
+    final File projectBaseDir = BuildProperties.getProjectBaseDir(myProject);
+    final String pathToFile = GenerationUtils.toRelativePath(
+      chunkBuildFile, projectBaseDir, BuildProperties.getProjectBaseDirProperty(), genOptions);
+    return new Import(pathToFile);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/ProjectBuild.java b/java/compiler/impl/src/com/intellij/compiler/ant/ProjectBuild.java
new file mode 100644
index 0000000..7d4c3d9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/ProjectBuild.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.compiler.ant;
+
+import com.intellij.compiler.ant.artifacts.ArtifactsGenerator;
+import com.intellij.compiler.ant.taskdefs.AntProject;
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 24, 2004
+ */
+public abstract class ProjectBuild extends Generator {
+  protected final Project myProject;
+  private final AntProject myAntProject;
+
+  public ProjectBuild(Project project, GenerationOptions genOptions) {
+    myProject = project;
+    myAntProject = new AntProject(BuildProperties.getProjectBuildFileName(myProject), BuildProperties.DEFAULT_TARGET);
+
+    myAntProject.add(new BuildPropertiesImpl(myProject, genOptions), 1);
+
+    // the sequence in which modules are imported is important cause output path properties for dependent modules should be defined first
+
+    final StringBuilder buildModulesTargetNames = new StringBuilder();
+    buildModulesTargetNames.append(BuildProperties.TARGET_INIT);
+    buildModulesTargetNames.append(", ");
+    buildModulesTargetNames.append(BuildProperties.TARGET_CLEAN);
+    final ModuleChunk[] chunks = genOptions.getModuleChunks();
+
+    if (chunks.length > 0) {
+      myAntProject.add(new Comment(CompilerBundle.message("generated.ant.build.modules.section.title")), 1);
+
+      for (final ModuleChunk chunk : chunks) {
+        myAntProject.add(createModuleBuildGenerator(chunk, genOptions), 1);
+        final String[] targets = ChunkBuildExtension.getAllTargets(chunk);
+        for (String target : targets) {
+          if (buildModulesTargetNames.length() > 0) {
+            buildModulesTargetNames.append(", ");
+          }
+          buildModulesTargetNames.append(target);
+        }
+      }
+    }
+    for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) {
+      extension.generateProjectTargets(project, genOptions, myAntProject);
+    }
+
+    final Target initTarget = new Target(BuildProperties.TARGET_INIT, null,
+                                         CompilerBundle.message("generated.ant.build.initialization.section.title"), null);
+    initTarget.add(new Comment(CompilerBundle.message("generated.ant.build.initialization.section.comment")));
+    myAntProject.add(initTarget, 1);
+
+    ArtifactsGenerator artifactsGenerator = new ArtifactsGenerator(project, genOptions);
+
+    myAntProject.add(new CleanProject(project, genOptions, artifactsGenerator), 1);
+
+    myAntProject.add(new Target(BuildProperties.TARGET_BUILD_MODULES, buildModulesTargetNames.toString(),
+                                CompilerBundle.message("generated.ant.build.build.all.modules.target.name"), null), 1);
+    
+    StringBuilder buildAllTargetNames = new StringBuilder();
+    buildAllTargetNames.append(BuildProperties.TARGET_BUILD_MODULES);
+    if (artifactsGenerator.hasArtifacts()) {
+      List<Generator> generators = artifactsGenerator.generate();
+      for (Generator generator : generators) {
+        myAntProject.add(generator, 1);
+      }
+
+      buildAllTargetNames.append(", ").append(ArtifactsGenerator.BUILD_ALL_ARTIFACTS_TARGET);
+    }
+
+    myAntProject.add(new Target(BuildProperties.TARGET_ALL, buildAllTargetNames.toString(),
+                                CompilerBundle.message("generated.ant.build.build.all.target.name"), null), 1);
+  }
+
+  public void generate(PrintWriter out) throws IOException {
+    //noinspection HardCodedStringLiteral
+    writeXmlHeader(out);
+    myAntProject.generate(out);
+  }
+
+  protected abstract Generator createModuleBuildGenerator(final ModuleChunk chunk, GenerationOptions genOptions);
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java
new file mode 100644
index 0000000..ab93b32
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/PropertyFileGeneratorImpl.java
@@ -0,0 +1,101 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.application.PathMacros;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.util.ArrayUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * Generator for property files.
+ *
+ * @author Eugene Zhuravlev
+ *         Date: Nov 27, 2004
+ */
+public class PropertyFileGeneratorImpl extends PropertyFileGenerator {
+    /**
+     * List of the properties
+     */
+    private final List<Pair<String, String>> myProperties = new ArrayList<Pair<String, String>>();
+
+    /**
+     * A constctor that extracts all neeed properties for ant build from the project.
+     *
+     * @param project    a project to examine
+     * @param genOptions generation options
+     */
+    public PropertyFileGeneratorImpl(Project project, GenerationOptions genOptions) {
+        // path variables
+        final PathMacros pathMacros = PathMacros.getInstance();
+        final Set<String> macroNamesSet = pathMacros.getUserMacroNames();
+        if (macroNamesSet.size() > 0) {
+          final String[] macroNames = ArrayUtil.toStringArray(macroNamesSet);
+            Arrays.sort(macroNames);
+            for (final String macroName : macroNames) {
+                addProperty(BuildProperties.getPathMacroProperty(macroName), pathMacros.getValue(macroName));
+            }
+        }
+        // jdk homes
+        if (genOptions.forceTargetJdk) {
+            final Sdk[] usedJdks = BuildProperties.getUsedJdks(project);
+            for (Sdk jdk : usedJdks) {
+                if (jdk.getHomeDirectory() == null) {
+                    continue;
+                }
+                final File homeDir = BuildProperties.toCanonicalFile(VfsUtil.virtualToIoFile(jdk.getHomeDirectory()));
+                addProperty(BuildProperties.getJdkHomeProperty(jdk.getName()), homeDir.getPath().replace(File.separatorChar, '/'));
+            }
+        }
+        // generate idea.home property
+        if (genOptions.isIdeaHomeGenerated()) {
+            addProperty(BuildProperties.PROPERTY_IDEA_HOME, PathManager.getHomePath());
+        }
+        ChunkBuildExtension.generateAllProperties(this, project, genOptions);
+    }
+
+    public void addProperty(String name, String value) {
+        myProperties.add(new Pair<String, String>(name, value));
+    }
+
+    @Override
+    public void generate(PrintWriter out) throws IOException {
+        boolean isFirst = true;
+        for (final Pair<String, String> pair : myProperties) {
+            if (!isFirst) {
+                crlf(out);
+            }
+            else {
+                isFirst = false;
+            }
+            out.print(StringUtil.escapeProperty(pair.getFirst(), true));
+            out.print("=");
+            out.print(StringUtil.escapeProperty(pair.getSecond(), false));
+        }
+    }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/SingleFileProjectBuild.java b/java/compiler/impl/src/com/intellij/compiler/ant/SingleFileProjectBuild.java
new file mode 100644
index 0000000..d084879
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/SingleFileProjectBuild.java
@@ -0,0 +1,39 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Dirname;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.compiler.CompilerBundle;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+public class SingleFileProjectBuild extends ProjectBuild {
+  public SingleFileProjectBuild(Project project, GenerationOptions genOptions) {
+    super(project, genOptions);
+  }
+
+  protected Generator createModuleBuildGenerator(ModuleChunk chunk, GenerationOptions genOptions) {
+    final CompositeGenerator gen = new CompositeGenerator();
+    gen.add(new Comment(CompilerBundle.message("generated.ant.build.building.concrete.module.section.title", chunk.getName())));
+    gen.add(new Dirname(BuildProperties.getModuleChunkBasedirProperty(chunk), BuildProperties.propertyRef("ant.file")), 1);
+    gen.add(new ChunkBuild(myProject, chunk, genOptions), 1);
+    return gen;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArchiveAntCopyInstructionCreator.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArchiveAntCopyInstructionCreator.java
new file mode 100644
index 0000000..4ede60c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArchiveAntCopyInstructionCreator.java
@@ -0,0 +1,59 @@
+/*
+ * 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.compiler.ant.artifacts;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.Tag;
+import com.intellij.compiler.ant.taskdefs.ZipFileSet;
+import com.intellij.packaging.elements.AntCopyInstructionCreator;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArchiveAntCopyInstructionCreator implements AntCopyInstructionCreator {
+  private final String myPrefix;
+
+  public ArchiveAntCopyInstructionCreator(String prefix) {
+    myPrefix = prefix;
+  }
+
+  @NotNull
+  public Tag createDirectoryContentCopyInstruction(@NotNull String dirPath) {
+    return new ZipFileSet(dirPath, myPrefix, true);
+  }
+
+  @NotNull
+  public Tag createFileCopyInstruction(@NotNull String filePath, String outputFileName) {
+    final String relativePath = myPrefix + "/" + outputFileName;
+    return new ZipFileSet(filePath, relativePath, false);
+  }
+
+  @NotNull
+  public AntCopyInstructionCreator subFolder(@NotNull String directoryName) {
+    return new ArchiveAntCopyInstructionCreator(myPrefix + "/" + directoryName);
+  }
+
+  public Generator createSubFolderCommand(@NotNull String directoryName) {
+    return null;
+  }
+
+  @NotNull
+  @Override
+  public Generator createExtractedDirectoryInstruction(@NotNull String jarPath) {
+    return ZipFileSet.createUnpackedSet(jarPath, myPrefix, true);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactAntGenerationContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactAntGenerationContextImpl.java
new file mode 100644
index 0000000..b422760
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactAntGenerationContextImpl.java
@@ -0,0 +1,166 @@
+/*
+ * 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.compiler.ant.artifacts;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.GenerationOptions;
+import com.intellij.compiler.ant.GenerationUtils;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.taskdefs.Mkdir;
+import com.intellij.compiler.ant.taskdefs.Property;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ArtifactAntGenerationContext;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import gnu.trove.THashMap;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactAntGenerationContextImpl implements ArtifactAntGenerationContext {
+  @NonNls public static final String ARTIFACTS_TEMP_DIR_PROPERTY = "artifacts.temp.dir";
+  private final Map<Artifact, String> myArtifact2Target = new THashMap<Artifact, String>();
+  private final List<Generator> myBeforeBuildGenerators = new ArrayList<Generator>();
+  private final List<Generator> myAfterBuildGenerators = new ArrayList<Generator>();
+  private final Set<String> myTempFileNames = new THashSet<String>();
+  private final Set<String> myCreatedTempSubdirs = new THashSet<String>();
+  private final Set<String> myProperties = new LinkedHashSet<String>();
+  private final Project myProject;
+  private final GenerationOptions myGenerationOptions;
+  private final List<Generator> myBeforeCurrentArtifact = new ArrayList<Generator>();
+  private final Set<Artifact> myArtifactsToClean = new THashSet<Artifact>();
+
+  public ArtifactAntGenerationContextImpl(Project project, GenerationOptions generationOptions, List<Artifact> allArtifacts) {
+    myProject = project;
+    myGenerationOptions = generationOptions;
+    for (Artifact artifact : allArtifacts) {
+      if (ArtifactUtil.shouldClearArtifactOutputBeforeRebuild(artifact)) {
+        myArtifactsToClean.add(artifact);
+      }
+    }
+  }
+
+  @Override
+  public Project getProject() {
+    return myProject;
+  }
+
+  @Override
+  public GenerationOptions getGenerationOptions() {
+    return myGenerationOptions;
+  }
+
+  public String getConfiguredArtifactOutputProperty(@NotNull Artifact artifact) {
+    return "artifact.output." + BuildProperties.convertName(artifact.getName());
+  }
+
+  public String getArtifactOutputProperty(@NotNull Artifact artifact) {
+    if (shouldBuildIntoTempDirectory(artifact)) {
+      return "artifact.temp.output." + BuildProperties.convertName(artifact.getName());
+    }
+    return getConfiguredArtifactOutputProperty(artifact);
+  }
+
+  public boolean shouldBuildIntoTempDirectory(@NotNull Artifact artifact) {
+    return !myArtifactsToClean.contains(artifact);
+  }
+
+  public String getCleanTargetName(@NotNull Artifact artifact) {
+    return "clean.artifact." + BuildProperties.convertName(artifact.getName());
+  }
+
+  public String getTargetName(@NotNull Artifact artifact) {
+    String target = myArtifact2Target.get(artifact);
+    if (target == null) {
+      target = generateTargetName(artifact.getName());
+      myArtifact2Target.put(artifact, target);
+    }
+    return target;
+  }
+
+  private static String generateTargetName(String artifactName) {
+    return "artifact." + BuildProperties.convertName(artifactName);
+  }
+
+  public String getSubstitutedPath(String path) {
+    return GenerationUtils.toRelativePath(path, VfsUtil.virtualToIoFile(myProject.getBaseDir()), BuildProperties.getProjectBaseDirProperty(), myGenerationOptions);
+  }
+
+  public void runBeforeCurrentArtifact(Generator generator) {
+    myBeforeCurrentArtifact.add(generator);
+  }
+
+  public void runBeforeBuild(Generator generator) {
+    myBeforeBuildGenerators.add(generator);
+  }
+
+  public void runAfterBuild(Generator generator) {
+    myAfterBuildGenerators.add(generator);
+  }
+
+  public String createNewTempFileProperty(String basePropertyName, String fileName) {
+    String tempFileName = fileName;
+    int i = 1;
+    String tempSubdir = null;
+    while (myTempFileNames.contains(tempFileName)) {
+      tempSubdir = String.valueOf(i++);
+      tempFileName = tempSubdir + "/" + fileName;
+    }
+
+    String propertyName = basePropertyName;
+    i = 2;
+    while (myProperties.contains(propertyName)) {
+      propertyName = basePropertyName + i++;
+    }
+
+    runBeforeBuild(new Property(propertyName, BuildProperties.propertyRelativePath(ARTIFACTS_TEMP_DIR_PROPERTY, tempFileName)));
+    if (tempSubdir != null && myCreatedTempSubdirs.add(tempSubdir)) {
+      runBeforeBuild(new Mkdir(BuildProperties.propertyRelativePath(ARTIFACTS_TEMP_DIR_PROPERTY, tempSubdir)));
+    }
+    myTempFileNames.add(tempFileName);
+    myProperties.add(propertyName);
+    return propertyName;
+  }
+
+  public Generator[] getAndClearBeforeCurrentArtifact() {
+    final Generator[] generators = myBeforeCurrentArtifact.toArray(new Generator[myBeforeCurrentArtifact.size()]);
+    myBeforeCurrentArtifact.clear();
+    return generators;
+  }
+
+  public String getModuleOutputPath(String moduleName) {
+    return BuildProperties.getOutputPathProperty(moduleName);
+  }
+
+  @Override
+  public String getModuleTestOutputPath(@NonNls String moduleName) {
+    return BuildProperties.getOutputPathForTestsProperty(moduleName);
+  }
+
+  public List<Generator> getBeforeBuildGenerators() {
+    return myBeforeBuildGenerators;
+  }
+
+  public List<Generator> getAfterBuildGenerators() {
+    return myAfterBuildGenerators;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java
new file mode 100644
index 0000000..51ce1f4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/ArtifactsGenerator.java
@@ -0,0 +1,190 @@
+/*
+ * 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.compiler.ant.artifacts;
+
+import com.intellij.compiler.ant.*;
+import com.intellij.compiler.ant.taskdefs.*;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.elements.ComplexPackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.artifacts.PackagingElementPath;
+import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
+import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
+import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactsGenerator {
+  @NonNls public static final String BUILD_ALL_ARTIFACTS_TARGET = "build.all.artifacts";
+  @NonNls private static final String INIT_ARTIFACTS_TARGET = "init.artifacts";
+  private final PackagingElementResolvingContext myResolvingContext;
+  private final ArtifactAntGenerationContextImpl myContext;
+  private final List<Artifact> myAllArtifacts;
+
+  public ArtifactsGenerator(Project project, GenerationOptions genOptions) {
+    myResolvingContext = ArtifactManager.getInstance(project).getResolvingContext();
+
+    myAllArtifacts = new ArrayList<Artifact>(Arrays.asList(ArtifactManager.getInstance(project).getSortedArtifacts()));
+
+    myContext = new ArtifactAntGenerationContextImpl(project, genOptions, myAllArtifacts);
+  }
+
+  public boolean hasArtifacts() {
+    return !myAllArtifacts.isEmpty();
+  }
+
+  public List<Generator> generate() {
+    final List<Generator> generators = new ArrayList<Generator>();
+
+    final Target initTarget = new Target(INIT_ARTIFACTS_TARGET, null, null, null);
+    generators.add(initTarget);
+    initTarget.add(new Property(ArtifactAntGenerationContextImpl.ARTIFACTS_TEMP_DIR_PROPERTY, BuildProperties.propertyRelativePath(BuildProperties.getProjectBaseDirProperty(), "__artifacts_temp")));
+
+    for (Artifact artifact : myAllArtifacts) {
+      if (!myContext.shouldBuildIntoTempDirectory(artifact)) {
+        generators.add(new CleanArtifactTarget(artifact, myContext));
+      }
+      final String outputPath = artifact.getOutputPath();
+      if (!StringUtil.isEmpty(outputPath)) {
+        initTarget.add(new Property(myContext.getConfiguredArtifactOutputProperty(artifact), myContext.getSubstitutedPath(outputPath)));
+      }
+    }
+    initTarget.add(new Mkdir(BuildProperties.propertyRef(ArtifactAntGenerationContextImpl.ARTIFACTS_TEMP_DIR_PROPERTY)));
+
+    StringBuilder depends = new StringBuilder();
+    for (Artifact artifact : myAllArtifacts) {
+      Target target = createArtifactTarget(artifact);
+      generators.add(target);
+
+      if (!StringUtil.isEmpty(artifact.getOutputPath())) {
+        if (depends.length() > 0) depends.append(", ");
+        depends.append(myContext.getTargetName(artifact));
+      }
+    }
+
+    for (Generator generator : myContext.getBeforeBuildGenerators()) {
+      initTarget.add(generator);
+    }
+
+    Target buildAllArtifacts = new Target(BUILD_ALL_ARTIFACTS_TARGET, depends.toString(), "Build all artifacts", null);
+    for (Artifact artifact : myAllArtifacts) {
+      final String artifactOutputPath = artifact.getOutputPath();
+      if (!StringUtil.isEmpty(artifactOutputPath) && myContext.shouldBuildIntoTempDirectory(artifact)) {
+        final String outputPath = BuildProperties.propertyRef(myContext.getConfiguredArtifactOutputProperty(artifact));
+        buildAllArtifacts.add(new Mkdir(outputPath));
+        final Copy copy = new Copy(outputPath);
+        copy.add(new FileSet(BuildProperties.propertyRef(myContext.getArtifactOutputProperty(artifact))));
+        buildAllArtifacts.add(copy);
+      }
+    }
+
+    buildAllArtifacts.add(new Comment("Delete temporary files"), 1);
+    for (Generator generator : myContext.getAfterBuildGenerators()) {
+      buildAllArtifacts.add(generator);
+    }
+    buildAllArtifacts.add(new Delete(BuildProperties.propertyRef(ArtifactAntGenerationContextImpl.ARTIFACTS_TEMP_DIR_PROPERTY)));
+
+    generators.add(buildAllArtifacts);
+    return generators;
+  }
+
+  private Target createArtifactTarget(Artifact artifact) {
+    final StringBuilder depends = new StringBuilder(INIT_ARTIFACTS_TARGET);
+
+    ArtifactUtil.processPackagingElements(artifact, null, new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean shouldProcessSubstitution(ComplexPackagingElement<?> element) {
+        return !(element instanceof ArtifactPackagingElement);
+      }
+
+      @Override
+      public boolean process(@NotNull PackagingElement<?> packagingElement, @NotNull PackagingElementPath path) {
+        if (packagingElement instanceof ArtifactPackagingElement) {
+          final Artifact included = ((ArtifactPackagingElement)packagingElement).findArtifact(myResolvingContext);
+          if (included != null) {
+            if (depends.length() > 0) depends.append(", ");
+            depends.append(myContext.getTargetName(included));
+          }
+        }
+        else if (packagingElement instanceof ModuleOutputPackagingElement) {
+          final Module module = ((ModuleOutputPackagingElement)packagingElement).findModule(myResolvingContext);
+          if (module != null) {
+            if (depends.length() > 0) depends.append(", ");
+            depends.append(BuildProperties.getCompileTargetName(module.getName()));
+          }
+        }
+        return true;
+      }
+    }, myResolvingContext, true);
+
+    final Target artifactTarget =
+        new Target(myContext.getTargetName(artifact), depends.toString(), "Build '" + artifact.getName() + "' artifact", null);
+
+    if (myContext.shouldBuildIntoTempDirectory(artifact)) {
+      final String outputDirectory = BuildProperties.propertyRelativePath(ArtifactAntGenerationContextImpl.ARTIFACTS_TEMP_DIR_PROPERTY,
+                                                                          FileUtil.sanitizeFileName(artifact.getName()));
+      artifactTarget.add(new Property(myContext.getArtifactOutputProperty(artifact), outputDirectory));
+    }
+
+    final String outputPath = BuildProperties.propertyRef(myContext.getArtifactOutputProperty(artifact));
+    artifactTarget.add(new Mkdir(outputPath));
+    generateTasksForArtifacts(artifact, artifactTarget, true);
+
+    final DirectoryAntCopyInstructionCreator creator = new DirectoryAntCopyInstructionCreator(outputPath);
+
+    List<Generator> copyInstructions = new ArrayList<Generator>();
+    copyInstructions.addAll(artifact.getRootElement().computeAntInstructions(myResolvingContext, creator, myContext, artifact.getArtifactType()));
+
+    for (Generator generator : myContext.getAndClearBeforeCurrentArtifact()) {
+      artifactTarget.add(generator);
+    }
+    for (Generator tag : copyInstructions) {
+      artifactTarget.add(tag);
+    }
+    generateTasksForArtifacts(artifact, artifactTarget, false);
+    return artifactTarget;
+  }
+
+  private void generateTasksForArtifacts(Artifact artifact, Target artifactTarget, final boolean preprocessing) {
+    for (ChunkBuildExtension extension : ChunkBuildExtension.EP_NAME.getExtensions()) {
+      extension.generateTasksForArtifact(artifact, preprocessing, myContext, artifactTarget);
+    }
+  }
+
+  public List<String> getCleanTargetNames() {
+    final List<String> targets = new ArrayList<String>();
+    for (Artifact artifact : myAllArtifacts) {
+      if (!myContext.shouldBuildIntoTempDirectory(artifact)) {
+        targets.add(myContext.getCleanTargetName(artifact));
+      }
+    }
+    return targets;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/CleanArtifactTarget.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/CleanArtifactTarget.java
new file mode 100644
index 0000000..8a205af
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/CleanArtifactTarget.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.compiler.ant.artifacts;
+
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.compiler.ant.taskdefs.Delete;
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.packaging.artifacts.Artifact;
+
+/**
+ * @author nik
+ */
+public class CleanArtifactTarget extends Target {
+  public CleanArtifactTarget(Artifact artifact, ArtifactAntGenerationContextImpl context) {
+    super(context.getCleanTargetName(artifact), null, "clean " + artifact.getName() + " artifact output", null);
+    add(new Delete(BuildProperties.propertyRef(context.getConfiguredArtifactOutputProperty(artifact))));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/DirectoryAntCopyInstructionCreator.java b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/DirectoryAntCopyInstructionCreator.java
new file mode 100644
index 0000000..900dff4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/ant/artifacts/DirectoryAntCopyInstructionCreator.java
@@ -0,0 +1,64 @@
+/*
+ * 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.compiler.ant.artifacts;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.Tag;
+import com.intellij.compiler.ant.taskdefs.*;
+import com.intellij.packaging.elements.AntCopyInstructionCreator;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class DirectoryAntCopyInstructionCreator implements AntCopyInstructionCreator {
+  private final String myOutputDirectory;
+
+  public DirectoryAntCopyInstructionCreator(String outputDirectory) {
+    myOutputDirectory = outputDirectory;
+  }
+
+  public String getOutputDirectory() {
+    return myOutputDirectory;
+  }
+
+  @NotNull
+  public Tag createDirectoryContentCopyInstruction(@NotNull String dirPath) {
+    final Copy copy = new Copy(myOutputDirectory);
+    copy.add(new FileSet(dirPath));
+    return copy;
+  }
+
+  @NotNull
+  public Tag createFileCopyInstruction(@NotNull String filePath, String outputFileName) {
+    return new Copy(filePath, myOutputDirectory + "/" + outputFileName);
+  }
+
+  @NotNull
+  public AntCopyInstructionCreator subFolder(@NotNull String directoryName) {
+    return new DirectoryAntCopyInstructionCreator(myOutputDirectory + "/" + directoryName);
+  }
+
+  public Generator createSubFolderCommand(@NotNull String directoryName) {
+    return new Mkdir(myOutputDirectory + "/" + directoryName);
+  }
+
+  @NotNull
+  @Override
+  public Generator createExtractedDirectoryInstruction(@NotNull String jarPath) {
+    return new Unzip(jarPath, myOutputDirectory);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationConstantValue.java
new file mode 100644
index 0000000..4d4bfc4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationConstantValue.java
@@ -0,0 +1,85 @@
+/*
+ * 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.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 2, 2004
+ */
+public class AnnotationConstantValue extends ConstantValue {
+  public static final AnnotationConstantValue[] EMPTY_ARRAY = new AnnotationConstantValue[0];
+  public static final AnnotationConstantValue[][] EMPTY_ARRAY_ARRAY = new AnnotationConstantValue[0][];
+  public final int myQName;
+  public final AnnotationNameValuePair[] myMemberValues;
+
+  public AnnotationConstantValue(int qName, AnnotationNameValuePair[] memberValues) {
+    myQName = qName;
+    myMemberValues = memberValues;
+  }
+
+  public int getAnnotationQName() {
+    return myQName;
+  }
+
+  /**
+   * @return an array of Integer -> ConstantValue pairs
+   */
+  public AnnotationNameValuePair[] getMemberValues() {
+    return myMemberValues;
+  }
+
+  public AnnotationConstantValue(DataInput in) throws IOException {
+    myQName = in.readInt();
+    final int size = in.readInt();
+    myMemberValues = new AnnotationNameValuePair[size];
+    for (int idx = 0; idx < myMemberValues.length; idx++) {
+      final int name = in.readInt();
+      final ConstantValue constantValue = MemberInfoExternalizer.loadConstantValue(in);
+      myMemberValues[idx] = new AnnotationNameValuePair(name, constantValue);
+    }
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeInt(myQName);
+    out.writeInt(myMemberValues.length);
+    for (int idx = 0; idx < myMemberValues.length; idx++) {
+      final AnnotationNameValuePair nameValuePair = myMemberValues[idx];
+      out.writeInt(nameValuePair.getName());
+      MemberInfoExternalizer.saveConstantValue(out, nameValuePair.getValue());
+    }
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof AnnotationConstantValue)) return false;
+
+    final AnnotationConstantValue annotationConstantValue = (AnnotationConstantValue)o;
+
+    if (myQName != annotationConstantValue.myQName) return false;
+    if (!Arrays.equals(myMemberValues, annotationConstantValue.myMemberValues)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    return myQName;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationNameValuePair.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationNameValuePair.java
new file mode 100644
index 0000000..e559875
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationNameValuePair.java
@@ -0,0 +1,38 @@
+/*
+ * 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.compiler.classParsing;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 8, 2004
+ */
+public class AnnotationNameValuePair {
+  private final int myName;
+  private final ConstantValue myValue;
+
+  public AnnotationNameValuePair(int name, ConstantValue value) {
+    myName = name;
+    myValue = value;
+  }
+
+  public int getName() {
+    return myName;
+  }
+
+  public ConstantValue getValue() {
+    return myValue;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java
new file mode 100644
index 0000000..24ade71
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/AnnotationPrimitiveConstantValue.java
@@ -0,0 +1,72 @@
+/*
+ * 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.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 2, 2004
+ */
+public class AnnotationPrimitiveConstantValue extends ConstantValue{
+  private final char myValueTag;
+  private final ConstantValue myValue;
+
+  public AnnotationPrimitiveConstantValue(char valueTag, ConstantValue value) {
+    myValueTag = valueTag;
+    myValue = value;
+  }
+
+  public AnnotationPrimitiveConstantValue(DataInput in) throws IOException {
+    myValueTag = in.readChar();
+    myValue = MemberInfoExternalizer.loadConstantValue(in);
+  }
+
+  public char getValueTag() {
+    return myValueTag;
+  }
+
+  public ConstantValue getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeChar(myValueTag);
+    MemberInfoExternalizer.saveConstantValue(out, myValue);
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof AnnotationPrimitiveConstantValue)) return false;
+
+    final AnnotationPrimitiveConstantValue memberValue = (AnnotationPrimitiveConstantValue)o;
+
+    if (myValueTag != memberValue.myValueTag) return false;
+    if (!myValue.equals(memberValue.myValue)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = (int)myValueTag;
+    result = 29 * result + myValue.hashCode();
+    return result;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java
new file mode 100644
index 0000000..bd80570
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassFileReader.java
@@ -0,0 +1,770 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 2, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.psi.CommonClassNames;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.cls.BytePointer;
+import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.cls.ClsUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+
+public class ClassFileReader {
+  private final File myFile;
+  private byte[] myData;
+  private int[] myConstantPoolOffsets = null; // the last offset points to the constant pool end
+
+  private String myQualifiedName;
+  private String myGenericSignature;
+  private List<ReferenceInfo> myReferences;
+  private List<FieldInfo> myFields;
+  private List<MethodInfo> myMethods;
+  private String mySourceFileName;
+  private String mySuperClassName;
+  private String[] mySuperInterfaces;
+  private final SymbolTable mySymbolTable;
+  private AnnotationConstantValue[] myRuntimeVisibleAnnotations;
+  private AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
+  private static final String CONSTRUCTOR_NAME = "<init>";
+  private boolean myParsingDone;
+
+  public ClassFileReader(@NotNull File file, SymbolTable symbolTable, @Nullable final byte[] fileContent) {
+    mySymbolTable = symbolTable;
+    myFile = file;
+    myData = fileContent;
+  }
+
+  public String getPath() {
+    return myFile.getAbsolutePath();
+  }
+
+  public Collection<ReferenceInfo> getReferences() throws ClsFormatException {
+    parseConstantPool();
+    return myReferences;
+  }
+
+  public MethodInfo[] getMethods() throws ClsFormatException{
+    parseMembers();
+    return myMethods.toArray(new MethodInfo[myMethods.size()]);
+  }
+
+  public FieldInfo[] getFields() throws ClsFormatException{
+    parseMembers();
+    return myFields.toArray(new FieldInfo[myFields.size()]);
+  }
+
+  private void parseMembers() throws ClsFormatException {
+    if (myParsingDone) {
+      return;
+    }
+    initConstantPool();
+    myMethods = new ArrayList<MethodInfo>();
+    myFields = new ArrayList<FieldInfo>();
+    BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd());
+    ptr.offset += 2; // access flags
+    ptr.offset += 2; // this class
+    ptr.offset += 2; // super class
+    int count = ClsUtil.readU2(ptr); // interface count
+    ptr.offset += 2 * count; // skip interface infos
+    count = ClsUtil.readU2(ptr); // field count
+    while (count-- > 0) {
+      FieldInfo field = (FieldInfo)readMemberStructure(ptr, true);
+      String name = getSymbol(field.getName());
+      if (name.indexOf('$') < 0 && name.indexOf('<') < 0){ // skip synthetic fields
+        myFields.add(field);
+      }
+    }
+    count = ClsUtil.readU2(ptr); // method count
+    while (count-- > 0) {
+      MethodInfo method = (MethodInfo)readMemberStructure(ptr, false);
+      String name = getSymbol(method.getName());
+      if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip synthetic methods
+        myMethods.add(method);
+      }
+      else
+      if (CONSTRUCTOR_NAME.equals(name)) { // store constructors
+        myMethods.add(method);
+      }
+    }
+
+    final ClsAttributeTable attributeTable = readAttributes(ptr);
+    mySourceFileName = attributeTable.sourceFile;
+    myGenericSignature = attributeTable.genericSignature;
+    myRuntimeVisibleAnnotations = attributeTable.runtimeVisibleAnnotations;
+    myRuntimeInvisibleAnnotations = attributeTable.runtimeInvisibleAnnotations;
+    myParsingDone = true;
+  }
+
+  private String getSymbol(final int id) throws ClsFormatException {
+    try {
+      return mySymbolTable.getSymbol(id);
+    }
+    catch (CacheCorruptedException e) {
+      throw new ClsFormatException(e.getLocalizedMessage());
+    }
+  }
+
+  private MemberInfo readMemberStructure(BytePointer ptr, boolean isField) throws ClsFormatException {
+    int flags = ClsUtil.readU2(ptr);
+    int nameIndex = ClsUtil.readU2(ptr);
+    int descriptorIndex = ClsUtil.readU2(ptr);
+
+    BytePointer p = new BytePointer(getData(), getOffsetInConstantPool(nameIndex));
+    String name = ClsUtil.readUtf8Info(p);
+    p.offset = getOffsetInConstantPool(descriptorIndex);
+    String descriptor = ClsUtil.readUtf8Info(p);
+
+    if (isField) {
+      final ClsAttributeTable attributeTable = readAttributes(ptr);
+      return new FieldInfo(
+        getSymbolId(name),
+        getSymbolId(descriptor),
+        attributeTable.genericSignature != null? getSymbolId(attributeTable.genericSignature) : -1,
+        flags,
+        attributeTable.constantValue,
+        attributeTable.runtimeVisibleAnnotations,
+        attributeTable.runtimeInvisibleAnnotations
+      );
+    }
+    else {
+      final ClsAttributeTable attributeTable = readAttributes(ptr);
+      int[] intExceptions = null;
+      if (attributeTable.exceptions != null) {
+        intExceptions = ArrayUtil.newIntArray(attributeTable.exceptions.length);
+        for (int idx = 0; idx < intExceptions.length; idx++) {
+          intExceptions[idx]  = getSymbolId(attributeTable.exceptions[idx]);
+        }
+      }
+      return new MethodInfo(
+        getSymbolId(name),
+        getSymbolId(descriptor),
+        attributeTable.genericSignature != null? getSymbolId(attributeTable.genericSignature) : -1,
+        flags,
+        intExceptions,
+        CONSTRUCTOR_NAME.equals(name),
+        attributeTable.runtimeVisibleAnnotations,
+        attributeTable.runtimeInvisibleAnnotations,
+        attributeTable.runtimeVisibleParameterAnnotations,
+        attributeTable.runtimeInvisibleParameterAnnotations,
+        attributeTable.annotationDefault
+      );
+    }
+  }
+
+  private int getSymbolId(final String symbol)  throws ClsFormatException{
+    try {
+      return mySymbolTable.getId(symbol);
+    }
+    catch (CacheCorruptedException e) {
+      throw new ClsFormatException(e.getLocalizedMessage());
+    }
+  }
+
+  public String getQualifiedName() throws ClsFormatException {
+    if (myQualifiedName == null) {
+      BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 2);
+      ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+      int tag = ClsUtil.readU1(ptr);
+      if (tag != ClsUtil.CONSTANT_Class){
+        throw new ClsFormatException();
+      }
+      ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+      myQualifiedName = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in the names
+    }
+    return myQualifiedName;
+  }
+
+  /**
+   * @return fully qualified name of the class' superclass. In case there is no super return ""
+   */
+  public String getSuperClass() throws ClsFormatException {
+    if (mySuperClassName == null) {
+      BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 4);
+      int index = ClsUtil.readU2(ptr);
+      if (index == 0) {
+        if (CommonClassNames.JAVA_LANG_OBJECT.equals(getQualifiedName())) {
+          mySuperClassName = "";
+        }
+        else {
+          throw new ClsFormatException();
+        }
+      }
+      else {
+        ptr.offset = getOffsetInConstantPool(index);
+        mySuperClassName = readClassInfo(ptr); // keep '$' in the name for anonymous classes
+        if (isInterface()) {
+          if (!CommonClassNames.JAVA_LANG_OBJECT.equals(mySuperClassName)) {
+            throw new ClsFormatException();
+          }
+        }
+        /*
+        else {
+          if (!MakeUtil.isAnonymous(mySuperClassName)) {
+            mySuperClassName = mySuperClassName.replace('$', '.');
+          }
+        }
+        */
+      }
+    }
+    return mySuperClassName;
+  }
+
+  public String[] getSuperInterfaces() throws ClsFormatException {
+    if (mySuperInterfaces == null) {
+      BytePointer ptr = new BytePointer(getData(), getConstantPoolEnd() + 6);
+      int count = ClsUtil.readU2(ptr);
+      mySuperInterfaces = ArrayUtil.newStringArray(count);
+      BytePointer auxPtr = new BytePointer(ptr.bytes, 0);
+      for (int idx = 0; idx < mySuperInterfaces.length; idx++) {
+        auxPtr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+        mySuperInterfaces[idx] = readClassInfo(auxPtr);
+      }
+    }
+    return mySuperInterfaces;
+  }
+
+
+  public String getSourceFileName() throws ClsFormatException {
+    parseMembers();
+    final String fName = mySourceFileName;
+    return fName != null? fName : "";
+  }
+
+  public String getGenericSignature() throws ClsFormatException {
+    parseMembers();
+    final String genericSignature = myGenericSignature;
+    return genericSignature != null && !genericSignature.isEmpty() ? genericSignature : null;
+  }
+
+  public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws ClsFormatException {
+    parseMembers();
+    final AnnotationConstantValue[] annotations = myRuntimeVisibleAnnotations;
+    return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
+  }
+
+  public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws ClsFormatException {
+    parseMembers();
+    final AnnotationConstantValue[] annotations = myRuntimeInvisibleAnnotations;
+    return annotations != null? annotations : AnnotationConstantValue.EMPTY_ARRAY;
+  }
+
+  private boolean isInterface(){
+    return (getAccessFlags() & ClsUtil.ACC_INTERFACE) != 0;
+  }
+
+// helper methods
+  private void parseConstantPool() throws ClsFormatException {
+    if (myReferences != null) {
+      return;
+    }
+    myReferences = new ArrayList<ReferenceInfo>();
+    initConstantPool();
+    final BytePointer ptr = new BytePointer(getData(), 0);
+    ConstantPoolIterator iterator = new ConstantPoolIterator(ptr);
+    while (iterator.hasMoreEntries()) {
+      final int tag = ClsUtil.readU1(ptr);
+      if (tag == ClsUtil.CONSTANT_Fieldref || tag == ClsUtil.CONSTANT_Methodref || tag == ClsUtil.CONSTANT_InterfaceMethodref) {
+        //ptr.offset -= 1; // position to the beginning of the structure
+        MemberReferenceInfo refInfo = readRefStructure(tag, ptr);
+        if (refInfo != null) {
+          myReferences.add(refInfo);
+        }
+        /*
+        String name = mySymbolTable.getSymbol(refInfo.getMemberInfo().getName());
+        if (name.indexOf('$') < 0 && name.indexOf('<') < 0) { // skip refs to synthetic members
+          myReferences.add(refInfo);
+        }
+        else if ("<init>".equals(name)) { // add instance initializers (constructors)
+          myReferences.add(refInfo);
+        }
+        else {
+          System.out.println("ReferenceInfo thrown out: " + mySymbolTable.getSymbol(refInfo.getClassName()) + "." + mySymbolTable.getSymbol(refInfo.getMemberInfo().getName()));
+          ourWasteReferenceObjectsCounter += 1;
+        }
+        */
+      }
+      else if (tag == ClsUtil.CONSTANT_Class) {
+        ptr.offset -= 1; // position to the beginning of the structure
+        String className = readClassInfo(ptr);
+        myReferences.add(new ReferenceInfo(getSymbolId(className)));
+      }
+      iterator.next();
+    }
+    //System.out.println("ourWasteReferenceObjectsCounter = " + ourWasteReferenceObjectsCounter);
+  }
+
+  private MemberReferenceInfo readRefStructure(int tag, BytePointer ptr) throws ClsFormatException {
+    /*
+    if (tag != ClsUtil.CONSTANT_Fieldref && tag != ClsUtil.CONSTANT_Methodref && tag != ClsUtil.CONSTANT_InterfaceMethodref) {
+      throw new ClsFormatException();
+    }
+    */
+    int classInfoIndex = ClsUtil.readU2(ptr);
+    int nameTypeInfoIndex = ClsUtil.readU2(ptr);
+
+    ptr.offset = getOffsetInConstantPool(classInfoIndex);
+    if (ClsUtil.CONSTANT_Class != ClsUtil.readU1(ptr)) {
+      throw new ClsFormatException();
+    }
+    ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+    String className = ClsUtil.readUtf8Info(ptr, '/', '.'); // keep '$' in names
+
+    ptr.offset = getOffsetInConstantPool(nameTypeInfoIndex);
+    if (ClsUtil.CONSTANT_NameAndType != ClsUtil.readU1(ptr)) {
+      throw new ClsFormatException();
+    }
+    int memberNameIndex = ClsUtil.readU2(ptr);
+    int descriptorIndex = ClsUtil.readU2(ptr);
+
+    ptr.offset = getOffsetInConstantPool(memberNameIndex);
+    String memberName = ClsUtil.readUtf8Info(ptr);
+
+    if ((memberName.indexOf('$') >= 0 || memberName.indexOf('<') >= 0) && !CONSTRUCTOR_NAME.equals(memberName)) { // skip refs to synthetic members
+      return null;
+    }
+
+    ptr.offset = getOffsetInConstantPool(descriptorIndex);
+    String descriptor = ClsUtil.readUtf8Info(ptr);
+
+    MemberInfo info = ClsUtil.CONSTANT_Fieldref == tag? new FieldInfo(getSymbolId(memberName), getSymbolId(descriptor)) : new MethodInfo(getSymbolId(memberName), getSymbolId(descriptor), CONSTRUCTOR_NAME.equals(memberName));
+    return new MemberReferenceInfo(getSymbolId(className), info);
+  }
+
+  public int getAccessFlags(){
+    try{
+      int offset = getConstantPoolEnd();
+      byte[] data = getData();
+      if (offset + 2 > data.length){
+        throw new ClsFormatException();
+      }
+      int b1 = data[offset++] & 0xFF;
+      int b2 = data[offset++] & 0xFF;
+      return (b1 << 8) + b2;
+    }
+    catch(ClsFormatException e){
+      return 0;
+    }
+  }
+
+  private byte[] getData(){
+    if (myData == null) {
+      try{
+        myData = FileUtil.loadFileBytes(myFile);
+      }
+      catch(IOException e){
+        myData = ArrayUtil.EMPTY_BYTE_ARRAY;
+      }
+    }
+    return myData;
+  }
+
+  private int getOffsetInConstantPool(int index) throws ClsFormatException {
+    initConstantPool();
+    if (index < 1 || index >= myConstantPoolOffsets.length){
+      throw new ClsFormatException();
+    }
+    return myConstantPoolOffsets[index - 1];
+  }
+
+  private int getConstantPoolEnd() throws ClsFormatException {
+    initConstantPool();
+    return myConstantPoolOffsets[myConstantPoolOffsets.length - 1];
+  }
+
+  private void initConstantPool() throws ClsFormatException {
+    if (myConstantPoolOffsets == null){
+      BytePointer ptr = new BytePointer(getData(), 0);
+      ConstantPoolIterator iterator = new ConstantPoolIterator(ptr);
+      myConstantPoolOffsets = new int[iterator.getEntryCount()];
+      myConstantPoolOffsets[0] = iterator.getCurrentOffset();
+      int index = 1;
+      while (iterator.hasMoreEntries()) {
+        int tag = ClsUtil.readU1(ptr);
+        if (tag == ClsUtil.CONSTANT_Long || tag == ClsUtil.CONSTANT_Double) {
+          myConstantPoolOffsets[index++] = ptr.offset + 8; // takes 2 entries!
+        }
+        iterator.next();
+        myConstantPoolOffsets[index++] = iterator.getCurrentOffset();
+      }
+    }
+  }
+
+  private String readClassInfo(BytePointer ptr) throws ClsFormatException{
+    final int tag = ClsUtil.readU1(ptr);
+    if (tag != ClsUtil.CONSTANT_Class){
+      throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", tag, ClsUtil.CONSTANT_Class));
+    }
+    int index = ClsUtil.readU2(ptr);
+    return ClsUtil.readUtf8Info(new BytePointer(ptr.bytes, getOffsetInConstantPool(index)), '/', '.');
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  private ClsAttributeTable readAttributes(BytePointer ptr) throws ClsFormatException {
+    int count = ClsUtil.readU2(ptr); // attributeCount
+    final ClsAttributeTable attributes = new ClsAttributeTable();
+    while (count-- > 0) {
+      final String attrName = readAttributeName(ptr);
+      if ("Exceptions".equals(attrName)) {
+        attributes.exceptions = readExceptions(ptr);
+      }
+      else if ("Signature".equals(attrName)) {
+        attributes.genericSignature = readSignatureAttribute(ptr);
+      }
+      else if ("SourceFile".equals(attrName)) {
+        attributes.sourceFile = readSourceFileAttribute(ptr);
+      }
+      else if ("ConstantValue".equals(attrName)){
+        attributes.constantValue = readFieldConstantValue(ptr);
+      }
+      else if ("RuntimeVisibleAnnotations".equals(attrName)) {
+        attributes.runtimeVisibleAnnotations = readAnnotations(ptr);
+      }
+      else if ("RuntimeInvisibleAnnotations".equals(attrName)) {
+        attributes.runtimeInvisibleAnnotations = readAnnotations(ptr);
+      }
+      else if ("RuntimeVisibleParameterAnnotations".equals(attrName)) {
+        attributes.runtimeVisibleParameterAnnotations = readParameterAnnotations(ptr);
+      }
+      else if ("RuntimeInvisibleParameterAnnotations".equals(attrName)) {
+        attributes.runtimeInvisibleParameterAnnotations = readParameterAnnotations(ptr);
+      }
+      else if ("AnnotationDefault".equals(attrName)) {
+        attributes.annotationDefault = readAnnotationMemberValue(new BytePointer(ptr.bytes, ptr.offset + 6));
+      }
+      gotoNextAttribute(ptr);
+    }
+    return attributes;
+  }
+
+  private String readAttributeName(BytePointer p) throws ClsFormatException {
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset);
+    final int nameIndex = ClsUtil.readU2(ptr);
+    ptr.offset = getOffsetInConstantPool(nameIndex);
+    return ClsUtil.readUtf8Info(ptr);
+  }
+
+  private static void gotoNextAttribute(BytePointer ptr) throws ClsFormatException {
+    ptr.offset += 2; // skip name index
+    final int length = ClsUtil.readU4(ptr);    // important! Do not inline since ptr.offset is also changed inside ClsUtil.readU4() method
+    ptr.offset += length;
+  }
+
+  /**
+      Signature_attribute {
+        u2 attribute_name_index;    (must be equal to "Signature")
+        u4 attribute_length;        (must be equal to 2)
+        u2 signature_index;
+      }
+   */
+  private String readSignatureAttribute(BytePointer p) throws ClsFormatException {
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length
+    if (ClsUtil.readU4(ptr) != 2) {
+      return null;
+    }
+    ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+    return ClsUtil.readUtf8Info(ptr);
+  }
+
+  private String[] readExceptions(BytePointer p) throws ClsFormatException{
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the count of exceptions
+    int count = ClsUtil.readU2(ptr);
+    final ArrayList<String> array = new ArrayList<String>(count);
+    while (count-- > 0) {
+      int idx = ClsUtil.readU2(ptr);
+      if (idx != 0) {
+        final String exceptionClass = readClassInfo(new BytePointer(ptr.bytes, getOffsetInConstantPool(idx)));
+        array.add(exceptionClass);
+      }
+    }
+    return ArrayUtil.toStringArray(array);
+  }
+
+  private String readSourceFileAttribute(BytePointer p) throws ClsFormatException {
+    BytePointer ptr = new BytePointer(p.bytes, p.offset + 2); // position to the length
+    if (ClsUtil.readU4(ptr) != 2) {
+      return null;
+    }
+    ptr.offset = getOffsetInConstantPool(ClsUtil.readU2(ptr));
+    String path = ClsUtil.readUtf8Info(ptr);
+    // jdk version 1.3.0 puts full path to the source, but later versions store only short name
+    final int slashIndex = path.lastIndexOf('/');
+    if (slashIndex >= 0) {
+      path = path.substring(slashIndex + 1, path.length());
+    }
+    return path;
+  }
+
+  private ConstantValue readFieldConstantValue(BytePointer p) throws ClsFormatException{
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset + 2);
+    if (ClsUtil.readU4(ptr) != 2) {
+      throw new ClsFormatException(); // attribute length must be 2
+    }
+    int valueIndex = ClsUtil.readU2(ptr);
+    ptr.offset = getOffsetInConstantPool(valueIndex);
+    return readConstant(ptr);
+  }
+
+  private ConstantValue readConstant(final BytePointer ptr) throws ClsFormatException {
+    final int tag = ClsUtil.readU1(ptr);
+    switch (tag) {
+      case ClsUtil.CONSTANT_Integer :
+        int value = ClsUtil.readU4(ptr);
+        return new IntegerConstantValue(value);
+      case ClsUtil.CONSTANT_Float:
+        float floatValue = ClsUtil.readFloat(ptr);
+        return new FloatConstantValue(floatValue);
+      case ClsUtil.CONSTANT_Long :
+        int high = ClsUtil.readU4(ptr);
+        int low = ClsUtil.readU4(ptr);
+        long v = ((long)high << 32) | (low & 0xFFFFFFFFL);
+        return new LongConstantValue(v);
+      case ClsUtil.CONSTANT_Double :
+        double doubleValue = ClsUtil.readDouble(ptr);
+        return new DoubleConstantValue(doubleValue);
+      case ClsUtil.CONSTANT_String :
+        int stringIndex = ClsUtil.readU2(ptr);
+        ptr.offset = getOffsetInConstantPool(stringIndex);
+        return new StringConstantValue(ClsUtil.readUtf8Info(ptr));
+      default : throw new ClsFormatException();
+    }
+  }
+
+  private AnnotationConstantValue[] readAnnotations(BytePointer p) throws ClsFormatException {
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6);
+    return readAnnotationsArray(ptr);
+  }
+
+  private AnnotationConstantValue[][] readParameterAnnotations(BytePointer p) throws ClsFormatException {
+    final BytePointer ptr = new BytePointer(p.bytes, p.offset + 6); // position to the number of parameters
+    final int numberOfParams = ClsUtil.readU1(ptr);
+    if (numberOfParams == 0) {
+      return null;
+    }
+    final AnnotationConstantValue[][] annotations = new AnnotationConstantValue[numberOfParams][];
+    for (int parameterIndex = 0; parameterIndex < numberOfParams; parameterIndex++) {
+      annotations[parameterIndex] = readAnnotationsArray(ptr);
+    }
+    return annotations;
+  }
+
+  private AnnotationConstantValue[] readAnnotationsArray(BytePointer ptr) throws ClsFormatException {
+    final int numberOfAnnotations = ClsUtil.readU2(ptr);
+    if (numberOfAnnotations == 0) {
+      return AnnotationConstantValue.EMPTY_ARRAY;
+    }
+    AnnotationConstantValue[] annotations = new AnnotationConstantValue[numberOfAnnotations];
+    for (int attributeIndex = 0; attributeIndex < numberOfAnnotations; attributeIndex++) {
+      annotations[attributeIndex] = readAnnotation(ptr);
+    }
+    return annotations;
+  }
+
+  private AnnotationConstantValue readAnnotation(BytePointer ptr) throws ClsFormatException {
+    final int classInfoIndex = ClsUtil.readU2(ptr);
+    final String qName = readAnnotationClassName(new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex)));
+    final List<AnnotationNameValuePair> memberValues = new ArrayList<AnnotationNameValuePair>();
+    final int numberOfPairs = ClsUtil.readU2(ptr);
+    for (int idx = 0; idx < numberOfPairs; idx++) {
+      final int memberNameIndex = ClsUtil.readU2(ptr);
+      final String memberName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(memberNameIndex));
+      final ConstantValue memberValue = readAnnotationMemberValue(ptr);
+      memberValues.add(new AnnotationNameValuePair(getSymbolId(memberName), memberValue));
+    }
+    return new AnnotationConstantValue(getSymbolId(qName), memberValues.toArray(new AnnotationNameValuePair[memberValues.size()]));
+  }
+
+  private String readAnnotationClassName(BytePointer ptr) throws ClsFormatException {
+    // TODO: need this method because because of incomplete class format spec at the moment of writing
+    // it is not clear what structure is expected: CONSTANT_Utf8 or CONSTANT_Class
+    final int tag = ClsUtil.readU1(ptr);
+    if (tag == ClsUtil.CONSTANT_Utf8) {
+      return ClsUtil.getTypeText(ptr.bytes, ptr.offset + 2); //skip length
+    }
+    if (tag == ClsUtil.CONSTANT_Class){
+      ptr.offset -= 1; // rollback
+      return readClassInfo(ptr);
+    }
+    //noinspection HardCodedStringLiteral
+    throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", tag, "CONSTANT_Utf8(" + ClsUtil.CONSTANT_Utf8 + ") / CONSTANT_Class(" + ClsUtil.CONSTANT_Class + ")"));
+  }
+
+  private ConstantValue readAnnotationMemberValue(BytePointer ptr) throws ClsFormatException {
+    final char tag = (char)ClsUtil.readU1(ptr);
+    switch (tag) {
+      case 'B':
+      case 'C':
+      case 'D':
+      case 'F':
+      case 'I':
+      case 'J':
+      case 'S':
+      case 'Z': {
+        final int valueIndex = ClsUtil.readU2(ptr);
+        return new AnnotationPrimitiveConstantValue(tag, readConstant(new BytePointer(ptr.bytes, getOffsetInConstantPool(valueIndex))));
+      }
+      case 's': {
+        final int valueIndex = ClsUtil.readU2(ptr);
+        return new StringConstantValue(ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(valueIndex)));
+      }
+      case 'e': {
+        final int typeNameIndex = ClsUtil.readU2(ptr);
+        final int constantNameIndex = ClsUtil.readU2(ptr);
+        final String typeName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(typeNameIndex));
+        final String constantName = ClsUtil.readUtf8Info(ptr.bytes, getOffsetInConstantPool(constantNameIndex));
+        return new EnumConstantValue(getSymbolId(typeName), getSymbolId(constantName));
+      }
+      case 'c' : {
+        final int classInfoIndex = ClsUtil.readU2(ptr);
+        BytePointer p = new BytePointer(ptr.bytes, getOffsetInConstantPool(classInfoIndex));
+        final int recordTag = ClsUtil.readU1(p);
+        if (recordTag != ClsUtil.CONSTANT_Utf8) {
+          throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.record.tag.expected.another", recordTag, ClsUtil.CONSTANT_Utf8));
+        }
+        p.offset += 2; //Skip length
+        final String className = ClsUtil.getTypeText(p.bytes, p.offset);
+        return new ClassInfoConstantValue(getSymbolId(className));
+      }
+      case '@' : {
+        return readAnnotation(ptr);
+      }
+      case '[' : {
+        final int numberOfValues = ClsUtil.readU2(ptr);
+        final ConstantValue[] values = new ConstantValue[numberOfValues];
+        for (int idx = 0; idx < numberOfValues; idx++) {
+          values[idx] = readAnnotationMemberValue(ptr);
+        }
+        return new ConstantValueArray(values);
+      }
+      default : throw new ClsFormatException(CompilerBundle.message("class.parsing.error.wrong.tag.annotation.member.value", tag));
+    }
+  }
+
+  private static class ClsAttributeTable {
+    public String[] exceptions;
+    public String genericSignature;
+    public String sourceFile;
+    public ConstantValue constantValue;
+    public AnnotationConstantValue[] runtimeVisibleAnnotations;
+    public AnnotationConstantValue[] runtimeInvisibleAnnotations;
+    public AnnotationConstantValue[][] runtimeVisibleParameterAnnotations;
+    public AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations;
+    public ConstantValue annotationDefault;
+  }
+
+  private static class ConstantPoolIterator {
+    private final BytePointer myPtr;
+    private final int myEntryCount;
+    private int myCurrentEntryIndex;
+    private int myCurrentOffset;
+
+    public ConstantPoolIterator(BytePointer ptr) throws ClsFormatException {
+      myPtr = ptr;
+      myPtr.offset = 0;
+      int magic = ClsUtil.readU4(myPtr);
+      if (magic != ClsUtil.MAGIC){
+        throw new ClsFormatException();
+      }
+      myPtr.offset += 2; // minor version
+      myPtr.offset += 2; // major version
+      myEntryCount = ClsUtil.readU2(myPtr);
+      if (myEntryCount < 1){
+        throw new ClsFormatException();
+      }
+      myCurrentEntryIndex = 1; // Entry at index 0 is included in the count but is not present in the constant pool
+      myCurrentOffset = myPtr.offset;
+    }
+
+    public int getEntryCount() {
+      return myEntryCount;
+    }
+
+    public int getCurrentOffset() {
+      return myCurrentOffset;
+    }
+
+    /**
+     *  tests if there are unread entries
+     */
+    public boolean hasMoreEntries() {
+      return myCurrentEntryIndex < myEntryCount;
+    }
+
+    /**
+     * Positions the pointer to the next entry
+     */
+    public void next() throws ClsFormatException {
+      myPtr.offset = myCurrentOffset;
+      int tag = ClsUtil.readU1(myPtr);
+      switch(tag){
+        default:
+          throw new ClsFormatException();
+
+        case ClsUtil.CONSTANT_Class:
+        case ClsUtil.CONSTANT_String:
+          myPtr.offset += 2;
+        break;
+
+        case ClsUtil.CONSTANT_Fieldref:
+        case ClsUtil.CONSTANT_Methodref:
+        case ClsUtil.CONSTANT_InterfaceMethodref:
+        case ClsUtil.CONSTANT_Integer:
+        case ClsUtil.CONSTANT_Float:
+        case ClsUtil.CONSTANT_NameAndType:
+          myPtr.offset += 4;
+        break;
+
+        case ClsUtil.CONSTANT_Long:
+        case ClsUtil.CONSTANT_Double:
+          myPtr.offset += 8;
+          myCurrentEntryIndex++; // takes 2 entries
+        break;
+
+        case ClsUtil.CONSTANT_Utf8:
+          int length = ClsUtil.readU2(myPtr);
+          myPtr.offset += length;
+        break;
+
+        case ClsUtil.CONSTANT_MethodHandle:
+          myPtr.offset += 3;
+          break;
+        case ClsUtil.CONSTANT_MethodType:
+          myPtr.offset += 2;
+          break;
+        case ClsUtil.CONSTANT_InvokeDynamic:
+          myPtr.offset += 4;
+          break;
+      }
+      myCurrentEntryIndex++;
+      myCurrentOffset = myPtr.offset;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfo.java
new file mode 100644
index 0000000..2d816ef
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfo.java
@@ -0,0 +1,229 @@
+/*
+ * 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.compiler.classParsing;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.cls.ClsFormatException;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collection;
+
+/**
+  @author Eugene Zhuravlev
+*/
+public final class ClassInfo implements Cloneable {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.ClassInfo");
+
+  private static final ReferenceInfo[] EMPTY_REF_ARRAY = new ReferenceInfo[0];
+
+  private final int myQualifiedName;
+  private final int myGenericSignature;
+  private final int mySuperQualifiedName;
+  private final int myFlags;
+  private String myPath;
+  private final String mySourceFileName;
+  private final int[] mySuperInterfaces;
+  private final FieldInfo[] myFields;
+  private final MethodInfo[] myMethods;
+  private ReferenceInfo[] myReferences;
+  private final AnnotationConstantValue[] myRuntimeVisibleAnnotations;
+  private final AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
+  private boolean myIsDirty = false;
+
+  public ClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws CacheCorruptedException {
+    try {
+      final int qName = symbolTable.getId(reader.getQualifiedName());
+      myQualifiedName = qName;
+
+      final String genericSignature = reader.getGenericSignature();
+      myGenericSignature = genericSignature != null? symbolTable.getId(genericSignature) : -1;
+
+      myPath = reader.getPath();
+
+      final String superClass = reader.getSuperClass();
+      final int superQName = "".equals(superClass)? -1 : symbolTable.getId(superClass);
+      mySuperQualifiedName = superQName;
+
+      LOG.assertTrue(superQName != qName);
+
+      final String[] superInterfaces = reader.getSuperInterfaces();
+      mySuperInterfaces = ArrayUtil.newIntArray(superInterfaces.length);
+      for (int idx = 0; idx < superInterfaces.length; idx++) {
+        mySuperInterfaces[idx] = symbolTable.getId(superInterfaces[idx]);
+      }
+
+      final String sourceFileName = reader.getSourceFileName();
+      mySourceFileName = sourceFileName != null? sourceFileName : "";
+
+      myFlags = reader.getAccessFlags();
+
+      myRuntimeVisibleAnnotations = reader.getRuntimeVisibleAnnotations();
+      myRuntimeInvisibleAnnotations = reader.getRuntimeInvisibleAnnotations();
+
+      final Collection<ReferenceInfo> refs = reader.getReferences();
+      myReferences = refs.toArray(new ReferenceInfo[refs.size()]);
+
+      myFields = reader.getFields();
+      myMethods = reader.getMethods();
+    }
+    catch (ClsFormatException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public ClassInfo(DataInput in) throws IOException {
+    myQualifiedName = in.readInt();
+    mySuperQualifiedName = in.readInt();
+    myGenericSignature = in.readInt();
+    myFlags = in.readInt();
+    myPath = in.readUTF();
+    mySourceFileName = in.readUTF();
+
+    final int ifaceCount = in.readInt();
+    mySuperInterfaces = new int[ifaceCount];
+    for (int idx = 0; idx < ifaceCount; idx++) {
+      mySuperInterfaces[idx] = in.readInt();
+    }
+
+    final int fieldCount = in.readInt();
+    myFields = new FieldInfo[fieldCount];
+    for (int idx = 0; idx < fieldCount; idx++) {
+      myFields[idx] = new FieldInfo(in);
+    }
+
+    final int methodCount = in.readInt();
+    myMethods = new MethodInfo[methodCount];
+    for (int idx = 0; idx < methodCount; idx++) {
+      myMethods[idx] = new MethodInfo(in);
+    }
+
+    final int refCount = in.readInt();
+    myReferences = refCount > 0? new ReferenceInfo[refCount] : EMPTY_REF_ARRAY;
+    for (int idx = 0; idx < refCount; idx++) {
+      myReferences[idx] = MemberInfoExternalizer.loadReferenceInfo(in);
+    }
+
+    myRuntimeVisibleAnnotations = MemberInfoExternalizer.readAnnotationConstantValueArray1(in);
+    myRuntimeInvisibleAnnotations = MemberInfoExternalizer.readAnnotationConstantValueArray1(in);
+  }
+
+  public ClassInfo clone()  {
+    try {
+      return (ClassInfo)super.clone();
+    }
+    catch (CloneNotSupportedException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeInt(myQualifiedName);
+    out.writeInt(mySuperQualifiedName);
+    out.writeInt(myGenericSignature);
+    out.writeInt(myFlags);
+    out.writeUTF(myPath);
+    out.writeUTF(mySourceFileName);
+    out.writeInt(mySuperInterfaces.length);
+    for (int ifaceQName : mySuperInterfaces) {
+      out.writeInt(ifaceQName);
+    }
+
+    out.writeInt(myFields.length);
+    for (FieldInfo field : myFields) {
+      field.save(out);
+    }
+
+    out.writeInt(myMethods.length);
+    for (MethodInfo method : myMethods) {
+      method.save(out);
+    }
+
+    out.writeInt(myReferences.length);
+    for (ReferenceInfo info : myReferences) {
+      MemberInfoExternalizer.saveReferenceInfo(out, info);
+    }
+
+    MemberInfoExternalizer.writeConstantValueArray1(out, myRuntimeVisibleAnnotations);
+    MemberInfoExternalizer.writeConstantValueArray1(out, myRuntimeInvisibleAnnotations);
+  }
+
+  public boolean isDirty() {
+    return myIsDirty;
+  }
+
+  public int getQualifiedName() throws IOException {
+    return myQualifiedName;
+  }
+
+  public int getGenericSignature() throws IOException {
+    return myGenericSignature;
+  }
+
+  public int getSuperQualifiedName() throws IOException {
+    return mySuperQualifiedName;
+  }
+
+  public int[] getSuperInterfaces() throws IOException {
+    return mySuperInterfaces;
+  }
+
+  public int getFlags() throws IOException {
+    return myFlags;
+  }
+
+  public String getPath() throws IOException {
+    return myPath;
+  }
+
+  public void setPath(String path) {
+    myIsDirty |= !Comparing.equal(myPath, path);
+    myPath = path;
+  }
+
+  public String getSourceFileName() throws IOException {
+    return mySourceFileName;
+  }
+
+  public AnnotationConstantValue[] getRuntimeVisibleAnnotations() throws IOException {
+    return myRuntimeVisibleAnnotations;
+  }
+
+  public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() throws IOException {
+    return myRuntimeInvisibleAnnotations;
+  }
+
+  public ReferenceInfo[] getReferences() {
+    return myReferences;
+  }
+
+  public void clearReferences() {
+    myReferences = EMPTY_REF_ARRAY;
+  }
+
+  public FieldInfo[] getFields() {
+    return myFields;
+  }
+
+  public MethodInfo[] getMethods() {
+    return myMethods;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfoConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfoConstantValue.java
new file mode 100644
index 0000000..a444d32
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ClassInfoConstantValue.java
@@ -0,0 +1,56 @@
+/*
+ * 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.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ClassInfoConstantValue extends ConstantValue{
+  private final int myValue;
+
+  public ClassInfoConstantValue(int value) {
+    myValue = value;
+  }
+
+  public ClassInfoConstantValue(DataInput in) throws IOException{
+    myValue = in.readInt();
+  }
+
+  public int getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeInt(myValue);
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ClassInfoConstantValue)) return false;
+
+    final ClassInfoConstantValue classInfoConstantValue = (ClassInfoConstantValue)o;
+
+    if (myValue != classInfoConstantValue.myValue) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    return myValue;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValue.java
new file mode 100644
index 0000000..31615b2
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValue.java
@@ -0,0 +1,35 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ConstantValue {
+  public static final ConstantValue EMPTY_CONSTANT_VALUE = new ConstantValue();
+
+  protected ConstantValue() {
+  }
+
+  public void save(DataOutput out) throws IOException {
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValueArray.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValueArray.java
new file mode 100644
index 0000000..850564a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ConstantValueArray.java
@@ -0,0 +1,68 @@
+/*
+ * 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.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Arrays;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 2, 2004
+ */
+public class ConstantValueArray extends ConstantValue{
+  private final ConstantValue[] myValue;
+
+  public ConstantValueArray(ConstantValue[] value) {
+    myValue = value;
+  }
+
+  public ConstantValueArray(DataInput in) throws IOException {
+    final int size = in.readInt();
+    myValue = new ConstantValue[size];
+    for (int idx = 0; idx < size; idx++) {
+      myValue[idx] = MemberInfoExternalizer.loadConstantValue(in);
+    }
+  }
+
+  public ConstantValue[] getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeInt(myValue.length);
+    for (int idx = 0; idx < myValue.length; idx++) {
+      MemberInfoExternalizer.saveConstantValue(out, myValue[idx]);
+    }
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ConstantValueArray)) return false;
+
+    final ConstantValueArray constantValueArray = (ConstantValueArray)o;
+
+    if (!Arrays.equals(myValue, constantValueArray.myValue)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    return 0;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/DoubleConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/DoubleConstantValue.java
new file mode 100644
index 0000000..7e7b8e6
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/DoubleConstantValue.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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class DoubleConstantValue extends ConstantValue{
+  private final double myValue;
+
+  public DoubleConstantValue(double value) {
+    myValue = value;
+  }
+
+  public DoubleConstantValue(DataInput in) throws IOException{
+    myValue = in.readDouble();
+  }
+
+  public double getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeDouble(myValue);
+  }
+
+  public boolean equals(Object obj) {
+    return (obj instanceof DoubleConstantValue) && (((DoubleConstantValue)obj).myValue == myValue);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/EnumConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/EnumConstantValue.java
new file mode 100644
index 0000000..548bda1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/EnumConstantValue.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class EnumConstantValue extends ConstantValue{
+  private final int myTypeName;
+  private final int myConstantName;
+
+  public EnumConstantValue(int typeName, int constantName) {
+    myTypeName = typeName;
+    myConstantName = constantName;
+  }
+
+  public EnumConstantValue(DataInput in) throws IOException{
+    myTypeName = in.readInt();
+    myConstantName = in.readInt();
+  }
+
+  public int getTypeName() {
+    return myTypeName;
+  }
+
+  public int getConstantName() {
+    return myConstantName;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeInt(myTypeName);
+    out.writeInt(myConstantName);
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof EnumConstantValue)) return false;
+
+    final EnumConstantValue enumConstantValue = (EnumConstantValue)o;
+
+    if (myConstantName != enumConstantValue.myConstantName) return false;
+    if (myTypeName != enumConstantValue.myTypeName) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = myTypeName;
+    result = 29 * result + myConstantName;
+    return result;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/FieldInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/FieldInfo.java
new file mode 100644
index 0000000..4611f08
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/FieldInfo.java
@@ -0,0 +1,55 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 10, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class FieldInfo extends MemberInfo {
+  public static final FieldInfo[] EMPTY_ARRAY = new FieldInfo[0];
+  private final ConstantValue myConstantValue;
+
+  public FieldInfo(int name, int descriptor) {
+    super(name, descriptor);
+    myConstantValue = ConstantValue.EMPTY_CONSTANT_VALUE;
+  }
+
+  public FieldInfo(int name, int descriptor, final int genericSignature, int flags, ConstantValue value, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) {
+    super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations);
+    myConstantValue = value == null ? ConstantValue.EMPTY_CONSTANT_VALUE : value;
+  }
+
+  public FieldInfo(DataInput in) throws IOException {
+    super(in);
+    myConstantValue = MemberInfoExternalizer.loadConstantValue(in);
+  }
+
+  public ConstantValue getConstantValue() {
+    return myConstantValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    MemberInfoExternalizer.saveConstantValue(out, myConstantValue);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/FloatConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/FloatConstantValue.java
new file mode 100644
index 0000000..f818cbf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/FloatConstantValue.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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class FloatConstantValue extends ConstantValue{
+  private final float myValue;
+
+  public FloatConstantValue(float value) {
+    myValue = value;
+  }
+
+  public FloatConstantValue(DataInput in) throws IOException{
+    myValue = in.readFloat();
+  }
+
+  public float getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeFloat(myValue);
+  }
+
+  public boolean equals(Object obj) {
+    return (obj instanceof FloatConstantValue) && (((FloatConstantValue)obj).myValue == myValue);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/GenericMethodSignature.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/GenericMethodSignature.java
new file mode 100644
index 0000000..10c01b4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/GenericMethodSignature.java
@@ -0,0 +1,98 @@
+/*
+ * 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.compiler.classParsing;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.util.ArrayUtil;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 4, 2004
+ */
+public class GenericMethodSignature {
+  private final String myFormalTypeParams;
+  private final String[] myParamSignatures;
+  private final String myReturnTypeSignature;
+  private final String myThrowsSignature;
+
+  private GenericMethodSignature(String formalTypeParams, String[] paramSignatures, String returnTypeSignature, String throwsSignature) {
+    myFormalTypeParams = formalTypeParams;
+    myParamSignatures = paramSignatures;
+    myReturnTypeSignature = returnTypeSignature;
+    myThrowsSignature = throwsSignature;
+  }
+
+  public String getFormalTypeParams() {
+    return myFormalTypeParams;
+  }
+
+  public String[] getParamSignatures() {
+    return myParamSignatures;
+  }
+
+  public String getReturnTypeSignature() {
+    return myReturnTypeSignature;
+  }
+
+  public String getThrowsSignature() {
+    return myThrowsSignature;
+  }
+
+  public static GenericMethodSignature parse(String methodSignature) throws SignatureParsingException {
+    final StringCharacterIterator it = new StringCharacterIterator(methodSignature);
+
+    final StringBuilder formals = new StringBuilder();
+    if (it.current() == '<') {
+      SignatureParser.INSTANCE.parseFormalTypeParameters(it, formals);
+    }
+
+    if (it.current() != '(') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "(", formals.toString()));
+    }
+
+    it.next(); // skip '('
+
+    final String[] paramSignatures;
+    if (it.current() != ')') {
+      final List<String> params = new ArrayList<String>();
+      while (it.current() != ')') {
+        final StringBuilder typeSignature = new StringBuilder();
+        SignatureParser.INSTANCE.parseTypeSignature(it, typeSignature);
+        params.add(typeSignature.toString());
+      }
+      paramSignatures = ArrayUtil.toStringArray(params);
+    }
+    else {
+      paramSignatures = ArrayUtil.EMPTY_STRING_ARRAY;
+    }
+    it.next(); // skip ')'
+
+    final StringBuilder returnTypeSignature = new StringBuilder();
+    SignatureParser.INSTANCE.parseReturnType(it, returnTypeSignature);
+
+    final StringBuilder throwsSignature = new StringBuilder();
+    if (it.current() != CharacterIterator.DONE) {
+      SignatureParser.INSTANCE.parseThrowsSignature(it, throwsSignature);
+    }
+    
+    return new GenericMethodSignature(formals.toString(), paramSignatures, returnTypeSignature.toString(), throwsSignature.toString());
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/IntegerConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/IntegerConstantValue.java
new file mode 100644
index 0000000..d59a727
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/IntegerConstantValue.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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class IntegerConstantValue extends ConstantValue{
+  private final int myValue;
+
+  public IntegerConstantValue(int value) {
+    myValue = value;
+  }
+
+  public IntegerConstantValue(DataInput in) throws IOException{
+    myValue = in.readInt();
+  }
+
+  public int getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeInt(myValue);
+  }
+
+  public boolean equals(Object obj) {
+    return (obj instanceof IntegerConstantValue) && (((IntegerConstantValue)obj).myValue == myValue);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/LongConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/LongConstantValue.java
new file mode 100644
index 0000000..2cbe2d7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/LongConstantValue.java
@@ -0,0 +1,49 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class LongConstantValue extends ConstantValue{
+  private final long myValue;
+
+  public LongConstantValue(long value) {
+    myValue = value;
+  }
+  public LongConstantValue(DataInput in) throws IOException{
+    myValue = in.readLong();
+  }
+
+  public long getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeLong(myValue);
+  }
+
+  public boolean equals(Object obj) {
+    return (obj instanceof LongConstantValue) && (((LongConstantValue)obj).myValue == myValue);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfo.java
new file mode 100644
index 0000000..3394a58
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfo.java
@@ -0,0 +1,152 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 8, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import com.intellij.util.cls.ClsUtil;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public abstract class MemberInfo {
+  public static final MemberInfo[] EMPTY_MEMBER_INFO_ARRAY = new MemberInfo[0];
+  private static final int FLAG_INFO_UNAVAILABLE = 0x8000;
+  private final int myName;
+  private final int myDescriptor;
+  private final int myGenericSignature;
+  private final int myFlags;
+  private final AnnotationConstantValue[] myRuntimeVisibleAnnotations;
+  private final AnnotationConstantValue[] myRuntimeInvisibleAnnotations;
+
+  protected MemberInfo(int name, int descriptor) {
+    this(name, descriptor, -1, FLAG_INFO_UNAVAILABLE, AnnotationConstantValue.EMPTY_ARRAY, AnnotationConstantValue.EMPTY_ARRAY);
+  }
+
+  protected MemberInfo(int name, int descriptor, int genericSignature, int flags, final AnnotationConstantValue[] runtimeVisibleAnnotations, final AnnotationConstantValue[] runtimeInvisibleAnnotations) {
+    myDescriptor = descriptor;
+    myGenericSignature = genericSignature;
+    myName = name;
+    myFlags = flags;
+    myRuntimeVisibleAnnotations = runtimeVisibleAnnotations != null? runtimeVisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY;
+    myRuntimeInvisibleAnnotations = runtimeInvisibleAnnotations != null? runtimeInvisibleAnnotations : AnnotationConstantValue.EMPTY_ARRAY;
+  }
+
+  protected MemberInfo(DataInput in) throws IOException {
+    myName = in.readInt();
+    myDescriptor = in.readInt();
+    myGenericSignature = in.readInt();
+    myFlags = in.readInt();
+    myRuntimeVisibleAnnotations = loadAnnotations(in);
+    myRuntimeInvisibleAnnotations = loadAnnotations(in);
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeInt(myName);
+    out.writeInt(myDescriptor);
+    out.writeInt(myGenericSignature);
+    out.writeInt(myFlags);
+    saveAnnotations(out, myRuntimeVisibleAnnotations);
+    saveAnnotations(out, myRuntimeInvisibleAnnotations);
+  }
+
+  public int getName() {
+    return myName;
+  }
+
+  public int getDescriptor() {
+    return myDescriptor;
+  }
+
+  public int getGenericSignature() {
+    return myGenericSignature;
+  }
+
+  public boolean isFlagInfoAvailable() {
+    return myFlags != FLAG_INFO_UNAVAILABLE;
+  }
+
+  public int getFlags() {
+    return myFlags;
+  }
+
+  public boolean isPublic() {
+    return ClsUtil.isPublic(myFlags);
+  }
+
+  public boolean isProtected() {
+    return ClsUtil.isProtected(myFlags);
+  }
+
+  public boolean isFinal() {
+    return ClsUtil.isFinal(myFlags);
+  }
+
+  public boolean isPrivate() {
+    return ClsUtil.isPrivate(myFlags);
+  }
+
+  public boolean isPackageLocal() {
+    return ClsUtil.isPackageLocal(myFlags);
+  }
+
+  public boolean isStatic() {
+    return ClsUtil.isStatic(myFlags);
+  }
+
+  public boolean equals(Object obj) {
+    if (!(obj instanceof MemberInfo)) return false;
+    MemberInfo info = (MemberInfo)obj;
+    return (myName == info.myName) && (myDescriptor == info.myDescriptor);
+  }
+
+  public int hashCode() {
+    return myName + myDescriptor;
+  }
+
+  public AnnotationConstantValue[] getRuntimeVisibleAnnotations() {
+    return myRuntimeVisibleAnnotations;
+  }
+
+  public AnnotationConstantValue[] getRuntimeInvisibleAnnotations() {
+    return myRuntimeInvisibleAnnotations;
+  }
+
+  protected final void saveAnnotations(DataOutput out, final AnnotationConstantValue[] annotations) throws IOException {
+    out.writeInt(annotations.length);
+    for (AnnotationConstantValue annotation : annotations) {
+      MemberInfoExternalizer.saveConstantValue(out, annotation);
+    }
+  }
+
+  protected final AnnotationConstantValue[] loadAnnotations(DataInput in) throws IOException {
+    final int size = in.readInt();
+    if (size == 0) {
+      return AnnotationConstantValue.EMPTY_ARRAY;
+    }
+    final AnnotationConstantValue[] annotations = new AnnotationConstantValue[size];
+    for (int idx = 0; idx < size; idx++) {
+      annotations[idx] = (AnnotationConstantValue)MemberInfoExternalizer.loadConstantValue(in);
+    }
+    return annotations;
+  }
+
+}
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfoExternalizer.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfoExternalizer.java
new file mode 100644
index 0000000..a807bd5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberInfoExternalizer.java
@@ -0,0 +1,219 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 10, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import com.intellij.openapi.diagnostic.Logger;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class MemberInfoExternalizer {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MemberInfoExternalizer");
+
+  public static final byte FIELD_INFO_TAG = 1;
+  public static final byte METHOD_INFO_TAG = 2;
+
+  public static final byte DECLARATION_INFO_TAG = 9;
+
+  public static final byte REFERENCE_INFO_TAG = 11;
+  public static final byte MEMBER_REFERENCE_INFO_TAG = 12;
+
+  public static final byte LONG_CONSTANT_TAG = 3;
+  public static final byte FLOAT_CONSTANT_TAG = 4;
+  public static final byte DOUBLE_CONSTANT_TAG = 5;
+  public static final byte INTEGER_CONSTANT_TAG = 6;
+  public static final byte STRING_CONSTANT_TAG = 7;
+  public static final byte CONSTANT_TAG = 8;
+  public static final byte ANNOTATION_CONSTANT_TAG = 13;
+  public static final byte ANNOTATION_PRIMITIVE_CONSTANT_TAG = 14;
+  public static final byte CONSTANT_VALUE_ARRAY_TAG = 15;
+  public static final byte CLASS_CONSTANT_VALUE_TAG = 16;
+  public static final byte ENUM_CONSTANT_VALUE_TAG = 17;
+
+  public static MemberInfo loadMemberInfo(DataInput in) throws IOException {
+    byte tag = in.readByte();
+    if (tag == METHOD_INFO_TAG) {
+      return new MethodInfo(in);
+    }
+    else if (tag == FIELD_INFO_TAG) {
+      return new FieldInfo(in);
+    }
+    LOG.error("Unknown member info");
+    return null;
+  }
+
+  public static ReferenceInfo loadReferenceInfo(DataInput in) throws IOException {
+    final byte tag = in.readByte();
+    if (tag == REFERENCE_INFO_TAG) {
+      return new ReferenceInfo(in);
+    }
+    else if (tag == MEMBER_REFERENCE_INFO_TAG) {
+      return new MemberReferenceInfo(in);
+    }
+    LOG.error("Unknown declaration info tag: " + tag);
+    return null;
+  }
+
+  public static ConstantValue loadConstantValue(DataInput in) throws IOException {
+    final byte tag = in.readByte();
+    if (tag == LONG_CONSTANT_TAG) {
+      return new LongConstantValue(in);
+    }
+    else if (tag == FLOAT_CONSTANT_TAG) {
+      return new FloatConstantValue(in);
+    }
+    else if (tag == DOUBLE_CONSTANT_TAG) {
+      return new DoubleConstantValue(in);
+    }
+    else if (tag == INTEGER_CONSTANT_TAG) {
+      return new IntegerConstantValue(in);
+    }
+    else if (tag == STRING_CONSTANT_TAG) {
+      return new StringConstantValue(in);
+    }
+    else if (tag == CONSTANT_TAG) {
+      return ConstantValue.EMPTY_CONSTANT_VALUE;
+    }
+    else if (tag == ANNOTATION_CONSTANT_TAG) {
+      return new AnnotationConstantValue(in);
+    }
+    else if (tag == ANNOTATION_PRIMITIVE_CONSTANT_TAG) {
+      return new AnnotationPrimitiveConstantValue(in);
+    }
+    else if (tag == CONSTANT_VALUE_ARRAY_TAG) {
+      return new ConstantValueArray(in);
+    }
+    else if (tag == CLASS_CONSTANT_VALUE_TAG) {
+      return new ClassInfoConstantValue(in);
+    }
+    else if (tag == ENUM_CONSTANT_VALUE_TAG) {
+      return new EnumConstantValue(in);
+    }
+    LOG.error("Unknown constant value type " + tag);
+    return null;
+  }
+
+  public static void saveMemberInfo(DataOutput out, MemberInfo info) throws IOException {
+    if (info instanceof MethodInfo) {
+      out.writeByte(METHOD_INFO_TAG);
+    }
+    else if (info instanceof FieldInfo){
+      out.writeByte(FIELD_INFO_TAG);
+    }
+    else {
+      LOG.error("Unknown member info");
+    }
+    info.save(out);
+  }
+
+  public static void saveReferenceInfo(DataOutput out, ReferenceInfo info) throws IOException {
+    if (info instanceof MemberReferenceInfo) {
+      out.writeByte(MEMBER_REFERENCE_INFO_TAG);
+    }
+    else{
+      out.writeByte(REFERENCE_INFO_TAG);
+    }
+    info.save(out);
+  }
+
+  public static void saveConstantValue(DataOutput out, ConstantValue value) throws IOException {
+    if (value instanceof LongConstantValue) {
+      out.writeByte(LONG_CONSTANT_TAG);
+    }
+    else if (value instanceof FloatConstantValue){
+      out.writeByte(FLOAT_CONSTANT_TAG);
+    }
+    else if (value instanceof DoubleConstantValue){
+      out.writeByte(DOUBLE_CONSTANT_TAG);
+    }
+    else if (value instanceof IntegerConstantValue){
+      out.writeByte(INTEGER_CONSTANT_TAG);
+    }
+    else if (value instanceof StringConstantValue){
+      out.writeByte(STRING_CONSTANT_TAG);
+    }
+    else if (value instanceof AnnotationConstantValue) {
+      out.writeByte(ANNOTATION_CONSTANT_TAG);
+    }
+    else if (value instanceof AnnotationPrimitiveConstantValue) {
+      out.writeByte(ANNOTATION_PRIMITIVE_CONSTANT_TAG);
+    }
+    else if (value instanceof ConstantValueArray) {
+      out.writeByte(CONSTANT_VALUE_ARRAY_TAG);
+    }
+    else if (value instanceof ClassInfoConstantValue) {
+      out.writeByte(CLASS_CONSTANT_VALUE_TAG);
+    }
+    else if (value instanceof EnumConstantValue) {
+      out.writeByte(ENUM_CONSTANT_VALUE_TAG);
+    }
+    else {
+      out.writeByte(CONSTANT_TAG);
+    }
+    if (value != null) {
+      value.save(out);
+    }
+  }
+
+  public static AnnotationConstantValue[] readAnnotationConstantValueArray1(DataInput in) throws IOException {
+    final int size = in.readInt();
+    final AnnotationConstantValue[] array = size > 0? new AnnotationConstantValue[size] : AnnotationConstantValue.EMPTY_ARRAY;
+    for (int idx = 0; idx < size; idx++) {
+      array[idx] = (AnnotationConstantValue)loadConstantValue(in);
+    }
+    return array;
+  }
+
+  public static AnnotationConstantValue[][] readAnnotationConstantValueArray2(DataInput in) throws IOException {
+    final int size = in.readInt();
+    final AnnotationConstantValue[][] array = size > 0? new AnnotationConstantValue[size][] : AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
+    for (int idx = 0; idx < size; idx++) {
+      array[idx] = readAnnotationConstantValueArray1(in);
+    }
+    return array;
+  }
+
+  public static void writeConstantValueArray1(DataOutput writer, final ConstantValue[] array) throws IOException {
+    if (array != null && array.length > 0) {
+      writer.writeInt(array.length);
+      for (ConstantValue value : array) {
+        saveConstantValue(writer, value);
+      }
+    }
+    else {
+      writer.writeInt(0);
+    }
+  }
+
+  public static void writeConstantValueArray2(DataOutput writer, final ConstantValue[][] array) throws IOException {
+    if (array != null && array.length > 0) {
+      writer.writeInt(array.length);
+      for (ConstantValue[] aArray : array) {
+        writeConstantValueArray1(writer, aArray);
+      }
+    }
+    else {
+      writer.writeInt(0);
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberReferenceInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberReferenceInfo.java
new file mode 100644
index 0000000..63d7c54
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/MemberReferenceInfo.java
@@ -0,0 +1,73 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 8, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import org.jetbrains.annotations.NonNls;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class MemberReferenceInfo extends ReferenceInfo {
+  private final MemberInfo myMemberInfo;
+
+  public MemberReferenceInfo(int declaringClass, MemberInfo memberInfo) {
+    super(declaringClass);
+    myMemberInfo = memberInfo;
+  }
+
+  public MemberReferenceInfo(DataInput in) throws IOException {
+    super(in);
+    myMemberInfo = MemberInfoExternalizer.loadMemberInfo(in);
+  }
+
+  public MemberInfo getMemberInfo() {
+    return myMemberInfo;
+  }
+
+  public boolean isFieldReference() {
+    return myMemberInfo instanceof FieldInfo;
+  }
+
+  public boolean isMethodReference() {
+    return myMemberInfo instanceof MethodInfo;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    MemberInfoExternalizer.saveMemberInfo(out, myMemberInfo);
+  }
+
+  public boolean equals(Object o) {
+    if (!super.equals(o)) {
+      return false;
+    }
+    return myMemberInfo.equals(((MemberReferenceInfo)o).myMemberInfo);
+  }
+
+  public int hashCode() {
+    return super.hashCode() + myMemberInfo.hashCode();
+  }
+
+  public @NonNls String toString() { // for debug purposes
+    return "Member reference: [class name=" + getClassName() + ", member name = " + myMemberInfo.getName() + ", member descriptor=" + myMemberInfo.getDescriptor() + ", member signature=" + myMemberInfo.getGenericSignature() + "]";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/MethodInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/MethodInfo.java
new file mode 100644
index 0000000..c18d9ae
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/MethodInfo.java
@@ -0,0 +1,263 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 10, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.compiler.make.CacheUtils;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.cls.ClsUtil;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.ArrayList;
+
+public class MethodInfo extends MemberInfo {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.classParsing.MethodInfo");
+
+  private static final int[] EXCEPTION_INFO_UNAVAILABLE = ArrayUtil.EMPTY_INT_ARRAY;
+  public static final MethodInfo[] EMPTY_ARRAY = new MethodInfo[0];
+
+  private final int[] myThrownExceptions;
+  // cached (lazy initialized) data
+  private String mySignature = null;
+  private String[] myParameterDescriptors = null;
+  private String myReturnTypeSignature = null;
+  private final boolean myIsConstructor;
+  private final AnnotationConstantValue[][] myRuntimeVisibleParameterAnnotations;
+  private final AnnotationConstantValue[][] myRuntimeInvisibleParameterAnnotations;
+  private final ConstantValue myAnnotationDefault;
+
+  public MethodInfo(int name, int descriptor, boolean isConstructor) {
+    super(name, descriptor);
+    myIsConstructor = isConstructor;
+    myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE;
+    myRuntimeVisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
+    myRuntimeInvisibleParameterAnnotations = AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
+    myAnnotationDefault = ConstantValue.EMPTY_CONSTANT_VALUE;
+  }
+
+  public MethodInfo(int name,
+                    int descriptor,
+                    final int genericSignature,
+                    int flags,
+                    int[] exceptions,
+                    boolean isConstructor,
+                    final AnnotationConstantValue[] runtimeVisibleAnnotations,
+                    final AnnotationConstantValue[] runtimeInvisibleAnnotations,
+                    final AnnotationConstantValue[][] runtimeVisibleParameterAnnotations,
+                    final AnnotationConstantValue[][] runtimeInvisibleParameterAnnotations, ConstantValue annotationDefault) {
+
+    super(name, descriptor, genericSignature, flags, runtimeVisibleAnnotations, runtimeInvisibleAnnotations);
+    myThrownExceptions = exceptions != null? exceptions : ArrayUtil.EMPTY_INT_ARRAY;
+    myIsConstructor = isConstructor;
+    myRuntimeVisibleParameterAnnotations = runtimeVisibleParameterAnnotations == null? AnnotationConstantValue.EMPTY_ARRAY_ARRAY : runtimeVisibleParameterAnnotations; 
+    myRuntimeInvisibleParameterAnnotations = runtimeInvisibleParameterAnnotations == null? AnnotationConstantValue.EMPTY_ARRAY_ARRAY : runtimeInvisibleParameterAnnotations;
+    myAnnotationDefault = annotationDefault;
+  }
+
+  public MethodInfo(DataInput in) throws IOException {
+    super(in);
+    myIsConstructor = in.readBoolean();
+    int count = in.readInt();
+    if (count == -1) {
+      myThrownExceptions = EXCEPTION_INFO_UNAVAILABLE;
+    }
+    else {
+      myThrownExceptions = ArrayUtil.newIntArray(count);
+      for (int idx = 0; idx < count; idx++) {
+        myThrownExceptions[idx] = in.readInt();
+      }
+    }
+    myRuntimeVisibleParameterAnnotations = loadParameterAnnotations(in);
+    myRuntimeInvisibleParameterAnnotations = loadParameterAnnotations(in);
+    myAnnotationDefault = MemberInfoExternalizer.loadConstantValue(in);
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeBoolean(myIsConstructor);
+    if (isExceptionInfoAvailable()) {
+      out.writeInt(myThrownExceptions.length);
+    }
+    else {
+      out.writeInt(-1);
+    }
+    for (int thrownException : myThrownExceptions) {
+      out.writeInt(thrownException);
+    }
+    saveParameterAnnotations(out, myRuntimeVisibleParameterAnnotations);
+    saveParameterAnnotations(out, myRuntimeInvisibleParameterAnnotations);
+    MemberInfoExternalizer.saveConstantValue(out, myAnnotationDefault);
+  }
+
+  private boolean isExceptionInfoAvailable() {
+    return myThrownExceptions != EXCEPTION_INFO_UNAVAILABLE;
+  }
+
+  public boolean areExceptionsEqual(MethodInfo info) {
+    if (myThrownExceptions.length != info.myThrownExceptions.length) {
+      return false;
+    }
+    if (myThrownExceptions.length != 0) { // optimization
+      TIntHashSet exceptionsSet = new TIntHashSet();
+      for (int thrownException : myThrownExceptions) {
+        exceptionsSet.add(thrownException);
+      }
+      for (int exception : info.myThrownExceptions) {
+        if (!exceptionsSet.contains(exception)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  public int[] getThrownExceptions() {
+    return myThrownExceptions;
+  }
+
+  public String getDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
+    if (mySignature == null) {
+      final String descriptor = symbolTable.getSymbol(getDescriptor());
+      final String name = symbolTable.getSymbol(getName());
+      mySignature = CacheUtils.getMethodSignature(name, descriptor);
+    }
+    return mySignature;
+  }
+
+  public String getReturnTypeDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
+    if (myReturnTypeSignature == null) {
+      String descriptor = symbolTable.getSymbol(getDescriptor());
+      myReturnTypeSignature = descriptor.substring(descriptor.indexOf(')') + 1, descriptor.length());
+    }
+    return myReturnTypeSignature;
+  }
+
+  public String[] getParameterDescriptors(SymbolTable symbolTable) throws CacheCorruptedException {
+    if (myParameterDescriptors == null) {
+      String descriptor = symbolTable.getSymbol(getDescriptor());
+      int endIndex = descriptor.indexOf(')');
+      if (endIndex <= 0) {
+        LOG.error("Corrupted method descriptor: " + descriptor);
+      }
+      myParameterDescriptors = parseParameterDescriptors(descriptor.substring(1, endIndex));
+    }
+    return myParameterDescriptors;
+  }
+
+  public boolean isAbstract() {
+    return ClsUtil.isAbstract(getFlags());
+  }
+
+  public boolean isConstructor() {
+    return myIsConstructor;
+  }
+
+  private String[] parseParameterDescriptors(String signature) {
+    ArrayList<String> list = new ArrayList<String>();
+    String paramSignature = parseFieldType(signature);
+    while (paramSignature != null && !"".equals(paramSignature)) {
+      list.add(paramSignature);
+      signature = signature.substring(paramSignature.length());
+      paramSignature = parseFieldType(signature);
+    }
+    return ArrayUtil.toStringArray(list);
+  }
+
+  private @NonNls String parseFieldType(@NonNls String signature) {
+    if (signature.length() == 0) {
+      return null;
+    }
+    if (signature.charAt(0) == 'B') {
+      return "B";
+    }
+    if (signature.charAt(0) == 'C') {
+      return "C";
+    }
+    if (signature.charAt(0) == 'D') {
+      return "D";
+    }
+    if (signature.charAt(0) == 'F') {
+      return "F";
+    }
+    if (signature.charAt(0) == 'I') {
+      return "I";
+    }
+    if (signature.charAt(0) == 'J') {
+      return "J";
+    }
+    if (signature.charAt(0) == 'S') {
+      return "S";
+    }
+    if (signature.charAt(0) == 'Z') {
+      return "Z";
+    }
+    if (signature.charAt(0) == 'L') {
+      return signature.substring(0, signature.indexOf(";") + 1);
+    }
+    if (signature.charAt(0) == '[') {
+      String s = parseFieldType(signature.substring(1));
+      return (s != null)? ("[" + s) : null;
+    }
+    return null;
+  }
+
+  public AnnotationConstantValue[][] getRuntimeVisibleParameterAnnotations() {
+    return myRuntimeVisibleParameterAnnotations;
+  }
+
+  public AnnotationConstantValue[][] getRuntimeInvisibleParameterAnnotations() {
+    return myRuntimeInvisibleParameterAnnotations;
+  }
+
+  public String toString() {
+    return mySignature;
+  }
+
+  private AnnotationConstantValue[][] loadParameterAnnotations(DataInput in) throws IOException {
+    final int size = in.readInt();
+    if (size == 0) {
+      return AnnotationConstantValue.EMPTY_ARRAY_ARRAY;
+    }
+    final AnnotationConstantValue[][] paramAnnotations = new AnnotationConstantValue[size][];
+    for (int idx = 0; idx < size; idx++) {
+      paramAnnotations[idx] = loadAnnotations(in);
+    }
+    return paramAnnotations;
+  }
+
+  private void saveParameterAnnotations(DataOutput out, AnnotationConstantValue[][] parameterAnnotations) throws IOException {
+    out.writeInt(parameterAnnotations.length);
+    for (AnnotationConstantValue[] parameterAnnotation : parameterAnnotations) {
+      saveAnnotations(out, parameterAnnotation);
+    }
+  }
+
+  public ConstantValue getAnnotationDefault() {
+    return myAnnotationDefault;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/ReferenceInfo.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/ReferenceInfo.java
new file mode 100644
index 0000000..3cf9a19
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/ReferenceInfo.java
@@ -0,0 +1,65 @@
+/*
+ * 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
+ */
+package com.intellij.compiler.classParsing;
+
+import org.jetbrains.annotations.NonNls;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class ReferenceInfo {
+  private final int myClassName;
+
+  public ReferenceInfo(int declaringClassName) {
+    myClassName = declaringClassName;
+  }
+
+  public ReferenceInfo(DataInput in) throws IOException {
+    this(in.readInt());
+  }
+
+  public @NonNls String toString() { // for debug purposes
+    return "Class reference[class name=" + String.valueOf(getClassName()) + "]";
+  }
+
+  public void save(DataOutput out) throws IOException {
+    out.writeInt(myClassName);
+  }
+
+  public int getClassName() {
+    return myClassName;
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ReferenceInfo that = (ReferenceInfo)o;
+
+    if (myClassName != that.myClassName) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    return myClassName;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParser.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParser.java
new file mode 100644
index 0000000..d195cf3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParser.java
@@ -0,0 +1,259 @@
+/*
+ * 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.compiler.classParsing;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+
+import java.text.CharacterIterator;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 4, 2004
+ */
+
+public class SignatureParser {
+  public static final SignatureParser INSTANCE = new SignatureParser();
+
+  public void parseIdentifier(CharacterIterator it, final StringBuilder buf) {
+    while (Character.isJavaIdentifierPart(it.current())) {
+      buf.append(it.current());
+      it.next();
+    }
+  }
+
+  public void parseFormalTypeParameters(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() != '<') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "<", buf.toString()));
+    }
+
+    buf.append(it.current()); // skip '<'
+    it.next();
+
+    while (it.current() != '>') {
+      parseFormalTypeParameter(it, buf);
+    }
+
+    buf.append(it.current());
+    it.next();
+  }
+
+  public void parseFormalTypeParameter(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    parseIdentifier(it, buf);
+    parseClassBound(it, buf);
+    while (it.current() == ':') {
+      parseInterfaceBound(it, buf);
+    }
+  }
+
+  public void parseClassBound(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() != ':') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ":", buf.toString()));
+    }
+    buf.append(it.current());
+    it.next();
+
+    final char current = it.current();
+    if (current != CharacterIterator.DONE && current != ':') {
+      parseFieldTypeSignature(it, buf);
+    }
+  }
+
+  public void parseInterfaceBound(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() != ':') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ":", buf.toString()));
+    }
+    buf.append(it.current());
+    it.next();
+    parseFieldTypeSignature(it, buf);
+  }
+
+  public void parseSuperclassSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    parseClassTypeSignature(it, buf);
+  }
+
+  public void parseSuperinterfaceSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    parseClassTypeSignature(it, buf);
+  }
+
+  public void parseFieldTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() == 'L') {
+      parseClassTypeSignature(it, buf);
+    }
+    else if (it.current() == '[') {
+      parseArrayTypeSignature(it, buf);
+    }
+    else if (it.current() == 'T') {
+      parseTypeVariableSignature(it, buf);
+    }
+    else {
+      //noinspection HardCodedStringLiteral
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "'L' / '[' / 'T'", buf.toString()));
+    }
+  }
+
+  public void parseClassTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    buf.append(it.current());
+    it.next();     // consume 'L'
+    parseSimpleClassTypeSignature(it, buf);
+    while (it.current() == '/' || it.current() == '.') { // Eclipse compiler generates '.' for inner classes 
+      parseClassTypeSignatureSuffix(it, buf);
+    }
+    if (it.current() != ';') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ";", buf.toString()));
+    }
+    buf.append(it.current());
+    it.next(); // consume ';'
+  }
+
+  public void parseSimpleClassTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    parseIdentifier(it, buf);
+    if (it.current() == '<') {
+      parseTypeArguments(it, buf);
+    }
+  }
+
+  public void parseClassTypeSignatureSuffix(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    buf.append(it.current());
+    it.next();
+    parseSimpleClassTypeSignature(it, buf);
+  }
+
+  public void parseTypeVariableSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    buf.append(it.current());
+    it.next(); // consume 'T'
+    parseIdentifier(it, buf);
+    if (it.current() != ';') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", ";", buf.toString()));
+    }
+    buf.append(it.current());
+    it.next(); // consume ';'
+  }
+
+  public void parseTypeArguments(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    buf.append(it.current());
+    it.next(); // consume '<'
+    while (it.current() != '>') {
+      parseTypeArgument(it, buf);
+    }
+    buf.append(it.current());
+    it.next(); // consume '>'
+  }
+
+  public void parseTypeArgument(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() == '*') {
+      parseWildcardIndicator(it, buf);
+    }
+    else {
+      if (it.current() == '+' || it.current() == '-') {
+        parseWildcardIndicator(it, buf);
+      }
+      parseFieldTypeSignature(it, buf);
+    }
+  }
+
+  public void parseWildcardIndicator(CharacterIterator it, final StringBuilder buf) {
+    buf.append(it.current());
+    it.next();
+  }
+
+  public void parseArrayTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    buf.append(it.current());
+    it.next(); // consume '['
+    parseTypeSignature(it, buf);
+  }
+
+  public void parseTypeSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    char current = it.current();
+    if (current == 'B' || current == 'C' || current == 'D' || current == 'F' || current == 'I' || current == 'J' || current == 'S' || current == 'Z') {
+      buf.append(it.current());
+      it.next(); // base type
+    }
+    else if (current == 'L' || current == '[' || current == 'T') {
+      parseFieldTypeSignature(it, buf);
+    }
+    else {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.unknown.type.signature"));
+    }
+  }
+
+  public void parseReturnType(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() == 'V') {
+      buf.append(it.current());
+      it.next();
+    }
+    else {
+      parseTypeSignature(it, buf);
+    }
+  }
+
+  public void parseThrowsSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() != '^') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "^", buf.toString()));
+    }
+    buf.append(it.current());
+    it.next();
+    if (it.current() == 'T') {
+      parseTypeVariableSignature(it, buf);
+    }
+    else {
+      parseClassTypeSignature(it, buf);
+    }
+  }
+
+  public void parseMethodSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() == '<') {
+      parseFormalTypeParameters(it, buf);
+    }
+
+    if (it.current() != '(') {
+      throw new SignatureParsingException(CompilerBundle.message("error.signature.parsing.expected.other.symbol", "(", buf.toString()));
+    }
+
+    buf.append(it.current());
+    it.next(); // skip '('
+
+    while (it.current() != ')') {
+      parseTypeSignature(it, buf);
+    }
+
+    buf.append(it.current());
+    it.next(); // skip ')'
+
+    parseReturnType(it, buf);
+
+    if (it.current() != CharacterIterator.DONE) {
+      parseThrowsSignature(it, buf);
+    }
+  }
+
+  public void parseClassSignature(CharacterIterator it, final StringBuilder buf) throws SignatureParsingException {
+    if (it.current() == '<') {
+      buf.append(it.current());
+      it.next();
+      while (it.current() != '>') {
+        parseFormalTypeParameter(it, buf);
+      }
+      buf.append(it.current());
+      it.next();
+    }
+
+    parseClassTypeSignature(it, buf);
+
+    while (it.current() != CharacterIterator.DONE) {
+      parseClassTypeSignature(it, buf);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParsingException.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParsingException.java
new file mode 100644
index 0000000..7246b19
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/SignatureParsingException.java
@@ -0,0 +1,26 @@
+/*
+ * 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.compiler.classParsing;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 4, 2004
+ */
+public class SignatureParsingException extends Exception{
+  public SignatureParsingException(String message) {
+    super(message);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/classParsing/StringConstantValue.java b/java/compiler/impl/src/com/intellij/compiler/classParsing/StringConstantValue.java
new file mode 100644
index 0000000..faf560f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/classParsing/StringConstantValue.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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.classParsing;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+public class StringConstantValue extends ConstantValue{
+  private final String myValue;
+
+  public StringConstantValue(String value) {
+    myValue = value;
+  }
+
+  public StringConstantValue(DataInput in) throws IOException{
+    myValue = in.readUTF();
+  }
+
+  public String getValue() {
+    return myValue;
+  }
+
+  public void save(DataOutput out) throws IOException {
+    super.save(out);
+    out.writeUTF(myValue);
+  }
+
+  public boolean equals(Object obj) {
+    return
+      (obj instanceof StringConstantValue) &&
+      ((myValue == null)? ((StringConstantValue)obj).myValue == null : myValue.equals(((StringConstantValue)obj).myValue));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java b/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.java
new file mode 100644
index 0000000..0b9ed31
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/AdditionalCompileScopeProvider.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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompilerFilter;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class AdditionalCompileScopeProvider {
+  public static final ExtensionPointName<AdditionalCompileScopeProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.additionalCompileScopeProvider");
+
+  @Nullable
+  public abstract CompileScope getAdditionalScope(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull Project project);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java
new file mode 100644
index 0000000..2f55990
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/BuildTargetScopeProvider.java
@@ -0,0 +1,38 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerFilter;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+
+/**
+ * @author nik
+ */
+public abstract class BuildTargetScopeProvider {
+  public static final ExtensionPointName<BuildTargetScopeProvider> EP_NAME = ExtensionPointName.create("com.intellij.compiler.buildTargetScopeProvider");
+
+  @NotNull
+  public abstract List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull CompileScope baseScope, @NotNull CompilerFilter filter,
+                                                                  @NotNull Project project);
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java
new file mode 100644
index 0000000..7341089
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextExProxy.java
@@ -0,0 +1,174 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessage;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 4, 2007
+ */
+public class CompileContextExProxy implements CompileContextEx {
+  private final CompileContextEx myDelegate;
+
+  public CompileContextExProxy(CompileContextEx delegate) {
+    myDelegate = delegate;
+  }
+
+  public Project getProject() {
+    return myDelegate.getProject();
+  }
+
+  public DependencyCache getDependencyCache() {
+    return myDelegate.getDependencyCache();
+  }
+
+  public VirtualFile getSourceFileByOutputFile(final VirtualFile outputFile) {
+    return myDelegate.getSourceFileByOutputFile(outputFile);
+  }
+
+  public void addMessage(final CompilerMessage message) {
+    myDelegate.addMessage(message);
+  }
+
+  @NotNull
+  public Set<VirtualFile> getTestOutputDirectories() {
+    return myDelegate.getTestOutputDirectories();
+  }
+
+  public boolean isInTestSourceContent(@NotNull final VirtualFile fileOrDir) {
+    return myDelegate.isInTestSourceContent(fileOrDir);
+  }
+
+  public boolean isInSourceContent(@NotNull final VirtualFile fileOrDir) {
+    return myDelegate.isInSourceContent(fileOrDir);
+  }
+
+  public void addScope(final CompileScope additionalScope) {
+    myDelegate.addScope(additionalScope);
+  }
+
+  public void addMessage(final CompilerMessageCategory category,
+                         final String message, @Nullable final String url, final int lineNum, final int columnNum) {
+    myDelegate.addMessage(category, message, url, lineNum, columnNum);
+  }
+
+  public void addMessage(final CompilerMessageCategory category, final String message, @Nullable final String url,
+                         final int lineNum,
+                         final int columnNum,
+                         final Navigatable navigatable) {
+    myDelegate.addMessage(category, message, url, lineNum, columnNum, navigatable);
+  }
+
+  public CompilerMessage[] getMessages(final CompilerMessageCategory category) {
+    return myDelegate.getMessages(category);
+  }
+
+  public int getMessageCount(final CompilerMessageCategory category) {
+    return myDelegate.getMessageCount(category);
+  }
+
+  public ProgressIndicator getProgressIndicator() {
+    return myDelegate.getProgressIndicator();
+  }
+
+  public CompileScope getCompileScope() {
+    return myDelegate.getCompileScope();
+  }
+
+  public CompileScope getProjectCompileScope() {
+    return myDelegate.getProjectCompileScope();
+  }
+
+  public void requestRebuildNextTime(final String message) {
+    myDelegate.requestRebuildNextTime(message);
+  }
+
+  public Module getModuleByFile(final VirtualFile file) {
+    return myDelegate.getModuleByFile(file);
+  }
+
+  public VirtualFile[] getSourceRoots(final Module module) {
+    return myDelegate.getSourceRoots(module);
+  }
+
+  public VirtualFile[] getAllOutputDirectories() {
+    return myDelegate.getAllOutputDirectories();
+  }
+
+  public VirtualFile getModuleOutputDirectory(final Module module) {
+    return myDelegate.getModuleOutputDirectory(module);
+  }
+
+  public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
+    return myDelegate.getModuleOutputDirectoryForTests(module);
+  }
+
+  public boolean isMake() {
+    return myDelegate.isMake();
+  }
+
+  public boolean isAnnotationProcessorsEnabled() {
+    return myDelegate.isAnnotationProcessorsEnabled();
+  }
+
+  public boolean isRebuild() {
+    return myDelegate.isRebuild();
+  }
+
+  public <T> T getUserData(@NotNull final Key<T> key) {
+    return myDelegate.getUserData(key);
+  }
+
+  public <T> void putUserData(@NotNull final Key<T> key, final T value) {
+    myDelegate.putUserData(key, value);
+  }
+
+  public void recalculateOutputDirs() {
+    myDelegate.recalculateOutputDirs();
+  }
+
+  public void markGenerated(Collection<VirtualFile> files) {
+    myDelegate.markGenerated(files);
+  }
+
+  public boolean isGenerated(VirtualFile file) {
+    return myDelegate.isGenerated(file);
+  }
+
+  public long getStartCompilationStamp() {
+    return myDelegate.getStartCompilationStamp();
+  }
+
+  public void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource, com.intellij.openapi.compiler.Compiler compiler) {
+    myDelegate.assignModule(root, module, isTestSource, compiler);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
new file mode 100644
index 0000000..298ce1a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileContextImpl.java
@@ -0,0 +1,480 @@
+/*
+ * 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: Jan 21, 2003
+ * Time: 4:19:03 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerMessageImpl;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.compiler.progress.CompilerTask;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.pom.Navigatable;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.HashSet;
+import com.intellij.util.containers.OrderedSet;
+import com.intellij.util.indexing.FileBasedIndex;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.*;
+
+public class CompileContextImpl extends UserDataHolderBase implements CompileContextEx {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileContextImpl");
+  private final Project myProject;
+  private final CompilerTask myTask;
+  private final Map<CompilerMessageCategory, Collection<CompilerMessage>> myMessages = new EnumMap<CompilerMessageCategory, Collection<CompilerMessage>>(CompilerMessageCategory.class);
+  private final boolean myShouldUpdateProblemsView;
+  private CompileScope myCompileScope;
+  private final DependencyCache myDependencyCache;
+  private final boolean myMake;
+  private final boolean myIsRebuild;
+  private final boolean myIsAnnotationProcessorsEnabled;
+  private boolean myRebuildRequested = false;
+  private String myRebuildReason;
+  private final Map<VirtualFile, Module> myRootToModuleMap = new HashMap<VirtualFile, Module>();
+  private final Map<Module, Set<VirtualFile>> myModuleToRootsMap = new HashMap<Module, Set<VirtualFile>>();
+  private final Map<VirtualFile, Pair<SourceGeneratingCompiler, Module>> myOutputRootToSourceGeneratorMap = new HashMap<VirtualFile, Pair<SourceGeneratingCompiler, Module>>();
+  private final Set<VirtualFile> myGeneratedTestRoots = new java.util.HashSet<VirtualFile>();
+  private VirtualFile[] myOutputDirectories;
+  private Set<VirtualFile> myTestOutputDirectories;
+  private final TIntHashSet myGeneratedSources = new TIntHashSet();
+  private final ProjectFileIndex myProjectFileIndex; // cached for performance reasons
+  private final ProjectCompileScope myProjectCompileScope;
+  private final long myStartCompilationStamp;
+  private final UUID mySessionId = UUID.randomUUID();
+
+  public CompileContextImpl(final Project project,
+                            final CompilerTask compilerSession,
+                            CompileScope compileScope,
+                            DependencyCache dependencyCache, boolean isMake, boolean isRebuild) {
+    myProject = project;
+    myTask = compilerSession;
+    myCompileScope = compileScope;
+    myDependencyCache = dependencyCache;
+    myMake = isMake;
+    myIsRebuild = isRebuild;
+    myStartCompilationStamp = System.currentTimeMillis();
+    myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+    myProjectCompileScope = new ProjectCompileScope(myProject);
+    myIsAnnotationProcessorsEnabled = CompilerConfiguration.getInstance(project).isAnnotationProcessorsEnabled();
+
+    if (compilerSession != null) {
+      compilerSession.setContentIdKey(compileScope.getUserData(CompilerManager.CONTENT_ID_KEY));
+    }
+    recalculateOutputDirs();
+    final CompilerWorkspaceConfiguration workspaceConfig = CompilerWorkspaceConfiguration.getInstance(myProject);
+    myShouldUpdateProblemsView = workspaceConfig.useOutOfProcessBuild() && workspaceConfig.MAKE_PROJECT_ON_SAVE;
+  }
+
+  public boolean shouldUpdateProblemsView() {
+    return myShouldUpdateProblemsView;
+  }
+
+  public void recalculateOutputDirs() {
+    final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
+
+    final Set<VirtualFile> allDirs = new OrderedSet<VirtualFile>();
+    final Set<VirtualFile> testOutputDirs = new java.util.HashSet<VirtualFile>();
+    final Set<VirtualFile> productionOutputDirs = new java.util.HashSet<VirtualFile>();
+
+    for (Module module : allModules) {
+      final CompilerModuleExtension manager = CompilerModuleExtension.getInstance(module);
+      final VirtualFile output = manager.getCompilerOutputPath();
+      if (output != null && output.isValid()) {
+        allDirs.add(output);
+        productionOutputDirs.add(output);
+      }
+      final VirtualFile testsOutput = manager.getCompilerOutputPathForTests();
+      if (testsOutput != null && testsOutput.isValid()) {
+        allDirs.add(testsOutput);
+        testOutputDirs.add(testsOutput);
+      }
+    }
+    myOutputDirectories = VfsUtil.toVirtualFileArray(allDirs);
+    // need this to ensure that the sent contains only _dedicated_ test output dirs
+    // Directories that are configured for both test and production classes must not be added in the resulting set
+    testOutputDirs.removeAll(productionOutputDirs);
+    myTestOutputDirectories = Collections.unmodifiableSet(testOutputDirs);
+  }
+
+  public void markGenerated(Collection<VirtualFile> files) {
+    for (final VirtualFile file : files) {
+      myGeneratedSources.add(FileBasedIndex.getFileId(file));
+    }
+  }
+
+  public long getStartCompilationStamp() {
+    return myStartCompilationStamp;
+  }
+
+  public boolean isGenerated(VirtualFile file) {
+    if (myGeneratedSources.contains(FileBasedIndex.getFileId(file))) {
+      return true;
+    }
+    if (isUnderRoots(myRootToModuleMap.keySet(), file)) {
+      return true;
+    }
+    final Module module = getModuleByFile(file);
+    if (module != null) {
+      final String procGenRoot = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+      if (procGenRoot != null && VfsUtil.isAncestor(new File(procGenRoot), new File(file.getPath()), true)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /*
+  private JBZipFile lookupZip(String outputDir) {
+    synchronized (myOpenZipFiles) {
+      JBZipFile zip = myOpenZipFiles.get(outputDir);
+      if (zip == null) {
+        final File zipFile = CompilerPathsEx.getZippedOutputPath(myProject, outputDir);
+        try {
+          try {
+            zip = new JBZipFile(zipFile);
+          }
+          catch (FileNotFoundException e) {
+            try {
+              zipFile.createNewFile();
+              zip = new JBZipFile(zipFile);
+            }
+            catch (IOException e1) {
+              zipFile.getParentFile().mkdirs();
+              zipFile.createNewFile();
+              zip = new JBZipFile(zipFile);
+            }
+          }
+          myOpenZipFiles.put(outputDir, zip);
+        }
+        catch (IOException e) {
+          LOG.info(e);
+          addMessage(CompilerMessageCategory.ERROR, "Cannot create zip file " + zipFile.getPath() + ": " + e.getMessage(), null, -1, -1);
+        }
+      }
+      return zip;
+    }
+  }
+  */
+
+  public Project getProject() {
+    return myProject;
+  }
+
+  public DependencyCache getDependencyCache() {
+    return myDependencyCache;
+  }
+
+  public CompilerMessage[] getMessages(CompilerMessageCategory category) {
+    Collection<CompilerMessage> collection = myMessages.get(category);
+    if (collection == null) {
+      return CompilerMessage.EMPTY_ARRAY;
+    }
+    return collection.toArray(new CompilerMessage[collection.size()]);
+  }
+
+  public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
+    CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, null);
+    addMessage(msg);
+  }
+
+  public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum,
+                         Navigatable navigatable) {
+    CompilerMessageImpl msg = new CompilerMessageImpl(myProject, category, message, findPresentableFileForMessage(url), lineNum, columnNum, navigatable);
+    addMessage(msg);
+  }
+
+  @Nullable
+  private VirtualFile findPresentableFileForMessage(@Nullable final String url) {
+    final VirtualFile file = findFileByUrl(url);
+    if (file == null) {
+      return null;
+    }
+    return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
+      @Override
+      public VirtualFile compute() {
+        if (file.isValid()) {
+          for (final Map.Entry<VirtualFile, Pair<SourceGeneratingCompiler, Module>> entry : myOutputRootToSourceGeneratorMap.entrySet()) {
+            final VirtualFile root = entry.getKey();
+            if (VfsUtilCore.isAncestor(root, file, false)) {
+              final Pair<SourceGeneratingCompiler, Module> pair = entry.getValue();
+              final VirtualFile presentableFile = pair.getFirst().getPresentableFile(CompileContextImpl.this, pair.getSecond(), root, file);
+              return presentableFile != null ? presentableFile : file;
+            }
+          }
+        }
+        return file;
+      }
+    });
+  }
+
+  @Nullable 
+  private static VirtualFile findFileByUrl(@Nullable String url) {
+    if (url == null) {
+      return null;
+    }
+    VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
+    if (file == null) {
+      // groovy stubs may be placed in completely random directories which aren't refreshed automatically 
+      return VirtualFileManager.getInstance().refreshAndFindFileByUrl(url);
+    }
+    return file;
+  }
+
+  public void addMessage(CompilerMessage msg) {
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      LOG.info("addMessage: " + msg + " this=" + this);
+    }
+
+    Collection<CompilerMessage> messages = myMessages.get(msg.getCategory());
+    if (messages == null) {
+      messages = new LinkedHashSet<CompilerMessage>();
+      myMessages.put(msg.getCategory(), messages);
+    }
+    if (messages.add(msg)) {
+      myTask.addMessage(msg);
+    }
+    if (myShouldUpdateProblemsView && msg.getCategory() == CompilerMessageCategory.ERROR) {
+      ProblemsViewImpl.SERVICE.getInstance(myProject).addMessage(msg, mySessionId);
+    }
+  }
+
+  public int getMessageCount(CompilerMessageCategory category) {
+    if (category != null) {
+      Collection<CompilerMessage> collection = myMessages.get(category);
+      return collection != null ? collection.size() : 0;
+    }
+    int count = 0;
+    for (Collection<CompilerMessage> collection : myMessages.values()) {
+      if (collection != null) {
+        count += collection.size();
+      }
+    }
+    return count;
+  }
+
+  public CompileScope getCompileScope() {
+    return myCompileScope;
+  }
+
+  public CompileScope getProjectCompileScope() {
+    return myProjectCompileScope;
+  }
+
+  public void requestRebuildNextTime(String message) {
+    if (!myRebuildRequested) {
+      myRebuildRequested = true;
+      myRebuildReason = message;
+      addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
+    }
+  }
+
+  public boolean isRebuildRequested() {
+    return myRebuildRequested;
+  }
+
+  public String getRebuildReason() {
+    return myRebuildReason;
+  }
+
+  public ProgressIndicator getProgressIndicator() {
+    //if (myProgressIndicatorProxy != null) {
+    //  return myProgressIndicatorProxy;
+    //}
+    return myTask.getIndicator();
+  }
+
+  public void assignModule(@NotNull VirtualFile root, @NotNull Module module, final boolean isTestSource, @Nullable Compiler compiler) {
+    try {
+      myRootToModuleMap.put(root, module);
+      Set<VirtualFile> set = myModuleToRootsMap.get(module);
+      if (set == null) {
+        set = new HashSet<VirtualFile>();
+        myModuleToRootsMap.put(module, set);
+      }
+      set.add(root);
+      if (isTestSource) {
+        myGeneratedTestRoots.add(root);
+      }
+      if (compiler instanceof SourceGeneratingCompiler) {
+        myOutputRootToSourceGeneratorMap.put(root, new Pair<SourceGeneratingCompiler, Module>((SourceGeneratingCompiler)compiler, module));
+      }
+    }
+    finally {
+      myModuleToRootsCache.remove(module);
+    }
+  }
+
+  @Nullable
+  public VirtualFile getSourceFileByOutputFile(VirtualFile outputFile) {
+    return TranslatingCompilerFilesMonitor.getSourceFileByOutput(outputFile);
+  }
+
+  public Module getModuleByFile(VirtualFile file) {
+    final Module module = myProjectFileIndex.getModuleForFile(file);
+    if (module != null) {
+      LOG.assertTrue(!module.isDisposed());
+      return module;
+    }
+    for (final VirtualFile root : myRootToModuleMap.keySet()) {
+      if (VfsUtil.isAncestor(root, file, false)) {
+        final Module mod = myRootToModuleMap.get(root);
+        if (mod != null) {
+          LOG.assertTrue(!mod.isDisposed());
+        }
+        return mod;
+      }
+    }
+    return null;
+  }
+
+
+  private final Map<Module, VirtualFile[]> myModuleToRootsCache = new HashMap<Module, VirtualFile[]>();
+
+  public VirtualFile[] getSourceRoots(Module module) {
+    VirtualFile[] cachedRoots = myModuleToRootsCache.get(module);
+    if (cachedRoots != null) {
+      if (areFilesValid(cachedRoots)) {
+        return cachedRoots;
+      }
+      else {
+        myModuleToRootsCache.remove(module); // clear cache for this module and rebuild list of roots
+      }
+    }
+
+    Set<VirtualFile> additionalRoots = myModuleToRootsMap.get(module);
+    VirtualFile[] moduleRoots = ModuleRootManager.getInstance(module).getSourceRoots();
+    if (additionalRoots == null || additionalRoots.isEmpty()) {
+      myModuleToRootsCache.put(module, moduleRoots);
+      return moduleRoots;
+    }
+
+    final VirtualFile[] allRoots = new VirtualFile[additionalRoots.size() + moduleRoots.length];
+    System.arraycopy(moduleRoots, 0, allRoots, 0, moduleRoots.length);
+    int index = moduleRoots.length;
+    for (final VirtualFile additionalRoot : additionalRoots) {
+      allRoots[index++] = additionalRoot;
+    }
+    myModuleToRootsCache.put(module, allRoots);
+    return allRoots;
+  }
+
+  private static boolean areFilesValid(VirtualFile[] files) {
+    for (VirtualFile file : files) {
+      if (!file.isValid()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public VirtualFile[] getAllOutputDirectories() {
+    return myOutputDirectories;
+  }
+
+  @NotNull
+  public Set<VirtualFile> getTestOutputDirectories() {
+    return myTestOutputDirectories;
+  }
+
+  public VirtualFile getModuleOutputDirectory(Module module) {
+    return CompilerPaths.getModuleOutputDirectory(module, false);
+  }
+
+  public VirtualFile getModuleOutputDirectoryForTests(Module module) {
+    return CompilerPaths.getModuleOutputDirectory(module, true);
+  }
+
+  public boolean isMake() {
+    return myMake;
+  }
+
+  public boolean isRebuild() {
+    return myIsRebuild;
+  }
+
+  public boolean isAnnotationProcessorsEnabled() {
+    return myIsAnnotationProcessorsEnabled;
+  }
+
+  public void addScope(final CompileScope additionalScope) {
+    myCompileScope = new CompositeScope(myCompileScope, additionalScope);
+  }
+
+  public boolean isInTestSourceContent(@NotNull final VirtualFile fileOrDir) {
+    if (myProjectFileIndex.isInTestSourceContent(fileOrDir)) {
+      return true;
+    }
+    if (isUnderRoots(myGeneratedTestRoots, fileOrDir)) {
+      return true;
+    }
+    return false;
+  }
+
+  public boolean isInSourceContent(@NotNull final VirtualFile fileOrDir) {
+    if (myProjectFileIndex.isInSourceContent(fileOrDir)) {
+      return true;
+    }
+    if (isUnderRoots(myRootToModuleMap.keySet(), fileOrDir)) {
+      return true;
+    }
+    return false;
+  }
+
+  public static boolean isUnderRoots(@NotNull Set<VirtualFile> roots, @NotNull VirtualFile file) {
+    VirtualFile parent = file;
+    while (true) {
+      if (parent == null) {
+        return false;
+      }
+      if (roots.contains(parent)) {
+        return true;
+      }
+      parent = parent.getParent();
+    }
+  }
+
+  public UUID getSessionId() {
+    return mySessionId;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
new file mode 100644
index 0000000..568bb42
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -0,0 +1,2851 @@
+/*
+ * 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.
+ */
+
+/**
+ * @author: Eugene Zhuravlev
+ * Date: Jan 17, 2003
+ * Time: 1:42:26 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.CommonBundle;
+import com.intellij.compiler.*;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.compiler.make.CacheUtils;
+import com.intellij.compiler.make.ChangedConstantsDependencyProcessor;
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.compiler.progress.CompilerTask;
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.compiler.server.CustomBuilderMessageHandler;
+import com.intellij.compiler.server.DefaultMessageHandler;
+import com.intellij.diagnostic.IdeErrorsDialog;
+import com.intellij.diagnostic.PluginException;
+import com.intellij.openapi.application.*;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.compiler.ex.CompilerPathsEx;
+import com.intellij.openapi.compiler.generic.GenericCompiler;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.LanguageLevelUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.roots.ui.configuration.CommonContentEntriesEditor;
+import com.intellij.openapi.roots.ui.configuration.ProjectSettingsService;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.newvfs.ManagingFS;
+import com.intellij.openapi.vfs.newvfs.RefreshQueue;
+import com.intellij.openapi.wm.StatusBar;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.impl.artifacts.ArtifactImpl;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
+import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil;
+import com.intellij.packaging.impl.compiler.ArtifactsCompiler;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.util.Chunk;
+import com.intellij.util.Function;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.containers.MultiMap;
+import com.intellij.util.containers.OrderedSet;
+import com.intellij.util.messages.MessageBus;
+import gnu.trove.THashSet;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.jps.api.CmdlineProtoUtil;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+import org.jetbrains.jps.api.RequestFuture;
+import org.jetbrains.jps.incremental.Utils;
+
+import javax.swing.*;
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.TimeUnit;
+
+import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+
+public class CompileDriver {
+
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompileDriver");
+  // to be used in tests only for debug output
+  public static volatile boolean ourDebugMode = false;
+
+  private final Project myProject;
+  private final Map<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>> myGenerationCompilerModuleToOutputDirMap; // [IntermediateOutputCompiler, Module] -> [ProductionSources, TestSources]
+  private final String myCachesDirectoryPath;
+  private boolean myShouldClearOutputDirectory;
+
+  private final Map<Module, String> myModuleOutputPaths = new HashMap<Module, String>();
+  private final Map<Module, String> myModuleTestOutputPaths = new HashMap<Module, String>();
+
+  @NonNls private static final String VERSION_FILE_NAME = "version.dat";
+  @NonNls private static final String LOCK_FILE_NAME = "in_progress.dat";
+
+  private static final boolean GENERATE_CLASSPATH_INDEX = "true".equals(System.getProperty("generate.classpath.index"));
+  private static final String PROP_PERFORM_INITIAL_REFRESH = "compiler.perform.outputs.refresh.on.start";
+  private static final Key<Boolean> REFRESH_DONE_KEY = Key.create("_compiler.initial.refresh.done_");
+
+  private static final FileProcessingCompilerAdapterFactory FILE_PROCESSING_COMPILER_ADAPTER_FACTORY = new FileProcessingCompilerAdapterFactory() {
+    public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) {
+      return new FileProcessingCompilerAdapter(context, compiler);
+    }
+  };
+  private static final FileProcessingCompilerAdapterFactory FILE_PACKAGING_COMPILER_ADAPTER_FACTORY = new FileProcessingCompilerAdapterFactory() {
+    public FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler) {
+      return new PackagingCompilerAdapter(context, (PackagingCompiler)compiler);
+    }
+  };
+  private CompilerFilter myCompilerFilter = CompilerFilter.ALL;
+  private static final CompilerFilter SOURCE_PROCESSING_ONLY = new CompilerFilter() {
+    public boolean acceptCompiler(Compiler compiler) {
+      return compiler instanceof SourceProcessingCompiler;
+    }
+  };
+  private static final CompilerFilter ALL_EXCEPT_SOURCE_PROCESSING = new CompilerFilter() {
+    public boolean acceptCompiler(Compiler compiler) {
+      return !SOURCE_PROCESSING_ONLY.acceptCompiler(compiler);
+    }
+  };
+
+  private Set<File> myAllOutputDirectories;
+  private static final long ONE_MINUTE_MS = 60L /*sec*/ * 1000L /*millisec*/;
+
+  public CompileDriver(Project project) {
+    myProject = project;
+    myCachesDirectoryPath = CompilerPaths.getCacheStoreDirectory(myProject).getPath().replace('/', File.separatorChar);
+    myShouldClearOutputDirectory = CompilerWorkspaceConfiguration.getInstance(myProject).CLEAR_OUTPUT_DIRECTORY;
+
+    myGenerationCompilerModuleToOutputDirMap = new HashMap<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>>();
+
+    if (!useOutOfProcessBuild()) {
+      final LocalFileSystem lfs = LocalFileSystem.getInstance();
+      final IntermediateOutputCompiler[] generatingCompilers = CompilerManager.getInstance(myProject).getCompilers(IntermediateOutputCompiler.class, myCompilerFilter);
+      final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
+      final CompilerConfiguration config = CompilerConfiguration.getInstance(project);
+      for (Module module : allModules) {
+        for (IntermediateOutputCompiler compiler : generatingCompilers) {
+          final VirtualFile productionOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, false));
+          final VirtualFile testOutput = lookupVFile(lfs, CompilerPaths.getGenerationOutputPath(compiler, module, true));
+          final Pair<IntermediateOutputCompiler, Module> pair = new Pair<IntermediateOutputCompiler, Module>(compiler, module);
+          final Pair<VirtualFile, VirtualFile> outputs = new Pair<VirtualFile, VirtualFile>(productionOutput, testOutput);
+          myGenerationCompilerModuleToOutputDirMap.put(pair, outputs);
+        }
+        if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
+          final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+          if (path != null) {
+            lookupVFile(lfs, path);  // ensure the file is created and added to VFS
+          }
+        }
+      }
+    }
+  }
+
+  public void setCompilerFilter(CompilerFilter compilerFilter) {
+    myCompilerFilter = compilerFilter == null? CompilerFilter.ALL : compilerFilter;
+  }
+
+  public void rebuild(CompileStatusNotification callback) {
+    final CompileScope compileScope;
+    ProjectCompileScope projectScope = new ProjectCompileScope(myProject);
+    if (useOutOfProcessBuild()) {
+      compileScope = projectScope;
+    }
+    else {
+      CompileScope scopeWithArtifacts = ArtifactCompileScope.createScopeWithArtifacts(projectScope, ArtifactUtil.getArtifactWithOutputPaths(myProject), false);
+      compileScope = addAdditionalRoots(scopeWithArtifacts, ALL_EXCEPT_SOURCE_PROCESSING);
+    }
+    doRebuild(callback, null, true, compileScope);
+  }
+
+  public void make(CompileScope scope, CompileStatusNotification callback) {
+    if (!useOutOfProcessBuild()) {
+      scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
+    }
+    if (validateCompilerConfiguration(scope, false)) {
+      startup(scope, false, false, callback, null, true);
+    }
+    else {
+      callback.finished(true, 0, 0, DummyCompileContext.getInstance());
+    }
+  }
+
+  public boolean isUpToDate(CompileScope scope) {
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("isUpToDate operation started");
+    }
+    if (!useOutOfProcessBuild()) {
+      scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
+    }
+
+    final CompilerTask task = new CompilerTask(myProject, "Classes up-to-date check", true, false);
+    final DependencyCache cache = useOutOfProcessBuild()? null : createDependencyCache();
+    final CompileContextImpl compileContext = new CompileContextImpl(myProject, task, scope, cache, true, false);
+
+    if (!useOutOfProcessBuild()) {
+      checkCachesVersion(compileContext, ManagingFS.getInstance().getCreationTimestamp());
+      if (compileContext.isRebuildRequested()) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Rebuild requested, up-to-date=false");
+        }
+        return false;
+      }
+
+      for (Map.Entry<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
+        final Pair<VirtualFile, VirtualFile> outputs = entry.getValue();
+        final Pair<IntermediateOutputCompiler, Module> key = entry.getKey();
+        final Module module = key.getSecond();
+        compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst());
+        compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst());
+      }
+    }
+
+    final Ref<ExitStatus> result = new Ref<ExitStatus>();
+
+    final Runnable compileWork;
+    if (useOutOfProcessBuild()) {
+      compileWork = new Runnable() {
+        public void run() {
+          final ProgressIndicator indicator = compileContext.getProgressIndicator();
+          if (indicator.isCanceled() || myProject.isDisposed()) {
+            return;
+          }
+          try {
+            final Collection<String> paths = CompileScopeUtil.fetchFiles(compileContext);
+            List<TargetTypeBuildScope> scopes = new ArrayList<TargetTypeBuildScope>();
+            if (paths.isEmpty()) {
+              if (!compileContext.isRebuild() && !CompileScopeUtil.allProjectModulesAffected(compileContext)) {
+                CompileScopeUtil.addScopesForModules(Arrays.asList(compileContext.getCompileScope().getAffectedModules()), scopes);
+              }
+              else {
+                scopes.addAll(CmdlineProtoUtil.createAllModulesScopes());
+              }
+              for (BuildTargetScopeProvider provider : BuildTargetScopeProvider.EP_NAME.getExtensions()) {
+                scopes = CompileScopeUtil.mergeScopes(scopes, provider.getBuildTargetScopes(compileContext.getCompileScope(), myCompilerFilter, myProject));
+              }
+            }
+            final RequestFuture future = compileInExternalProcess(compileContext, scopes, paths, true);
+            if (future != null) {
+              while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) {
+                if (indicator.isCanceled()) {
+                  future.cancel(false);
+                }
+              }
+            }
+          }
+          catch (Throwable e) {
+            LOG.error(e);
+          }
+          finally {
+            result.set(COMPILE_SERVER_BUILD_STATUS.get(compileContext));
+            CompilerCacheManager.getInstance(myProject).flushCaches();
+          }
+        }
+      };
+    }
+    else {
+      compileWork = new Runnable() {
+        public void run() {
+          try {
+            myAllOutputDirectories = getAllOutputDirectories(compileContext);
+            // need this for updating zip archives experiment, uncomment if the feature is turned on
+            //myOutputFinder = new OutputPathFinder(myAllOutputDirectories);
+            result.set(doCompile(compileContext, false, false, true));
+          }
+          finally {
+            CompilerCacheManager.getInstance(myProject).flushCaches();
+          }
+        }
+      };
+    }
+    task.start(compileWork, null);
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("isUpToDate operation finished");
+    }
+
+    return ExitStatus.UP_TO_DATE.equals(result.get());
+  }
+
+  private DependencyCache createDependencyCache() {
+    return new DependencyCache(myCachesDirectoryPath + File.separator + ".dependency-info");
+  }
+
+  public void compile(CompileScope scope, CompileStatusNotification callback, boolean clearingOutputDirsPossible) {
+    myShouldClearOutputDirectory &= clearingOutputDirsPossible;
+    if (containsFileIndexScopes(scope)) {
+      scope = addAdditionalRoots(scope, ALL_EXCEPT_SOURCE_PROCESSING);
+    }
+    if (validateCompilerConfiguration(scope, false)) {
+      startup(scope, false, true, callback, null, true);
+    }
+    else {
+      callback.finished(true, 0, 0, DummyCompileContext.getInstance());
+    }
+  }
+
+  private static boolean containsFileIndexScopes(CompileScope scope) {
+    if (scope instanceof CompositeScope) {
+      for (CompileScope childScope : ((CompositeScope)scope).getScopes()) {
+        if (containsFileIndexScopes(childScope)) {
+          return true;
+        }
+      }
+    }
+    return scope instanceof FileIndexCompileScope;
+  }
+
+  private static class CompileStatus {
+    final int CACHE_FORMAT_VERSION;
+    final boolean COMPILATION_IN_PROGRESS;
+    final long VFS_CREATION_STAMP;
+
+    private CompileStatus(int cacheVersion, boolean isCompilationInProgress, long vfsStamp) {
+      CACHE_FORMAT_VERSION = cacheVersion;
+      COMPILATION_IN_PROGRESS = isCompilationInProgress;
+      VFS_CREATION_STAMP = vfsStamp;
+    }
+  }
+
+  private CompileStatus readStatus() {
+    final boolean isInProgress = getLockFile().exists();
+    int version = -1;
+    long vfsStamp = -1L;
+    try {
+      final File versionFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME);
+      DataInputStream in = new DataInputStream(new FileInputStream(versionFile));
+      try {
+        version = in.readInt();
+        try {
+          vfsStamp = in.readLong();
+        }
+        catch (IOException ignored) {
+        }
+      }
+      finally {
+        in.close();
+      }
+    }
+    catch (FileNotFoundException e) {
+      // ignore
+    }
+    catch (IOException e) {
+      LOG.info(e);  // may happen in case of IDEA crashed and the file is not written properly
+      return null;
+    }
+    return new CompileStatus(version, isInProgress, vfsStamp);
+  }
+
+  private void writeStatus(CompileStatus status, CompileContext context) {
+    final File statusFile = new File(myCachesDirectoryPath, VERSION_FILE_NAME);
+
+    final File lockFile = getLockFile();
+    try {
+      FileUtil.createIfDoesntExist(statusFile);
+      DataOutputStream out = new DataOutputStream(new FileOutputStream(statusFile));
+      try {
+        out.writeInt(status.CACHE_FORMAT_VERSION);
+        out.writeLong(status.VFS_CREATION_STAMP);
+      }
+      finally {
+        out.close();
+      }
+      if (status.COMPILATION_IN_PROGRESS) {
+        FileUtil.createIfDoesntExist(lockFile);
+      }
+      else {
+        deleteFile(lockFile);
+      }
+    }
+    catch (IOException e) {
+      context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1);
+    }
+  }
+
+  private File getLockFile() {
+    return new File(CompilerPaths.getCompilerSystemDirectory(myProject), LOCK_FILE_NAME);
+  }
+
+  private void doRebuild(CompileStatusNotification callback,
+                         CompilerMessage message,
+                         final boolean checkCachesVersion,
+                         final CompileScope compileScope) {
+    if (validateCompilerConfiguration(compileScope, !useOutOfProcessBuild())) {
+      startup(compileScope, true, false, callback, message, checkCachesVersion);
+    }
+    else {
+      callback.finished(true, 0, 0, DummyCompileContext.getInstance());
+    }
+  }
+
+  private CompileScope addAdditionalRoots(CompileScope originalScope, final CompilerFilter filter) {
+    CompileScope scope = attachIntermediateOutputDirectories(originalScope, filter);
+
+    final AdditionalCompileScopeProvider[] scopeProviders = Extensions.getExtensions(AdditionalCompileScopeProvider.EXTENSION_POINT_NAME);
+    CompileScope baseScope = scope;
+    for (AdditionalCompileScopeProvider scopeProvider : scopeProviders) {
+      final CompileScope additionalScope = scopeProvider.getAdditionalScope(baseScope, filter, myProject);
+      if (additionalScope != null) {
+        scope = new CompositeScope(scope, additionalScope);
+      }
+    }
+    return scope;
+  }
+
+  private CompileScope attachIntermediateOutputDirectories(CompileScope originalScope, CompilerFilter filter) {
+    CompileScope scope = originalScope;
+    final Set<Module> affected = new HashSet<Module>(Arrays.asList(originalScope.getAffectedModules()));
+    for (Map.Entry<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
+      final Module module = entry.getKey().getSecond();
+      if (affected.contains(module) && filter.acceptCompiler(entry.getKey().getFirst())) {
+        final Pair<VirtualFile, VirtualFile> outputs = entry.getValue();
+        scope = new CompositeScope(scope, new FileSetCompileScope(Arrays.asList(outputs.getFirst(), outputs.getSecond()), new Module[]{module}));
+      }
+    }
+    return scope;
+  }
+
+  private void attachAnnotationProcessorsOutputDirectories(CompileContextEx context) {
+    final LocalFileSystem lfs = LocalFileSystem.getInstance();
+    final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
+    final Set<Module> affected = new HashSet<Module>(Arrays.asList(context.getCompileScope().getAffectedModules()));
+    for (Module module : affected) {
+      if (!config.getAnnotationProcessingConfiguration(module).isEnabled()) {
+        continue;
+      }
+      final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+      if (path == null) {
+        continue;
+      }
+      final VirtualFile vFile = lfs.findFileByPath(path);
+      if (vFile == null) {
+        continue;
+      }
+      if (ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vFile)) {
+        // no need to add, is already marked as source
+        continue;
+      }
+      context.addScope(new FileSetCompileScope(Collections.singletonList(vFile), new Module[]{module}));
+      context.assignModule(vFile, module, false, null);
+    }
+  }
+
+  @Nullable
+  private RequestFuture compileInExternalProcess(final @NotNull CompileContextImpl compileContext,
+                                                 @NotNull List<TargetTypeBuildScope> scopes,
+                                                 final @NotNull Collection<String> paths,
+                                                 final boolean onlyCheckUpToDate)
+    throws Exception {
+    final CompileScope scope = compileContext.getCompileScope();
+    // need to pass scope's user data to server
+    final Map<String, String> builderParams;
+    if (onlyCheckUpToDate) {
+      builderParams = Collections.emptyMap();
+    }
+    else {
+      final Map<Key, Object> exported = scope.exportUserData();
+      if (!exported.isEmpty()) {
+        builderParams = new HashMap<String, String>();
+        for (Map.Entry<Key, Object> entry : exported.entrySet()) {
+          final String _key = entry.getKey().toString();
+          final String _value = entry.getValue().toString();
+          builderParams.put(_key, _value);
+        }
+      }
+      else {
+        builderParams = Collections.emptyMap();
+      }
+    }
+
+    final MessageBus messageBus = myProject.getMessageBus();
+    final MultiMap<String, Artifact> outputToArtifact = ArtifactCompilerUtil.containsArtifacts(scopes) ? ArtifactCompilerUtil.createOutputToArtifactMap(myProject) : null;
+    final BuildManager buildManager = BuildManager.getInstance();
+    buildManager.cancelAutoMakeTasks(myProject);
+    return buildManager.scheduleBuild(myProject, compileContext.isRebuild(), compileContext.isMake(), onlyCheckUpToDate, scopes, paths, builderParams, new DefaultMessageHandler(myProject) {
+
+      @Override
+      public void buildStarted(UUID sessionId) {
+      }
+
+      @Override
+      public void sessionTerminated(final UUID sessionId) {
+        if (compileContext.shouldUpdateProblemsView()) {
+          final ProblemsView view = ProblemsViewImpl.SERVICE.getInstance(myProject);
+          view.clearProgress();
+          view.clearOldMessages(compileContext.getCompileScope(), compileContext.getSessionId());
+        }
+      }
+
+      @Override
+      public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) {
+        compileContext.addMessage(CompilerMessageCategory.ERROR, failure.getDescription(), null, -1, -1);
+        final String trace = failure.getStacktrace();
+        if (trace != null) {
+          LOG.info(trace);
+          System.out.println(trace);
+        }
+        compileContext.putUserData(COMPILE_SERVER_BUILD_STATUS, ExitStatus.ERRORS);
+      }
+
+      @Override
+      protected void handleCompileMessage(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message) {
+        final CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind kind = message.getKind();
+        //System.out.println(compilerMessage.getText());
+        final String messageText = message.getText();
+        if (kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.PROGRESS) {
+          final ProgressIndicator indicator = compileContext.getProgressIndicator();
+          indicator.setText(messageText);
+          if (message.hasDone()) {
+            indicator.setFraction(message.getDone());
+          }
+        }
+        else {
+          final CompilerMessageCategory category = kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.ERROR ? CompilerMessageCategory.ERROR
+            : kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.WARNING ? CompilerMessageCategory.WARNING : CompilerMessageCategory.INFORMATION;
+
+          String sourceFilePath = message.hasSourceFilePath() ? message.getSourceFilePath() : null;
+          if (sourceFilePath != null) {
+            sourceFilePath = FileUtil.toSystemIndependentName(sourceFilePath);
+          }
+          final long line = message.hasLine() ? message.getLine() : -1;
+          final long column = message.hasColumn() ? message.getColumn() : -1;
+          final String srcUrl = sourceFilePath != null ? VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, sourceFilePath) : null;
+          compileContext.addMessage(category, messageText, srcUrl, (int)line, (int)column);
+        }
+      }
+
+      @Override
+      protected void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event) {
+        final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Type eventType = event.getEventType();
+        switch (eventType) {
+          case FILES_GENERATED:
+            final List<CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile> generated = event.getGeneratedFilesList();
+            final CompilationStatusListener publisher = messageBus.syncPublisher(CompilerTopics.COMPILATION_STATUS);
+            Set<String> writtenArtifactOutputPaths = outputToArtifact != null ? new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY) : null;
+            for (CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile generatedFile : generated) {
+              final String root = FileUtil.toSystemIndependentName(generatedFile.getOutputRoot());
+              final String relativePath = FileUtil.toSystemIndependentName(generatedFile.getRelativePath());
+              publisher.fileGenerated(root, relativePath);
+              if (outputToArtifact != null) {
+                Collection<Artifact> artifacts = outputToArtifact.get(root);
+                if (!artifacts.isEmpty()) {
+                  for (Artifact artifact : artifacts) {
+                    ArtifactsCompiler.addChangedArtifact(compileContext, artifact);
+                  }
+                  writtenArtifactOutputPaths.add(FileUtil.toSystemDependentName(DeploymentUtil.appendToPath(root, relativePath)));
+                }
+              }
+            }
+            if (writtenArtifactOutputPaths != null && !writtenArtifactOutputPaths.isEmpty()) {
+              ArtifactsCompiler.addWrittenPaths(compileContext, writtenArtifactOutputPaths);
+            }
+            break;
+          case BUILD_COMPLETED:
+            ExitStatus status = ExitStatus.SUCCESS;
+            if (event.hasCompletionStatus()) {
+              final CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Status completionStatus = event.getCompletionStatus();
+              switch (completionStatus) {
+                case CANCELED:
+                  status = ExitStatus.CANCELLED;
+                  break;
+                case ERRORS:
+                  status = ExitStatus.ERRORS;
+                  break;
+                case SUCCESS:
+                  status = ExitStatus.SUCCESS;
+                  break;
+                case UP_TO_DATE:
+                  status = ExitStatus.UP_TO_DATE;
+                  break;
+              }
+            }
+            compileContext.putUserDataIfAbsent(COMPILE_SERVER_BUILD_STATUS, status);
+            break;
+          case CUSTOM_BUILDER_MESSAGE:
+            if (event.hasCustomBuilderMessage()) {
+              CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.CustomBuilderMessage message = event.getCustomBuilderMessage();
+              messageBus.syncPublisher(CustomBuilderMessageHandler.TOPIC).messageReceived(message.getBuilderId(), message.getMessageType(),
+                                                                                          message.getMessageText());
+            }
+            break;
+        }
+      }
+    });
+  }
+
+
+  private static final Key<ExitStatus> COMPILE_SERVER_BUILD_STATUS = Key.create("COMPILE_SERVER_BUILD_STATUS");
+
+  private void startup(final CompileScope scope,
+                       final boolean isRebuild,
+                       final boolean forceCompile,
+                       final CompileStatusNotification callback,
+                       final CompilerMessage message,
+                       final boolean checkCachesVersion) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
+
+    final boolean useExtProcessBuild = useOutOfProcessBuild();
+
+    final String contentName =
+      forceCompile ? CompilerBundle.message("compiler.content.name.compile") : CompilerBundle.message("compiler.content.name.make");
+    final CompilerTask compileTask = new CompilerTask(myProject, contentName, ApplicationManager.getApplication().isUnitTestMode(), true);
+
+    StatusBar.Info.set("", myProject, "Compiler");
+    if (useExtProcessBuild) {
+      // ensure the project model seen by build process is up-to-date
+      myProject.save();
+    }
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+    FileDocumentManager.getInstance().saveAllDocuments();
+
+    final DependencyCache dependencyCache = useExtProcessBuild ? null: createDependencyCache();
+    final CompileContextImpl compileContext =
+      new CompileContextImpl(myProject, compileTask, scope, dependencyCache, !isRebuild && !forceCompile, isRebuild);
+
+    if (!useExtProcessBuild) {
+      for (Map.Entry<Pair<IntermediateOutputCompiler, Module>, Pair<VirtualFile, VirtualFile>> entry : myGenerationCompilerModuleToOutputDirMap.entrySet()) {
+        final Pair<VirtualFile, VirtualFile> outputs = entry.getValue();
+        final Pair<IntermediateOutputCompiler, Module> key = entry.getKey();
+        final Module module = key.getSecond();
+        compileContext.assignModule(outputs.getFirst(), module, false, key.getFirst());
+        compileContext.assignModule(outputs.getSecond(), module, true, key.getFirst());
+      }
+      attachAnnotationProcessorsOutputDirectories(compileContext);
+    }
+
+    final Runnable compileWork;
+    if (useExtProcessBuild) {
+      compileWork = new Runnable() {
+        public void run() {
+          final ProgressIndicator indicator = compileContext.getProgressIndicator();
+          if (indicator.isCanceled() || myProject.isDisposed()) {
+            if (callback != null) {
+              callback.finished(true, 0, 0, compileContext);
+            }
+            return;
+          }
+          try {
+            LOG.info("COMPILATION STARTED (BUILD PROCESS)");
+            if (message != null) {
+              compileContext.addMessage(message);
+            }
+            if (!executeCompileTasks(compileContext, true)) {
+              COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED);
+              return;
+            }
+
+            final Collection<String> paths = CompileScopeUtil.fetchFiles(compileContext);
+            List<TargetTypeBuildScope> scopes = new ArrayList<TargetTypeBuildScope>();
+            if (paths.isEmpty()) {
+              if (!isRebuild && !CompileScopeUtil.allProjectModulesAffected(compileContext)) {
+                CompileScopeUtil.addScopesForModules(Arrays.asList(compileContext.getCompileScope().getAffectedModules()), scopes);
+              }
+              else {
+                scopes.addAll(CmdlineProtoUtil.createAllModulesScopes());
+              }
+              for (BuildTargetScopeProvider provider : BuildTargetScopeProvider.EP_NAME.getExtensions()) {
+                scopes = CompileScopeUtil.mergeScopes(scopes, provider.getBuildTargetScopes(scope, myCompilerFilter, myProject));
+              }
+            }
+            final RequestFuture future = compileInExternalProcess(compileContext, scopes, paths, false);
+            if (future != null) {
+              while (!future.waitFor(200L , TimeUnit.MILLISECONDS)) {
+                if (indicator.isCanceled()) {
+                  future.cancel(false);
+                }
+              }
+              if (!executeCompileTasks(compileContext, false)) {
+                COMPILE_SERVER_BUILD_STATUS.set(compileContext, ExitStatus.CANCELLED);
+                return;
+              }
+            }
+          }
+          catch (Throwable e) {
+            LOG.error(e); // todo
+          }
+          finally {
+            CompilerCacheManager.getInstance(myProject).flushCaches();
+
+            final long duration = notifyCompilationCompleted(compileContext, callback, COMPILE_SERVER_BUILD_STATUS.get(compileContext));
+            CompilerUtil.logDuration(
+              "\tCOMPILATION FINISHED (BUILD PROCESS); Errors: " +
+              compileContext.getMessageCount(CompilerMessageCategory.ERROR) +
+              "; warnings: " +
+              compileContext.getMessageCount(CompilerMessageCategory.WARNING),
+              duration
+            );
+
+            // refresh on output roots is required in order for the order enumerator to see all roots via VFS
+            final Set<File> outputs = new HashSet<File>();
+            for (final String path : CompilerPathsEx.getOutputPaths(ModuleManager.getInstance(myProject).getModules())) {
+              outputs.add(new File(path));
+            }
+            if (!outputs.isEmpty()) {
+              LocalFileSystem.getInstance().refreshIoFiles(outputs, true, false, null);
+            }
+          }
+        }
+      };
+    }
+    else {
+      compileWork = new Runnable() {
+        public void run() {
+          if (compileContext.getProgressIndicator().isCanceled()) {
+            if (callback != null) {
+              callback.finished(true, 0, 0, compileContext);
+            }
+            return;
+          }
+          try {
+            if (myProject.isDisposed()) {
+              return;
+            }
+            LOG.info("COMPILATION STARTED");
+            if (message != null) {
+              compileContext.addMessage(message);
+            }
+            TranslatingCompilerFilesMonitor.getInstance().ensureInitializationCompleted(myProject, compileContext.getProgressIndicator());
+            doCompile(compileContext, isRebuild, forceCompile, callback, checkCachesVersion);
+          }
+          finally {
+            FileUtil.delete(CompilerPaths.getRebuildMarkerFile(myProject));
+          }
+        }
+      };
+    }
+
+    compileTask.start(compileWork, new Runnable() {
+      public void run() {
+        if (isRebuild) {
+          final int rv = Messages.showOkCancelDialog(
+              myProject, "You are about to rebuild the whole project.\nRun 'Make Project' instead?", "Confirm Project Rebuild",
+              "Make", "Rebuild", Messages.getQuestionIcon()
+          );
+          if (rv == 0 /*yes, please, do run make*/) {
+            startup(scope, false, false, callback, null, checkCachesVersion);
+            return;
+          }
+        }
+        startup(scope, isRebuild, forceCompile, callback, message, checkCachesVersion);
+      }
+    });
+  }
+
+  @Nullable @TestOnly
+  public static ExitStatus getExternalBuildExitStatus(CompileContext context) {
+    return context.getUserData(COMPILE_SERVER_BUILD_STATUS);
+  }
+
+  private void doCompile(final CompileContextImpl compileContext,
+                         final boolean isRebuild,
+                         final boolean forceCompile,
+                         final CompileStatusNotification callback,
+                         final boolean checkCachesVersion) {
+    ExitStatus status = ExitStatus.ERRORS;
+    boolean wereExceptions = false;
+    final long vfsTimestamp = (ManagingFS.getInstance()).getCreationTimestamp();
+    try {
+      if (checkCachesVersion) {
+        checkCachesVersion(compileContext, vfsTimestamp);
+        if (compileContext.isRebuildRequested()) {
+          return;
+        }
+      }
+      writeStatus(new CompileStatus(CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION, true, vfsTimestamp), compileContext);
+      if (compileContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        return;
+      }
+
+      myAllOutputDirectories = getAllOutputDirectories(compileContext);
+      status = doCompile(compileContext, isRebuild, forceCompile, false);
+    }
+    catch (Throwable ex) {
+      if (ApplicationManager.getApplication().isUnitTestMode()) {
+        throw new RuntimeException(ex);
+      }
+      wereExceptions = true;
+      final PluginId pluginId = IdeErrorsDialog.findPluginId(ex);
+
+      final StringBuilder message = new StringBuilder();
+      message.append("Internal error");
+      if (pluginId != null) {
+        message.append(" (Plugin: ").append(pluginId).append(")");
+      }
+      message.append(": ").append(ex.getMessage());
+      compileContext.addMessage(CompilerMessageCategory.ERROR, message.toString(), null, -1, -1);
+      
+      if (pluginId != null) {
+        throw new PluginException(ex, pluginId);
+      }
+      throw new RuntimeException(ex);
+    }
+    finally {
+      dropDependencyCache(compileContext);
+      CompilerCacheManager.getInstance(myProject).flushCaches();
+      if (compileContext.isRebuildRequested()) {
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+          public void run() {
+            final CompilerMessageImpl msg = new CompilerMessageImpl(myProject, CompilerMessageCategory.INFORMATION, compileContext.getRebuildReason());
+            doRebuild(callback, msg, false, compileContext.getCompileScope());
+          }
+        }, ModalityState.NON_MODAL);
+      }
+      else {
+        if (!myProject.isDisposed()) {
+          writeStatus(new CompileStatus(CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION, wereExceptions, vfsTimestamp), compileContext);
+        }
+        final long duration = notifyCompilationCompleted(compileContext, callback, status);
+        CompilerUtil.logDuration(
+          "\tCOMPILATION FINISHED; Errors: " +
+          compileContext.getMessageCount(CompilerMessageCategory.ERROR) +
+          "; warnings: " +
+          compileContext.getMessageCount(CompilerMessageCategory.WARNING),
+          duration
+        );
+      }
+    }
+  }
+
+  /** @noinspection SSBasedInspection*/
+  private long notifyCompilationCompleted(final CompileContextImpl compileContext, final CompileStatusNotification callback, final ExitStatus _status) {
+    final long duration = System.currentTimeMillis() - compileContext.getStartCompilationStamp();
+    SwingUtilities.invokeLater(new Runnable() {
+      public void run() {
+        int errorCount = 0;
+        int warningCount = 0;
+        try {
+          errorCount = compileContext.getMessageCount(CompilerMessageCategory.ERROR);
+          warningCount = compileContext.getMessageCount(CompilerMessageCategory.WARNING);
+          if (!myProject.isDisposed()) {
+            final String statusMessage = createStatusMessage(_status, warningCount, errorCount, duration);
+            final MessageType messageType = errorCount > 0 ? MessageType.ERROR : warningCount > 0 ? MessageType.WARNING : MessageType.INFO;
+            if (duration > ONE_MINUTE_MS) {
+              ToolWindowManager.getInstance(myProject).notifyByBalloon(ToolWindowId.MESSAGES_WINDOW, messageType, statusMessage);
+            }
+            CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, messageType).notify(myProject);
+            if (_status != ExitStatus.UP_TO_DATE && compileContext.getMessageCount(null) > 0) {
+              compileContext.addMessage(CompilerMessageCategory.INFORMATION, statusMessage, null, -1, -1);
+            }
+          }
+        }
+        finally {
+          if (callback != null) {
+            callback.finished(_status == ExitStatus.CANCELLED, errorCount, warningCount, compileContext);
+          }
+        }
+      }
+    });
+    return duration;
+  }
+
+  private void checkCachesVersion(final CompileContextImpl compileContext, final long currentVFSTimestamp) {
+    if (CompilerPaths.getRebuildMarkerFile(compileContext.getProject()).exists()) {
+      compileContext.requestRebuildNextTime("Compiler caches are out of date, project rebuild is required");
+      return;
+    }
+    final CompileStatus compileStatus = readStatus();
+    if (compileStatus == null) {
+      compileContext.requestRebuildNextTime(CompilerBundle.message("error.compiler.caches.corrupted"));
+    }
+    else if (compileStatus.CACHE_FORMAT_VERSION != -1 &&
+             compileStatus.CACHE_FORMAT_VERSION != CompilerConfigurationImpl.DEPENDENCY_FORMAT_VERSION) {
+      compileContext.requestRebuildNextTime(CompilerBundle.message("error.caches.old.format"));
+    }
+    else if (compileStatus.COMPILATION_IN_PROGRESS) {
+      compileContext.requestRebuildNextTime(CompilerBundle.message("error.previous.compilation.failed"));
+    }
+    else if (compileStatus.VFS_CREATION_STAMP >= 0L){
+      if (currentVFSTimestamp != compileStatus.VFS_CREATION_STAMP) {
+        compileContext.requestRebuildNextTime(CompilerBundle.message("error.vfs.was.rebuilt"));
+      }
+    }
+  }
+
+  private static String createStatusMessage(final ExitStatus status, final int warningCount, final int errorCount, long duration) {
+    String message;
+    if (status == ExitStatus.CANCELLED) {
+      message = CompilerBundle.message("status.compilation.aborted");
+    }
+    else if (status == ExitStatus.UP_TO_DATE) {
+      message = CompilerBundle.message("status.all.up.to.date");
+    }
+    else  {
+      if (status == ExitStatus.SUCCESS) {
+        message = warningCount > 0
+               ? CompilerBundle.message("status.compilation.completed.successfully.with.warnings", warningCount)
+               : CompilerBundle.message("status.compilation.completed.successfully");
+      }
+      else {
+        message = CompilerBundle.message("status.compilation.completed.successfully.with.warnings.and.errors", errorCount, warningCount);
+      }
+      message = message + " in " + Utils.formatDuration(duration);
+    }
+    return message;
+  }
+
+  private ExitStatus doCompile(final CompileContextEx context, boolean isRebuild, final boolean forceCompile, final boolean onlyCheckStatus) {
+    try {
+      if (isRebuild) {
+        deleteAll(context);
+      }
+      else if (forceCompile) {
+        if (myShouldClearOutputDirectory) {
+          clearAffectedOutputPathsIfPossible(context);
+        }
+      }
+      if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        if (LOG.isDebugEnabled()) {
+          logErrorMessages(context);
+        }
+        return ExitStatus.ERRORS;
+      }
+
+      if (!onlyCheckStatus) {
+          if (!executeCompileTasks(context, true)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Compilation cancelled");
+            }
+            return ExitStatus.CANCELLED;
+          }
+        }
+
+      if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        if (LOG.isDebugEnabled()) {
+          logErrorMessages(context);
+        }
+        return ExitStatus.ERRORS;
+      }
+
+      boolean needRecalcOutputDirs = false;
+      if (Registry.is(PROP_PERFORM_INITIAL_REFRESH) || !Boolean.valueOf(REFRESH_DONE_KEY.get(myProject, Boolean.FALSE))) {
+        REFRESH_DONE_KEY.set(myProject, Boolean.TRUE);
+        final long refreshStart = System.currentTimeMillis();
+
+        //need this to make sure the VFS is built
+        final List<VirtualFile> outputsToRefresh = new ArrayList<VirtualFile>();
+
+        final VirtualFile[] all = context.getAllOutputDirectories();
+
+        final ProgressIndicator progressIndicator = context.getProgressIndicator();
+
+        //final int totalCount = all.length + myGenerationCompilerModuleToOutputDirMap.size() * 2;
+        progressIndicator.pushState();
+        progressIndicator.setText("Inspecting output directories...");
+        try {
+          for (VirtualFile output : all) {
+            if (output.isValid()) {
+              walkChildren(output, context);
+            }
+            else {
+              needRecalcOutputDirs = true;
+              final File file = new File(output.getPath());
+              if (!file.exists()) {
+                final boolean created = file.mkdirs();
+                if (!created) {
+                  context.addMessage(CompilerMessageCategory.ERROR, "Failed to create output directory " + file.getPath(), null, 0, 0);
+                  return ExitStatus.ERRORS;
+                }
+              }
+              output = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+              if (output == null) {
+                context.addMessage(CompilerMessageCategory.ERROR, "Failed to locate output directory " + file.getPath(), null, 0, 0);
+                return ExitStatus.ERRORS;
+              }
+            }
+            outputsToRefresh.add(output);
+          }
+          for (Pair<IntermediateOutputCompiler, Module> pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
+            final Pair<VirtualFile, VirtualFile> generated = myGenerationCompilerModuleToOutputDirMap.get(pair);
+            walkChildren(generated.getFirst(), context);
+            outputsToRefresh.add(generated.getFirst());
+            walkChildren(generated.getSecond(), context);
+            outputsToRefresh.add(generated.getSecond());
+          }
+
+          RefreshQueue.getInstance().refresh(false, true, null, outputsToRefresh);
+          if (progressIndicator.isCanceled()) {
+            return ExitStatus.CANCELLED;
+          }
+        }
+        finally {
+          progressIndicator.popState();
+        }
+
+        final long initialRefreshTime = System.currentTimeMillis() - refreshStart;
+        CompilerUtil.logDuration("Initial VFS refresh", initialRefreshTime);
+      }
+
+      //DumbService.getInstance(myProject).waitForSmartMode();
+      final Semaphore semaphore = new Semaphore();
+      semaphore.down();
+      DumbService.getInstance(myProject).runWhenSmart(new Runnable() {
+        public void run() {
+          semaphore.up();
+        }
+      });
+      while (!semaphore.waitFor(500)) {
+        if (context.getProgressIndicator().isCanceled()) {
+          return ExitStatus.CANCELLED;
+        }
+      }
+
+      if (needRecalcOutputDirs) {
+        context.recalculateOutputDirs();
+      }
+
+      boolean didSomething = false;
+
+      final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+      GenericCompilerRunner runner = new GenericCompilerRunner(context, isRebuild, onlyCheckStatus,
+                                                               compilerManager.getCompilers(GenericCompiler.class, myCompilerFilter));
+      try {
+        didSomething |= generateSources(compilerManager, context, forceCompile, onlyCheckStatus);
+
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, SourceInstrumentingCompiler.class,
+                                                      FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, forceCompile, true, onlyCheckStatus);
+
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, SourceProcessingCompiler.class,
+                                                      FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, forceCompile, true, onlyCheckStatus);
+
+        final CompileScope intermediateSources = attachIntermediateOutputDirectories(new CompositeScope(CompileScope.EMPTY_ARRAY) {
+          @NotNull
+          public Module[] getAffectedModules() {
+            return context.getCompileScope().getAffectedModules();
+          }
+        }, SOURCE_PROCESSING_ONLY);
+        context.addScope(intermediateSources);
+
+        didSomething |= translate(context, compilerManager, forceCompile, isRebuild, onlyCheckStatus);
+
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassInstrumentingCompiler.class,
+                                                      FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, isRebuild, false, onlyCheckStatus);
+        didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.CLASS_INSTRUMENTING);
+
+        // explicitly passing forceCompile = false because in scopes that is narrower than ProjectScope it is impossible
+        // to understand whether the class to be processed is in scope or not. Otherwise compiler may process its items even if
+        // there were changes in completely independent files.
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, ClassPostProcessingCompiler.class,
+                                                      FILE_PROCESSING_COMPILER_ADAPTER_FACTORY, isRebuild, false, onlyCheckStatus);
+        didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.CLASS_POST_PROCESSING);
+
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, PackagingCompiler.class,
+                                                      FILE_PACKAGING_COMPILER_ADAPTER_FACTORY,
+                                                      isRebuild, false, onlyCheckStatus);
+        didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.PACKAGING);
+
+        didSomething |= invokeFileProcessingCompilers(compilerManager, context, Validator.class, FILE_PROCESSING_COMPILER_ADAPTER_FACTORY,
+                                                      forceCompile, true, onlyCheckStatus);
+        didSomething |= runner.invokeCompilers(GenericCompiler.CompileOrderPlace.VALIDATING);
+      }
+      catch (ExitException e) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug(e);
+          logErrorMessages(context);
+        }
+        return e.getExitStatus();
+      }
+      finally {
+        // drop in case it has not been dropped yet.
+        dropDependencyCache(context);
+        final VirtualFile[] allOutputDirs = context.getAllOutputDirectories();
+
+        if (didSomething && GENERATE_CLASSPATH_INDEX) {
+          CompilerUtil.runInContext(context, "Generating classpath index...", new ThrowableRunnable<RuntimeException>(){
+            public void run() {
+              int count = 0;
+              for (VirtualFile file : allOutputDirs) {
+                context.getProgressIndicator().setFraction((double)++count / allOutputDirs.length);
+                createClasspathIndex(file);
+              }
+            }
+          });
+        }
+
+      }
+
+      if (!onlyCheckStatus) {
+          if (!executeCompileTasks(context, false)) {
+            return ExitStatus.CANCELLED;
+          }
+          final int constantSearchesCount = ChangedConstantsDependencyProcessor.getConstantSearchesCount(context);
+          LOG.debug("Constants searches: " + constantSearchesCount);
+        }
+
+      if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        if (LOG.isDebugEnabled()) {
+          logErrorMessages(context);
+        }
+        return ExitStatus.ERRORS;
+      }
+      if (!didSomething) {
+        return ExitStatus.UP_TO_DATE;
+      }
+      return ExitStatus.SUCCESS;
+    }
+    catch (ProcessCanceledException e) {
+      return ExitStatus.CANCELLED;
+    }
+  }
+
+  private void clearAffectedOutputPathsIfPossible(final CompileContextEx context) {
+    final List<File> scopeOutputs = new ReadAction<List<File>>() {
+      protected void run(final Result<List<File>> result) {
+        final MultiMap<File, Module> outputToModulesMap = new MultiMap<File, Module>();
+        for (Module module : ModuleManager.getInstance(myProject).getModules()) {
+          final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+          if (compilerModuleExtension == null) {
+            continue;
+          }
+          final String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl();
+          if (outputPathUrl != null) {
+            final String path = VirtualFileManager.extractPath(outputPathUrl);
+            outputToModulesMap.putValue(new File(path), module);
+          }
+
+          final String outputPathForTestsUrl = compilerModuleExtension.getCompilerOutputUrlForTests();
+          if (outputPathForTestsUrl != null) {
+            final String path = VirtualFileManager.extractPath(outputPathForTestsUrl);
+            outputToModulesMap.putValue(new File(path), module);
+          }
+        }
+        final Set<Module> affectedModules = new HashSet<Module>(Arrays.asList(context.getCompileScope().getAffectedModules()));
+        List<File> scopeOutputs = new ArrayList<File>(affectedModules.size() * 2);
+        for (File output : outputToModulesMap.keySet()) {
+          if (affectedModules.containsAll(outputToModulesMap.get(output))) {
+            scopeOutputs.add(output);
+          }
+        }
+
+        final Set<Artifact> artifactsToBuild = ArtifactCompileScope.getArtifactsToBuild(myProject, context.getCompileScope(), true);
+        for (Artifact artifact : artifactsToBuild) {
+          final String outputFilePath = ((ArtifactImpl)artifact).getOutputDirectoryPathToCleanOnRebuild();
+          if (outputFilePath != null) {
+            scopeOutputs.add(new File(FileUtil.toSystemDependentName(outputFilePath)));
+          }
+        }
+        result.setResult(scopeOutputs);
+      }
+    }.execute().getResultObject();
+    if (scopeOutputs.size() > 0) {
+      CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable<RuntimeException>() {
+        public void run() {
+          CompilerUtil.clearOutputDirectories(scopeOutputs);
+        }
+      });
+    }
+  }
+
+  private static void logErrorMessages(final CompileContext context) {
+    final CompilerMessage[] errors = context.getMessages(CompilerMessageCategory.ERROR);
+    if (errors.length > 0) {
+      LOG.debug("Errors reported: ");
+      for (CompilerMessage error : errors) {
+        LOG.debug("\t" + error.getMessage());
+      }
+    }
+  }
+
+  private static void walkChildren(VirtualFile from, final CompileContext context) {
+    VfsUtilCore.visitChildrenRecursively(from, new VirtualFileVisitor() {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile file) {
+        if (file.isDirectory()) {
+          context.getProgressIndicator().checkCanceled();
+          context.getProgressIndicator().setText2(file.getPresentableUrl());
+        }
+        return true;
+      }
+    });
+  }
+
+  private static void createClasspathIndex(final VirtualFile file) {
+    try {
+      BufferedWriter writer = new BufferedWriter(new FileWriter(new File(VfsUtilCore.virtualToIoFile(file), "classpath.index")));
+      try {
+        writeIndex(writer, file, file);
+      }
+      finally {
+        writer.close();
+      }
+    }
+    catch (IOException e) {
+      // Ignore. Failed to create optional classpath index
+    }
+  }
+
+  private static void writeIndex(final BufferedWriter writer, final VirtualFile root, final VirtualFile file) throws IOException {
+    VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile file) {
+        try {
+          writer.write(VfsUtilCore.getRelativePath(file, root, '/'));
+          writer.write('\n');
+          return true;
+        }
+        catch (IOException e) {
+          throw new VisitorException(e);
+        }
+      }
+    }, IOException.class);
+  }
+
+  private static void dropDependencyCache(final CompileContextEx context) {
+    CompilerUtil.runInContext(context, CompilerBundle.message("progress.saving.caches"), new ThrowableRunnable<RuntimeException>(){
+      public void run() {
+        context.getDependencyCache().resetState();
+      }
+    });
+  }
+
+  private boolean generateSources(final CompilerManager compilerManager,
+                                  CompileContextEx context,
+                                  final boolean forceCompile,
+                                  final boolean onlyCheckStatus) throws ExitException {
+    boolean didSomething = false;
+
+    final SourceGeneratingCompiler[] sourceGenerators = compilerManager.getCompilers(SourceGeneratingCompiler.class, myCompilerFilter);
+    for (final SourceGeneratingCompiler sourceGenerator : sourceGenerators) {
+      if (context.getProgressIndicator().isCanceled()) {
+        throw new ExitException(ExitStatus.CANCELLED);
+      }
+
+      final boolean generatedSomething = generateOutput(context, sourceGenerator, forceCompile, onlyCheckStatus);
+
+      if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        throw new ExitException(ExitStatus.ERRORS);
+      }
+      didSomething |= generatedSomething;
+    }
+    return didSomething;
+  }
+
+  private boolean translate(final CompileContextEx context,
+                            final CompilerManager compilerManager,
+                            final boolean forceCompile,
+                            boolean isRebuild,
+                            final boolean onlyCheckStatus) throws ExitException {
+
+    boolean didSomething = false;
+
+    final TranslatingCompiler[] translators = compilerManager.getCompilers(TranslatingCompiler.class, myCompilerFilter);
+
+
+    final List<Chunk<Module>> sortedChunks = Collections.unmodifiableList(ApplicationManager.getApplication().runReadAction(new Computable<List<Chunk<Module>>>() {
+      public List<Chunk<Module>> compute() {
+        final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
+        return ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(moduleManager.getModules()));
+      }
+    }));
+
+    final DumbService dumbService = DumbService.getInstance(myProject);
+    try {
+      final Set<Module> processedModules = new HashSet<Module>();
+      VirtualFile[] snapshot = null;
+      final Map<Chunk<Module>, Collection<VirtualFile>> chunkMap = new HashMap<Chunk<Module>, Collection<VirtualFile>>();
+      int total = 0;
+      int processed = 0;
+      for (final Chunk<Module> currentChunk : sortedChunks) {
+        final TranslatorsOutputSink sink = new TranslatorsOutputSink(context, translators);
+        final Set<FileType> generatedTypes = new HashSet<FileType>();
+        Collection<VirtualFile> chunkFiles = chunkMap.get(currentChunk);
+        final Set<VirtualFile> filesToRecompile = new HashSet<VirtualFile>();
+        final Set<VirtualFile> allDependent = new HashSet<VirtualFile>();
+        try {
+          int round = 0;
+          boolean compiledSomethingForThisChunk = false;
+          Collection<VirtualFile> dependentFiles = Collections.emptyList();
+          final Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> dependencyFilter = new DependentClassesCumulativeFilter();
+          
+          do {
+            for (int currentCompiler = 0, translatorsLength = translators.length; currentCompiler < translatorsLength; currentCompiler++) {
+              sink.setCurrentCompilerIndex(currentCompiler);
+              final TranslatingCompiler compiler = translators[currentCompiler];
+              if (context.getProgressIndicator().isCanceled()) {
+                throw new ExitException(ExitStatus.CANCELLED);
+              }
+
+              dumbService.waitForSmartMode();
+
+              if (snapshot == null || ContainerUtil.intersects(generatedTypes, compilerManager.getRegisteredInputTypes(compiler))) {
+                // rescan snapshot if previously generated files may influence the input of this compiler
+                final Set<VirtualFile> prevSnapshot = round > 0 && snapshot != null? new HashSet<VirtualFile>(Arrays.asList(snapshot)) : Collections.<VirtualFile>emptySet();
+                snapshot = ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
+                  public VirtualFile[] compute() {
+                    return context.getCompileScope().getFiles(null, true);
+                  }
+                });
+                recalculateChunkToFilesMap(context, sortedChunks, snapshot, chunkMap);
+                if (round == 0) {
+                  chunkFiles = chunkMap.get(currentChunk);
+                }
+                else {
+                  final Set<VirtualFile> newFiles = new HashSet<VirtualFile>(chunkMap.get(currentChunk));
+                  newFiles.removeAll(prevSnapshot);
+                  newFiles.removeAll(chunkFiles);
+                  if (!newFiles.isEmpty()) {
+                    final ArrayList<VirtualFile> merged = new ArrayList<VirtualFile>(chunkFiles.size() + newFiles.size());
+                    merged.addAll(chunkFiles);
+                    merged.addAll(newFiles);
+                    chunkFiles = merged;
+                  }
+                }
+                total = snapshot.length * translatorsLength;
+              }
+
+              final CompileContextEx _context;
+              if (compiler instanceof IntermediateOutputCompiler) {
+                // wrap compile context so that output goes into intermediate directories
+                final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler;
+                _context = new CompileContextExProxy(context) {
+                  public VirtualFile getModuleOutputDirectory(final Module module) {
+                    return getGenerationOutputDir(_compiler, module, false);
+                  }
+  
+                  public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
+                    return getGenerationOutputDir(_compiler, module, true);
+                  }
+                };
+              }
+              else {
+                _context = context;
+              }
+              final boolean compiledSomething =
+                compileSources(_context, currentChunk, compiler, chunkFiles, round == 0? forceCompile : true, isRebuild, onlyCheckStatus, sink);
+  
+              processed += chunkFiles.size();
+              _context.getProgressIndicator().setFraction(((double)processed) / total);
+  
+              if (compiledSomething) {
+                generatedTypes.addAll(compilerManager.getRegisteredOutputTypes(compiler));
+              }
+  
+              didSomething |= compiledSomething;
+              compiledSomethingForThisChunk |= didSomething;
+
+              if (_context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+                break; // break the loop over compilers
+              }
+            }
+
+            final boolean hasUnprocessedTraverseRoots = context.getDependencyCache().hasUnprocessedTraverseRoots();
+            if (!isRebuild && (compiledSomethingForThisChunk || hasUnprocessedTraverseRoots)) {
+              final Set<VirtualFile> compiledWithErrors = CacheUtils.getFilesCompiledWithErrors(context);
+              filesToRecompile.removeAll(sink.getCompiledSources());
+              filesToRecompile.addAll(compiledWithErrors);
+
+              dependentFiles = CacheUtils.findDependentFiles(context, compiledWithErrors, dependencyFilter);
+              if (!processedModules.isEmpty()) {
+                for (Iterator<VirtualFile> it = dependentFiles.iterator(); it.hasNext();) {
+                  final VirtualFile next = it.next();
+                  final Module module = context.getModuleByFile(next);
+                  if (module != null && processedModules.contains(module)) {
+                    it.remove();
+                  }
+                }
+              }
+              
+              if (ourDebugMode) {
+                if (!dependentFiles.isEmpty()) {
+                  for (VirtualFile dependentFile : dependentFiles) {
+                    System.out.println("FOUND TO RECOMPILE: " + dependentFile.getPresentableUrl());
+                  }
+                }
+                else {
+                  System.out.println("NO FILES TO RECOMPILE");
+                }
+              }
+
+              if (!dependentFiles.isEmpty()) {
+                filesToRecompile.addAll(dependentFiles);
+                allDependent.addAll(dependentFiles);
+                if (context.getProgressIndicator().isCanceled() || context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+                  break;
+                }
+                final List<VirtualFile> filesInScope = getFilesInScope(context, currentChunk, dependentFiles);
+                if (filesInScope.isEmpty()) {
+                  break;
+                }
+                context.getDependencyCache().clearTraverseRoots();
+                chunkFiles = filesInScope;
+                total += chunkFiles.size() * translators.length;
+              }
+              
+              didSomething |= (hasUnprocessedTraverseRoots != context.getDependencyCache().hasUnprocessedTraverseRoots());
+            }
+
+            round++;
+          }
+          while (!dependentFiles.isEmpty() && context.getMessageCount(CompilerMessageCategory.ERROR) == 0);
+
+          if (CompilerConfiguration.MAKE_ENABLED) {
+            if (!context.getProgressIndicator().isCanceled()) {
+              // when cancelled pretend nothing was compiled and next compile will compile everything from the scratch
+              final ProgressIndicator indicator = context.getProgressIndicator();
+              final DependencyCache cache = context.getDependencyCache();
+
+              indicator.pushState();
+              indicator.setText(CompilerBundle.message("progress.updating.caches"));
+              indicator.setText2("");
+
+              cache.update();
+
+              indicator.setText(CompilerBundle.message("progress.saving.caches"));
+              cache.resetState();
+              processedModules.addAll(currentChunk.getNodes());
+              indicator.popState();
+            }
+          }
+
+          if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+            throw new ExitException(ExitStatus.ERRORS);
+          }
+
+        }
+        catch (CacheCorruptedException e) {
+          LOG.info(e);
+          context.requestRebuildNextTime(e.getMessage());
+        }
+        finally {
+          final int errorCount = context.getMessageCount(CompilerMessageCategory.ERROR);
+          if (errorCount != 0) {
+            filesToRecompile.addAll(allDependent);
+          }
+          if (filesToRecompile.size() > 0) {
+            sink.add(null, Collections.<TranslatingCompiler.OutputItem>emptyList(), VfsUtilCore.toVirtualFileArray(filesToRecompile));
+          }
+          if (errorCount == 0) {
+            // perform update only if there were no errors, so it is guaranteed that the file was processd by all neccesary compilers
+            sink.flushPostponedItems();
+          }
+        }
+      }
+    }
+    catch (ProcessCanceledException e) {
+      ProgressManager.getInstance().executeNonCancelableSection(new Runnable() {
+        public void run() {
+          try {
+            final Collection<VirtualFile> deps = CacheUtils.findDependentFiles(context, Collections.<VirtualFile>emptySet(), null);
+            if (deps.size() > 0) {
+              TranslatingCompilerFilesMonitor.getInstance().update(context, null, Collections.<TranslatingCompiler.OutputItem>emptyList(),
+                                                                   VfsUtilCore.toVirtualFileArray(deps));
+            }
+          }
+          catch (IOException ignored) {
+            LOG.info(ignored);
+          }
+          catch (CacheCorruptedException ignored) {
+            LOG.info(ignored);
+          }
+          catch (ExitException e1) {
+            LOG.info(e1);
+          }
+        }
+      });
+      throw e;
+    }
+    finally {
+      dropDependencyCache(context);
+      if (didSomething) {
+        TranslatingCompilerFilesMonitor.getInstance().updateOutputRootsLayout(myProject);
+      }
+    }
+    return didSomething;
+  }
+
+  private static List<VirtualFile> getFilesInScope(final CompileContextEx context, final Chunk<Module> chunk, final Collection<VirtualFile> files) {
+    final List<VirtualFile> filesInScope = new ArrayList<VirtualFile>(files.size());
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        for (VirtualFile file : files) {
+          if (context.getCompileScope().belongs(file.getUrl())) {
+            final Module module = context.getModuleByFile(file);
+            if (chunk.getNodes().contains(module)) {
+              filesInScope.add(file);
+            }
+          }
+        }
+      }
+    });
+    return filesInScope;
+  }
+
+  private static void recalculateChunkToFilesMap(CompileContextEx context, List<Chunk<Module>> allChunks, VirtualFile[] snapshot, Map<Chunk<Module>, Collection<VirtualFile>> chunkMap) {
+    final Map<Module, List<VirtualFile>> moduleToFilesMap = CompilerUtil.buildModuleToFilesMap(context, snapshot);
+    for (Chunk<Module> moduleChunk : allChunks) {
+      List<VirtualFile> files = Collections.emptyList();
+      for (Module module : moduleChunk.getNodes()) {
+        final List<VirtualFile> moduleFiles = moduleToFilesMap.get(module);
+        if (moduleFiles != null) {
+          files = ContainerUtil.concat(files, moduleFiles);
+        }
+      }
+      chunkMap.put(moduleChunk, files);
+    }
+  }
+
+  private interface FileProcessingCompilerAdapterFactory {
+    FileProcessingCompilerAdapter create(CompileContext context, FileProcessingCompiler compiler);
+  }
+
+  private boolean invokeFileProcessingCompilers(final CompilerManager compilerManager,
+                                                CompileContextEx context,
+                                                Class<? extends FileProcessingCompiler> fileProcessingCompilerClass,
+                                                FileProcessingCompilerAdapterFactory factory,
+                                                boolean forceCompile,
+                                                final boolean checkScope,
+                                                final boolean onlyCheckStatus) throws ExitException {
+    boolean didSomething = false;
+    final FileProcessingCompiler[] compilers = compilerManager.getCompilers(fileProcessingCompilerClass, myCompilerFilter);
+    if (compilers.length > 0) {
+      try {
+        CacheDeferredUpdater cacheUpdater = new CacheDeferredUpdater();
+        try {
+          for (final FileProcessingCompiler compiler : compilers) {
+            if (context.getProgressIndicator().isCanceled()) {
+              throw new ExitException(ExitStatus.CANCELLED);
+            }
+
+            CompileContextEx _context = context;
+            if (compiler instanceof IntermediateOutputCompiler) {
+              final IntermediateOutputCompiler _compiler = (IntermediateOutputCompiler)compiler;
+              _context = new CompileContextExProxy(context) {
+                public VirtualFile getModuleOutputDirectory(final Module module) {
+                  return getGenerationOutputDir(_compiler, module, false);
+                }
+
+                public VirtualFile getModuleOutputDirectoryForTests(final Module module) {
+                  return getGenerationOutputDir(_compiler, module, true);
+                }
+              };
+            }
+
+            final boolean processedSomething = processFiles(factory.create(_context, compiler), forceCompile, checkScope, onlyCheckStatus, cacheUpdater);
+
+            if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+              throw new ExitException(ExitStatus.ERRORS);
+            }
+
+            didSomething |= processedSomething;
+          }
+        }
+        finally {
+          cacheUpdater.doUpdate();
+        }
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        context.requestRebuildNextTime(e.getMessage());
+        throw new ExitException(ExitStatus.ERRORS);
+      }
+      catch (ProcessCanceledException e) {
+        throw e;
+      }
+      catch (ExitException e) {
+        throw e;
+      }
+      catch (Exception e) {
+        context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1);
+        LOG.error(e);
+      }
+    }
+
+    return didSomething;
+  }
+
+  private static Map<Module, Set<GeneratingCompiler.GenerationItem>> buildModuleToGenerationItemMap(GeneratingCompiler.GenerationItem[] items) {
+    final Map<Module, Set<GeneratingCompiler.GenerationItem>> map = new HashMap<Module, Set<GeneratingCompiler.GenerationItem>>();
+    for (GeneratingCompiler.GenerationItem item : items) {
+      Module module = item.getModule();
+      LOG.assertTrue(module != null);
+      Set<GeneratingCompiler.GenerationItem> itemSet = map.get(module);
+      if (itemSet == null) {
+        itemSet = new HashSet<GeneratingCompiler.GenerationItem>();
+        map.put(module, itemSet);
+      }
+      itemSet.add(item);
+    }
+    return map;
+  }
+
+  private void deleteAll(final CompileContextEx context) {
+    CompilerUtil.runInContext(context, CompilerBundle.message("progress.clearing.output"), new ThrowableRunnable<RuntimeException>() {
+      public void run() {
+        final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode();
+        final VirtualFile[] allSources = context.getProjectCompileScope().getFiles(null, true);
+        if (myShouldClearOutputDirectory) {
+          CompilerUtil.clearOutputDirectories(myAllOutputDirectories);
+        }
+        else { // refresh is still required
+          try {
+            for (final Compiler compiler : CompilerManager.getInstance(myProject).getCompilers(Compiler.class)) {
+              try {
+                if (compiler instanceof GeneratingCompiler) {
+                  final StateCache<ValidityState> cache = getGeneratingCompilerCache((GeneratingCompiler)compiler);
+                  final Iterator<String> urlIterator = cache.getUrlsIterator();
+                  while (urlIterator.hasNext()) {
+                    context.getProgressIndicator().checkCanceled();
+                    deleteFile(new File(VirtualFileManager.extractPath(urlIterator.next())));
+                  }
+                }
+                else if (compiler instanceof TranslatingCompiler) {
+                  final ArrayList<Trinity<File, String, Boolean>> toDelete = new ArrayList<Trinity<File, String, Boolean>>();
+                  ApplicationManager.getApplication().runReadAction(new Runnable() {
+                    public void run() {
+                      TranslatingCompilerFilesMonitor.getInstance().collectFiles(
+                        context, 
+                        (TranslatingCompiler)compiler, Arrays.<VirtualFile>asList(allSources).iterator(), 
+                        true /*pass true to make sure that every source in scope file is processed*/, 
+                        false /*important! should pass false to enable collection of files to delete*/,
+                        new ArrayList<VirtualFile>(), 
+                        toDelete
+                      );
+                    }
+                  });
+                  for (Trinity<File, String, Boolean> trinity : toDelete) {
+                    context.getProgressIndicator().checkCanceled();
+                    final File file = trinity.getFirst();
+                    deleteFile(file);
+                    if (isTestMode) {
+                      CompilerManagerImpl.addDeletedPath(file.getPath());
+                    }
+                  }
+                }
+              }
+              catch (IOException e) {
+                LOG.info(e);
+              }
+            }
+            pruneEmptyDirectories(context.getProgressIndicator(), myAllOutputDirectories); // to avoid too much files deleted events
+          }
+          finally {
+            CompilerUtil.refreshIODirectories(myAllOutputDirectories);
+          }
+        }
+        dropScopesCaches();
+
+        clearCompilerSystemDirectory(context);
+      }
+    });
+  }
+
+  private void dropScopesCaches() {
+    // hack to be sure the classpath will include the output directories
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        ((ProjectRootManagerEx)ProjectRootManager.getInstance(myProject)).clearScopesCachesForModules();
+      }
+    });
+  }
+
+  private static void pruneEmptyDirectories(ProgressIndicator progress, final Set<File> directories) {
+    for (File directory : directories) {
+      doPrune(progress, directory, directories);
+    }
+  }
+
+  private static boolean doPrune(ProgressIndicator progress, final File directory, final Set<File> outPutDirectories) {
+    progress.checkCanceled();
+    final File[] files = directory.listFiles();
+    boolean isEmpty = true;
+    if (files != null) {
+      for (File file : files) {
+        if (!outPutDirectories.contains(file)) {
+          if (doPrune(progress, file, outPutDirectories)) {
+            deleteFile(file);
+          }
+          else {
+            isEmpty = false;
+          }
+        }
+        else {
+          isEmpty = false;
+        }
+      }
+    }
+    else {
+      isEmpty = false;
+    }
+
+    return isEmpty;
+  }
+
+  private Set<File> getAllOutputDirectories(CompileContext context) {
+    final Set<File> outputDirs = new OrderedSet<File>();
+    final Module[] modules = ModuleManager.getInstance(myProject).getModules();
+    for (final String path : CompilerPathsEx.getOutputPaths(modules)) {
+      outputDirs.add(new File(path));
+    }
+    for (Pair<IntermediateOutputCompiler, Module> pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
+      outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false)));
+      outputDirs.add(new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true)));
+    }
+    final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
+    if (context.isAnnotationProcessorsEnabled()) {
+      for (Module module : modules) {
+        if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
+          final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+          if (path != null) {
+            outputDirs.add(new File(path));
+          }
+        }
+      }
+    }
+    for (Artifact artifact : ArtifactManager.getInstance(myProject).getArtifacts()) {
+      final String path = ((ArtifactImpl)artifact).getOutputDirectoryPathToCleanOnRebuild();
+      if (path != null) {
+        outputDirs.add(new File(FileUtil.toSystemDependentName(path)));
+      }
+    }
+    return outputDirs;
+  }
+
+  private void clearCompilerSystemDirectory(final CompileContextEx context) {
+    CompilerCacheManager.getInstance(myProject).clearCaches(context);
+    FileUtil.delete(CompilerPathsEx.getZipStoreDirectory(myProject));
+    dropDependencyCache(context);
+
+    for (Pair<IntermediateOutputCompiler, Module> pair : myGenerationCompilerModuleToOutputDirMap.keySet()) {
+      final File[] outputs = {
+        new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), false)),
+        new File(CompilerPaths.getGenerationOutputPath(pair.getFirst(), pair.getSecond(), true))
+      };
+      for (File output : outputs) {
+        final File[] files = output.listFiles();
+        if (files != null) {
+          for (final File file : files) {
+            final boolean deleteOk = deleteFile(file);
+            if (!deleteOk) {
+              context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.failed.to.delete", file.getPath()),
+                                 null, -1, -1);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   * @param file a file to delete
+   * @return true if and only if the file existed and was successfully deleted
+   * Note: the behaviour is different from FileUtil.delete() which returns true if the file absent on the disk
+   */
+  private static boolean deleteFile(final File file) {
+    File[] files = file.listFiles();
+    if (files != null) {
+      for (File file1 : files) {
+        deleteFile(file1);
+      }
+    }
+
+    for (int i = 0; i < 10; i++){
+      if (file.delete()) {
+        return true;
+      }
+      if (!file.exists()) {
+        return false;
+      }
+      try {
+        Thread.sleep(50);
+      }
+      catch (InterruptedException ignored) {
+      }
+    }
+    return false;
+  }
+
+  private VirtualFile getGenerationOutputDir(final IntermediateOutputCompiler compiler, final Module module, final boolean forTestSources) {
+    final Pair<VirtualFile, VirtualFile> outputs =
+      myGenerationCompilerModuleToOutputDirMap.get(new Pair<IntermediateOutputCompiler, Module>(compiler, module));
+    return forTestSources? outputs.getSecond() : outputs.getFirst();
+  }
+
+  private boolean generateOutput(final CompileContextEx context,
+                                 final GeneratingCompiler compiler,
+                                 final boolean forceGenerate,
+                                 final boolean onlyCheckStatus) throws ExitException {
+    final GeneratingCompiler.GenerationItem[] allItems = compiler.getGenerationItems(context);
+    final List<GeneratingCompiler.GenerationItem> toGenerate = new ArrayList<GeneratingCompiler.GenerationItem>();
+    final List<File> filesToRefresh = new ArrayList<File>();
+    final List<File> generatedFiles = new ArrayList<File>();
+    final List<Module> affectedModules = new ArrayList<Module>();
+    try {
+      final StateCache<ValidityState> cache = getGeneratingCompilerCache(compiler);
+      final Set<String> pathsToRemove = new HashSet<String>(cache.getUrls());
+
+      final Map<GeneratingCompiler.GenerationItem, String> itemToOutputPathMap = new HashMap<GeneratingCompiler.GenerationItem, String>();
+      final IOException[] ex = {null};
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          for (final GeneratingCompiler.GenerationItem item : allItems) {
+            final Module itemModule = item.getModule();
+            final String outputDirPath = CompilerPaths.getGenerationOutputPath(compiler, itemModule, item.isTestSource());
+            final String outputPath = outputDirPath + "/" + item.getPath();
+            itemToOutputPathMap.put(item, outputPath);
+
+            try {
+              final ValidityState savedState = cache.getState(outputPath);
+
+              if (forceGenerate || savedState == null || !savedState.equalsTo(item.getValidityState())) {
+                final String outputPathUrl = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, outputPath);
+                if (context.getCompileScope().belongs(outputPathUrl)) {
+                  toGenerate.add(item);
+                }
+                else {
+                  pathsToRemove.remove(outputPath);
+                }
+              }
+              else {
+                pathsToRemove.remove(outputPath);
+              }
+            }
+            catch (IOException e) {
+              ex[0] = e;
+            }
+          }
+        }
+      });
+      if (ex[0] != null) {
+        throw ex[0];
+      }                   
+
+      if (onlyCheckStatus) {
+        if (toGenerate.isEmpty() && pathsToRemove.isEmpty()) {
+          return false;
+        }
+        if (LOG.isDebugEnabled()) {
+          if (!toGenerate.isEmpty()) {
+            LOG.debug("Found items to generate, compiler " + compiler.getDescription());
+          }
+          if (!pathsToRemove.isEmpty()) {
+            LOG.debug("Found paths to remove, compiler " + compiler.getDescription());
+          }
+        }
+        throw new ExitException(ExitStatus.CANCELLED);
+      }
+
+      if (!pathsToRemove.isEmpty()) {
+        CompilerUtil.runInContext(context, CompilerBundle.message("progress.synchronizing.output.directory"), new ThrowableRunnable<IOException>(){
+          public void run() throws IOException {
+            for (final String path : pathsToRemove) {
+              final File file = new File(path);
+              final boolean deleted = deleteFile(file);
+              if (deleted) {
+                cache.remove(path);
+                filesToRefresh.add(file);
+              }
+            }
+          }
+        });
+      }
+
+      final Map<Module, Set<GeneratingCompiler.GenerationItem>> moduleToItemMap =
+          buildModuleToGenerationItemMap(toGenerate.toArray(new GeneratingCompiler.GenerationItem[toGenerate.size()]));
+      List<Module> modules = new ArrayList<Module>(moduleToItemMap.size());
+      for (final Module module : moduleToItemMap.keySet()) {
+        modules.add(module);
+      }
+      ModuleCompilerUtil.sortModules(myProject, modules);
+
+      for (final Module module : modules) {
+        CompilerUtil.runInContext(context, "Generating output from "+compiler.getDescription(),new ThrowableRunnable<IOException>(){
+          public void run() throws IOException {
+            final Set<GeneratingCompiler.GenerationItem> items = moduleToItemMap.get(module);
+            if (items != null && !items.isEmpty()) {
+              final GeneratingCompiler.GenerationItem[][] productionAndTestItems = splitGenerationItems(items);
+              for (GeneratingCompiler.GenerationItem[] _items : productionAndTestItems) {
+                if (_items.length == 0) continue;
+                final VirtualFile outputDir = getGenerationOutputDir(compiler, module, _items[0].isTestSource());
+                final GeneratingCompiler.GenerationItem[] successfullyGenerated = compiler.generate(context, _items, outputDir);
+
+                CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable<IOException>() {
+                  public void run() throws IOException {
+                    if (successfullyGenerated.length > 0) {
+                      affectedModules.add(module);
+                    }
+                    for (final GeneratingCompiler.GenerationItem item : successfullyGenerated) {
+                      final String fullOutputPath = itemToOutputPathMap.get(item);
+                      cache.update(fullOutputPath, item.getValidityState());
+                      final File file = new File(fullOutputPath);
+                      filesToRefresh.add(file);
+                      generatedFiles.add(file);
+                      context.getProgressIndicator().setText2(file.getPath());
+                    }
+                  }
+                });
+              }
+            }
+          }
+        });
+      }
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      context.requestRebuildNextTime(e.getMessage());
+      throw new ExitException(ExitStatus.ERRORS);
+    }
+    finally {
+      CompilerUtil.refreshIOFiles(filesToRefresh);
+      if (!generatedFiles.isEmpty()) {
+        DumbService.getInstance(myProject).waitForSmartMode();
+        List<VirtualFile> vFiles = ApplicationManager.getApplication().runReadAction(new Computable<List<VirtualFile>>() {
+          public List<VirtualFile> compute() {
+            final ArrayList<VirtualFile> vFiles = new ArrayList<VirtualFile>(generatedFiles.size());
+            for (File generatedFile : generatedFiles) {
+              final VirtualFile vFile = LocalFileSystem.getInstance().findFileByIoFile(generatedFile);
+              if (vFile != null) {
+                vFiles.add(vFile);
+              }
+            }
+            return vFiles;
+          }
+        });
+        if (forceGenerate) {
+          context.addScope(new FileSetCompileScope(vFiles, affectedModules.toArray(new Module[affectedModules.size()])));
+        }
+        context.markGenerated(vFiles);
+      }
+    }
+    return !toGenerate.isEmpty() || !filesToRefresh.isEmpty();
+  }
+
+  private static GeneratingCompiler.GenerationItem[][] splitGenerationItems(final Set<GeneratingCompiler.GenerationItem> items) {
+    final List<GeneratingCompiler.GenerationItem> production = new ArrayList<GeneratingCompiler.GenerationItem>();
+    final List<GeneratingCompiler.GenerationItem> tests = new ArrayList<GeneratingCompiler.GenerationItem>();
+    for (GeneratingCompiler.GenerationItem item : items) {
+      if (item.isTestSource()) {
+        tests.add(item);
+      }
+      else {
+        production.add(item);
+      }
+    }
+    return new GeneratingCompiler.GenerationItem[][]{
+      production.toArray(new GeneratingCompiler.GenerationItem[production.size()]),
+      tests.toArray(new GeneratingCompiler.GenerationItem[tests.size()])
+    };
+  }
+
+  private boolean compileSources(final CompileContextEx context,
+                                 final Chunk<Module> moduleChunk,
+                                 final TranslatingCompiler compiler,
+                                 final Collection<VirtualFile> srcSnapshot,
+                                 final boolean forceCompile,
+                                 final boolean isRebuild,
+                                 final boolean onlyCheckStatus,
+                                 TranslatingCompiler.OutputSink sink) throws ExitException {
+
+    final Set<VirtualFile> toCompile = new HashSet<VirtualFile>();
+    final List<Trinity<File, String, Boolean>> toDelete = new ArrayList<Trinity<File, String, Boolean>>();
+    context.getProgressIndicator().pushState();
+
+    final boolean[] wereFilesDeleted = {false};
+    try {
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          TranslatingCompilerFilesMonitor.getInstance().collectFiles(
+            context, compiler, srcSnapshot.iterator(), forceCompile, isRebuild, toCompile, toDelete
+          );
+        }
+      });
+
+      if (onlyCheckStatus) {
+        if (toDelete.isEmpty() && toCompile.isEmpty()) {
+          return false;
+        }
+        if (LOG.isDebugEnabled() || ourDebugMode) {
+          if (!toDelete.isEmpty()) {
+            final StringBuilder message = new StringBuilder();
+            message.append("Found items to delete, compiler ").append(compiler.getDescription());
+            for (Trinity<File, String, Boolean> trinity : toDelete) {
+              message.append("\n").append(trinity.getFirst());
+            }
+            LOG.debug(message.toString());
+            if (ourDebugMode) {
+              System.out.println(message);
+            }
+          }
+          if (!toCompile.isEmpty()) {
+            final String message = "Found items to compile, compiler " + compiler.getDescription();
+            LOG.debug(message);
+            if (ourDebugMode) {
+              System.out.println(message);
+            }
+          }
+        }
+        throw new ExitException(ExitStatus.CANCELLED);
+      }
+
+      if (!toDelete.isEmpty()) {
+        try {
+          wereFilesDeleted[0] = syncOutputDir(context, toDelete);
+        }
+        catch (CacheCorruptedException e) {
+          LOG.info(e);
+          context.requestRebuildNextTime(e.getMessage());
+        }
+      }
+
+      if ((wereFilesDeleted[0] || !toCompile.isEmpty()) && context.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
+        compiler.compile(context, moduleChunk, VfsUtilCore.toVirtualFileArray(toCompile), sink);
+      }
+    }
+    finally {
+      context.getProgressIndicator().popState();
+    }
+    return !toCompile.isEmpty() || wereFilesDeleted[0];
+  }
+
+  private static boolean syncOutputDir(final CompileContextEx context, final Collection<Trinity<File, String, Boolean>> toDelete) throws CacheCorruptedException {
+    final DependencyCache dependencyCache = context.getDependencyCache();
+    final boolean isTestMode = ApplicationManager.getApplication().isUnitTestMode();
+
+    final List<File> filesToRefresh = new ArrayList<File>();
+    final boolean[] wereFilesDeleted = {false};
+    CompilerUtil.runInContext(context, CompilerBundle.message("progress.synchronizing.output.directory"), new ThrowableRunnable<CacheCorruptedException>(){
+      public void run() throws CacheCorruptedException {
+        final long start = System.currentTimeMillis();
+        try {
+          for (final Trinity<File, String, Boolean> trinity : toDelete) {
+            final File outputPath = trinity.getFirst();
+            context.getProgressIndicator().checkCanceled();
+            context.getProgressIndicator().setText2(outputPath.getPath());
+            filesToRefresh.add(outputPath);
+            if (isTestMode) {
+              LOG.assertTrue(outputPath.exists());
+            }
+            if (!deleteFile(outputPath)) {
+              if (isTestMode) {
+                if (outputPath.exists()) {
+                  LOG.error("Was not able to delete output file: " + outputPath.getPath());
+                }
+                else {
+                  CompilerManagerImpl.addDeletedPath(outputPath.getPath());
+                }
+              }
+              continue;
+            }
+            wereFilesDeleted[0] = true;
+
+            // update zip here
+            //final String outputDir = myOutputFinder.lookupOutputPath(outputPath);
+            //if (outputDir != null) {
+            //  try {
+            //    context.updateZippedOuput(outputDir, FileUtil.toSystemIndependentName(outputPath.getPath()).substring(outputDir.length() + 1));
+            //  }
+            //  catch (IOException e) {
+            //    LOG.info(e);
+            //  }
+            //}
+
+            final String className = trinity.getSecond();
+            if (className != null) {
+              final int id = dependencyCache.getSymbolTable().getId(className);
+              dependencyCache.addTraverseRoot(id);
+              final boolean sourcePresent = trinity.getThird().booleanValue();
+              if (!sourcePresent) {
+                dependencyCache.markSourceRemoved(id);
+              }
+            }
+            if (isTestMode) {
+              CompilerManagerImpl.addDeletedPath(outputPath.getPath());
+            }
+          }
+        }
+        finally {
+          CompilerUtil.logDuration("Sync output directory", System.currentTimeMillis() - start);
+          CompilerUtil.refreshIOFiles(filesToRefresh);
+        }
+      }
+    });
+    return wereFilesDeleted[0];
+  }
+
+  // [mike] performance optimization - this method is accessed > 15,000 times in Aurora
+  private String getModuleOutputPath(final Module module, boolean inTestSourceContent) {
+    final Map<Module, String> map = inTestSourceContent ? myModuleTestOutputPaths : myModuleOutputPaths;
+    String path = map.get(module);
+    if (path == null) {
+      path = CompilerPaths.getModuleOutputPath(module, inTestSourceContent);
+      map.put(module, path);
+    }
+
+    return path;
+  }
+
+  private boolean processFiles(final FileProcessingCompilerAdapter adapter,
+                               final boolean forceCompile,
+                               final boolean checkScope,
+                               final boolean onlyCheckStatus, final CacheDeferredUpdater cacheUpdater) throws ExitException, IOException {
+    final CompileContextEx context = (CompileContextEx)adapter.getCompileContext();
+    final FileProcessingCompilerStateCache cache = getFileProcessingCompilerCache(adapter.getCompiler());
+    final FileProcessingCompiler.ProcessingItem[] items = adapter.getProcessingItems();
+    if (context.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+      return false;
+    }
+    if (LOG.isDebugEnabled() && items.length > 0) {
+      LOG.debug("Start processing files by " + adapter.getCompiler().getDescription());
+    }
+    final CompileScope scope = context.getCompileScope();
+    final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
+    final Set<String> allUrls = new HashSet<String>();
+    final IOException[] ex = {null};
+    DumbService.getInstance(myProject).waitForSmartMode();
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          for (FileProcessingCompiler.ProcessingItem item : items) {
+            final VirtualFile file = item.getFile();
+            final String url = file.getUrl();
+            allUrls.add(url);
+            if (!forceCompile && cache.getTimestamp(url) == file.getTimeStamp()) {
+              final ValidityState state = cache.getExtState(url);
+              final ValidityState itemState = item.getValidityState();
+              if (state != null ? state.equalsTo(itemState) : itemState == null) {
+                continue;
+              }
+            }
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Adding item to process: " + url + "; saved ts= " + cache.getTimestamp(url) + "; VFS ts=" + file.getTimeStamp());
+            }
+            toProcess.add(item);
+          }
+        }
+        catch (IOException e) {
+          ex[0] = e;
+        }
+      }
+    });
+
+    if (ex[0] != null) {
+      throw ex[0];
+    }
+
+    final Collection<String> urls = cache.getUrls();
+    final List<String> urlsToRemove = new ArrayList<String>();
+    if (!urls.isEmpty()) {
+      CompilerUtil.runInContext(context, CompilerBundle.message("progress.processing.outdated.files"), new ThrowableRunnable<IOException>(){
+        public void run() throws IOException {
+          ApplicationManager.getApplication().runReadAction(new Runnable() {
+            public void run() {
+              for (final String url : urls) {
+                if (!allUrls.contains(url)) {
+                  if (!checkScope || scope.belongs(url)) {
+                    urlsToRemove.add(url);
+                  }
+                }
+              }
+            }
+          });
+          if (!onlyCheckStatus && !urlsToRemove.isEmpty()) {
+            for (final String url : urlsToRemove) {
+              adapter.processOutdatedItem(context, url, cache.getExtState(url));
+              cache.remove(url);
+            }
+          }
+        }
+      });
+    }
+
+    if (onlyCheckStatus) {
+      if (urlsToRemove.isEmpty() && toProcess.isEmpty()) {
+        return false;
+      }
+      if (LOG.isDebugEnabled()) {
+        if (!urlsToRemove.isEmpty()) {
+          LOG.debug("Found urls to remove, compiler " + adapter.getCompiler().getDescription());
+          for (String url : urlsToRemove) {
+            LOG.debug("\t" + url);
+          }
+        }
+        if (!toProcess.isEmpty()) {
+          LOG.debug("Found items to compile, compiler " + adapter.getCompiler().getDescription());
+          for (FileProcessingCompiler.ProcessingItem item : toProcess) {
+            LOG.debug("\t" + item.getFile().getPresentableUrl());
+          }
+        }
+      }
+      throw new ExitException(ExitStatus.CANCELLED);
+    }
+
+    if (toProcess.isEmpty()) {
+      return false;
+    }
+
+    final FileProcessingCompiler.ProcessingItem[] processed =
+      adapter.process(toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]));
+
+    if (processed.length == 0) {
+      return true;
+    }
+    CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable<IOException>() {
+      public void run() {
+        final List<VirtualFile> vFiles = new ArrayList<VirtualFile>(processed.length);
+        for (FileProcessingCompiler.ProcessingItem aProcessed : processed) {
+          final VirtualFile file = aProcessed.getFile();
+          vFiles.add(file);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("\tFile processed " + file.getPresentableUrl() + "; ts=" + file.getTimeStamp());
+          }
+
+          //final String path = file.getPath();
+          //final String outputDir = myOutputFinder.lookupOutputPath(path);
+          //if (outputDir != null) {
+          //  context.updateZippedOuput(outputDir, path.substring(outputDir.length() + 1));
+          //}
+        }
+        LocalFileSystem.getInstance().refreshFiles(vFiles);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Files after VFS refresh:");
+          for (VirtualFile file : vFiles) {
+            LOG.debug("\t" + file.getPresentableUrl() + "; ts=" + file.getTimeStamp());
+          }
+        }
+        for (FileProcessingCompiler.ProcessingItem item : processed) {
+          cacheUpdater.addFileForUpdate(item, cache);
+        }
+      }
+    });
+    return true;
+  }
+
+  private FileProcessingCompilerStateCache getFileProcessingCompilerCache(FileProcessingCompiler compiler) throws IOException {
+    return CompilerCacheManager.getInstance(myProject).getFileProcessingCompilerCache(compiler);
+  }
+
+  private StateCache<ValidityState> getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
+    return CompilerCacheManager.getInstance(myProject).getGeneratingCompilerCache(compiler);
+  }
+
+  public void executeCompileTask(final CompileTask task, final CompileScope scope, final String contentName, final Runnable onTaskFinished) {
+    final CompilerTask progressManagerTask =
+      new CompilerTask(myProject, contentName, false, false);
+    final CompileContextImpl compileContext = new CompileContextImpl(myProject, progressManagerTask, scope, null, false, false);
+
+    FileDocumentManager.getInstance().saveAllDocuments();
+
+    progressManagerTask.start(new Runnable() {
+      public void run() {
+        try {
+          task.execute(compileContext);
+        }
+        catch (ProcessCanceledException ex) {
+          // suppressed
+        }
+        finally {
+          if (onTaskFinished != null) {
+            onTaskFinished.run();
+          }
+        }
+      }
+    }, null);
+  }
+
+  private boolean executeCompileTasks(final CompileContext context, final boolean beforeTasks) {
+    final CompilerManager manager = CompilerManager.getInstance(myProject);
+    final ProgressIndicator progressIndicator = context.getProgressIndicator();
+    progressIndicator.pushState();
+    try {
+      CompileTask[] tasks = beforeTasks ? manager.getBeforeTasks() : manager.getAfterTasks();
+      if (tasks.length > 0) {
+        progressIndicator.setText(beforeTasks
+                                  ? CompilerBundle.message("progress.executing.precompile.tasks")
+                                  : CompilerBundle.message("progress.executing.postcompile.tasks"));
+        for (CompileTask task : tasks) {
+          if (!task.execute(context)) {
+            return false;
+          }
+        }
+      }
+    }
+    finally {
+      progressIndicator.popState();
+      WindowManager.getInstance().getStatusBar(myProject).setInfo("");
+      if (progressIndicator instanceof CompilerTask) {
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+          public void run() {
+            ((CompilerTask)progressIndicator).showCompilerContent();
+          }
+        });
+      }
+    }
+    return true;
+  }
+
+  private boolean validateCompilerConfiguration(final CompileScope scope, boolean checkOutputAndSourceIntersection) {
+    try {
+      final Module[] scopeModules = scope.getAffectedModules()/*ModuleManager.getInstance(myProject).getModules()*/;
+      final List<String> modulesWithoutOutputPathSpecified = new ArrayList<String>();
+      boolean isProjectCompilePathSpecified = true;
+      final List<String> modulesWithoutJdkAssigned = new ArrayList<String>();
+      final Set<File> nonExistingOutputPaths = new HashSet<File>();
+      final CompilerConfiguration config = CompilerConfiguration.getInstance(myProject);
+      final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+      final boolean useOutOfProcessBuild = useOutOfProcessBuild();
+      for (final Module module : scopeModules) {
+        if (!compilerManager.isValidationEnabled(module)) {
+          continue;
+        }
+        final boolean hasSources = hasSources(module, false);
+        final boolean hasTestSources = hasSources(module, true);
+        if (!hasSources && !hasTestSources) {
+          // If module contains no sources, shouldn't have to select JDK or output directory (SCR #19333)
+          // todo still there may be problems with this approach if some generated files are attributed by this module
+          continue;
+        }
+        final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+        if (jdk == null) {
+          modulesWithoutJdkAssigned.add(module.getName());
+        }
+        final String outputPath = getModuleOutputPath(module, false);
+        final String testsOutputPath = getModuleOutputPath(module, true);
+        if (outputPath == null && testsOutputPath == null) {
+          modulesWithoutOutputPathSpecified.add(module.getName());
+        }
+        else {
+          if (outputPath != null) {
+            if (!useOutOfProcessBuild) {
+              final File file = new File(outputPath.replace('/', File.separatorChar));
+              if (!file.exists()) {
+                nonExistingOutputPaths.add(file);
+              }
+            }
+          }
+          else {
+            if (hasSources) {
+              modulesWithoutOutputPathSpecified.add(module.getName());
+            }
+          }
+          if (testsOutputPath != null) {
+            if (!useOutOfProcessBuild) {
+              final File f = new File(testsOutputPath.replace('/', File.separatorChar));
+              if (!f.exists()) {
+                nonExistingOutputPaths.add(f);
+              }
+            }
+          }
+          else {
+            if (hasTestSources) {
+              modulesWithoutOutputPathSpecified.add(module.getName());
+            }
+          }
+          if (!useOutOfProcessBuild) {
+            if (config.getAnnotationProcessingConfiguration(module).isEnabled()) {
+              final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+              if (path == null) {
+                final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(module.getProject());
+                if (extension == null || extension.getCompilerOutputUrl() == null) {
+                  isProjectCompilePathSpecified = false;
+                }
+                else {
+                  modulesWithoutOutputPathSpecified.add(module.getName());
+                }
+              }
+              else {
+                final File file = new File(path);
+                if (!file.exists()) {
+                  nonExistingOutputPaths.add(file);
+                }
+              }
+            }
+          }
+        }
+      }
+      if (!modulesWithoutJdkAssigned.isEmpty()) {
+        showNotSpecifiedError("error.jdk.not.specified", modulesWithoutJdkAssigned, ProjectBundle.message("modules.classpath.title"));
+        return false;
+      }
+
+      if (!isProjectCompilePathSpecified) {
+        final String message = CompilerBundle.message("error.project.output.not.specified");
+        if (ApplicationManager.getApplication().isUnitTestMode()) {
+          LOG.error(message);
+        }
+  
+        Messages.showMessageDialog(myProject, message, CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+        ProjectSettingsService.getInstance(myProject).openProjectSettings();
+        return false;
+      }
+
+      if (!modulesWithoutOutputPathSpecified.isEmpty()) {
+        showNotSpecifiedError("error.output.not.specified", modulesWithoutOutputPathSpecified, CommonContentEntriesEditor.NAME);
+        return false;
+      }
+
+      if (!nonExistingOutputPaths.isEmpty()) {
+        for (File file : nonExistingOutputPaths) {
+          final boolean succeeded = file.mkdirs();
+          if (!succeeded) {
+            if (file.exists()) {
+              // for overlapping paths, this one might have been created as an intermediate path on a previous iteration
+              continue;
+            }
+            Messages.showMessageDialog(myProject, CompilerBundle.message("error.failed.to.create.directory", file.getPath()),
+                                       CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+            return false;
+          }
+        }
+        final Boolean refreshSuccess =
+          new WriteAction<Boolean>() {
+            @Override
+            protected void run(Result<Boolean> result) throws Throwable {
+              LocalFileSystem.getInstance().refreshIoFiles(nonExistingOutputPaths);
+              Boolean res = Boolean.TRUE;
+              for (File file : nonExistingOutputPaths) {
+                if (LocalFileSystem.getInstance().findFileByIoFile(file) == null) {
+                  res = Boolean.FALSE;
+                  break;
+                }
+              }
+              result.setResult(res);
+            }
+          }.execute().getResultObject();
+  
+        if (!refreshSuccess.booleanValue()) {
+          return false;
+        }
+        dropScopesCaches();
+      }
+
+      if (checkOutputAndSourceIntersection && myShouldClearOutputDirectory) {
+        if (!validateOutputAndSourcePathsIntersection()) {
+          return false;
+        }
+        // myShouldClearOutputDirectory may change in validateOutputAndSourcePathsIntersection()
+        CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, myShouldClearOutputDirectory);
+      }
+      else {
+        CompilerPathsEx.CLEAR_ALL_OUTPUTS_KEY.set(scope, false);
+      }
+      final List<Chunk<Module>> chunks = ModuleCompilerUtil.getSortedModuleChunks(myProject, Arrays.asList(scopeModules));
+      for (final Chunk<Module> chunk : chunks) {
+        final Set<Module> chunkModules = chunk.getNodes();
+        if (chunkModules.size() <= 1) {
+          continue; // no need to check one-module chunks
+        }
+        for (Module chunkModule : chunkModules) {
+          if (config.getAnnotationProcessingConfiguration(chunkModule).isEnabled()) {
+            showCyclesNotSupportedForAnnotationProcessors(chunkModules.toArray(new Module[chunkModules.size()]));
+            return false;
+          }
+        }
+        Sdk jdk = null;
+        LanguageLevel languageLevel = null;
+        for (final Module module : chunkModules) {
+          final Sdk moduleJdk = ModuleRootManager.getInstance(module).getSdk();
+          if (jdk == null) {
+            jdk = moduleJdk;
+          }
+          else {
+            if (!jdk.equals(moduleJdk)) {
+              showCyclicModulesHaveDifferentJdksError(chunkModules.toArray(new Module[chunkModules.size()]));
+              return false;
+            }
+          }
+  
+          LanguageLevel moduleLanguageLevel = LanguageLevelUtil.getEffectiveLanguageLevel(module);
+          if (languageLevel == null) {
+            languageLevel = moduleLanguageLevel;
+          }
+          else {
+            if (!languageLevel.equals(moduleLanguageLevel)) {
+              showCyclicModulesHaveDifferentLanguageLevel(chunkModules.toArray(new Module[chunkModules.size()]));
+              return false;
+            }
+          }
+        }
+      }
+      if (!useOutOfProcessBuild) {
+        final Compiler[] allCompilers = compilerManager.getCompilers(Compiler.class);
+        for (Compiler compiler : allCompilers) {
+          if (!compiler.validateConfiguration(scope)) {
+            return false;
+          }
+        }
+      }
+      return true;
+    }
+    catch (Throwable e) {
+      LOG.info(e);
+      return false;
+    }
+  }
+
+  private boolean useOutOfProcessBuild() {
+    return CompilerWorkspaceConfiguration.getInstance(myProject).useOutOfProcessBuild();
+  }
+
+  private void showCyclicModulesHaveDifferentLanguageLevel(Module[] modulesInChunk) {
+    LOG.assertTrue(modulesInChunk.length > 0);
+    String moduleNameToSelect = modulesInChunk[0].getName();
+    final String moduleNames = getModulesString(modulesInChunk);
+    Messages.showMessageDialog(myProject, CompilerBundle.message("error.chunk.modules.must.have.same.language.level", moduleNames),
+                               CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+    showConfigurationDialog(moduleNameToSelect, null);
+  }
+
+  private void showCyclicModulesHaveDifferentJdksError(Module[] modulesInChunk) {
+    LOG.assertTrue(modulesInChunk.length > 0);
+    String moduleNameToSelect = modulesInChunk[0].getName();
+    final String moduleNames = getModulesString(modulesInChunk);
+    Messages.showMessageDialog(myProject, CompilerBundle.message("error.chunk.modules.must.have.same.jdk", moduleNames),
+                               CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+    showConfigurationDialog(moduleNameToSelect, null);
+  }
+
+  private void showCyclesNotSupportedForAnnotationProcessors(Module[] modulesInChunk) {
+    LOG.assertTrue(modulesInChunk.length > 0);
+    String moduleNameToSelect = modulesInChunk[0].getName();
+    final String moduleNames = getModulesString(modulesInChunk);
+    Messages.showMessageDialog(myProject, CompilerBundle.message("error.annotation.processing.not.supported.for.module.cycles", moduleNames),
+                               CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+    showConfigurationDialog(moduleNameToSelect, null);
+  }
+
+  private static String getModulesString(Module[] modulesInChunk) {
+    final StringBuilder moduleNames = StringBuilderSpinAllocator.alloc();
+    try {
+      for (Module module : modulesInChunk) {
+        if (moduleNames.length() > 0) {
+          moduleNames.append("\n");
+        }
+        moduleNames.append("\"").append(module.getName()).append("\"");
+      }
+      return moduleNames.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(moduleNames);
+    }
+  }
+
+  private static boolean hasSources(Module module, boolean checkTestSources) {
+    final ContentEntry[] contentEntries = ModuleRootManager.getInstance(module).getContentEntries();
+    for (final ContentEntry contentEntry : contentEntries) {
+      final SourceFolder[] sourceFolders = contentEntry.getSourceFolders();
+      for (final SourceFolder sourceFolder : sourceFolders) {
+        if (sourceFolder.getFile() == null) {
+          continue; // skip invalid source folders
+        }
+        if (checkTestSources) {
+          if (sourceFolder.isTestSource()) {
+            return true;
+          }
+        }
+        else {
+          if (!sourceFolder.isTestSource()) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private void showNotSpecifiedError(@NonNls final String resourceId, List<String> modules, String editorNameToSelect) {
+    String nameToSelect = null;
+    final StringBuilder names = StringBuilderSpinAllocator.alloc();
+    final String message;
+    try {
+      final int maxModulesToShow = 10;
+      for (String name : modules.size() > maxModulesToShow ? modules.subList(0, maxModulesToShow) : modules) {
+        if (nameToSelect == null) {
+          nameToSelect = name;
+        }
+        if (names.length() > 0) {
+          names.append(",\n");
+        }
+        names.append("\"");
+        names.append(name);
+        names.append("\"");
+      }
+      if (modules.size() > maxModulesToShow) {
+        names.append(",\n...");
+      }
+      message = CompilerBundle.message(resourceId, modules.size(), names.toString());
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(names);
+    }
+
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      LOG.error(message);
+    }
+
+    Messages.showMessageDialog(myProject, message, CommonBundle.getErrorTitle(), Messages.getErrorIcon());
+    showConfigurationDialog(nameToSelect, editorNameToSelect);
+  }
+
+  private boolean validateOutputAndSourcePathsIntersection() {
+    final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
+    List<VirtualFile> allOutputs = new ArrayList<VirtualFile>();
+    ContainerUtil.addAll(allOutputs, CompilerPathsEx.getOutputDirectories(allModules));
+    for (Artifact artifact : ArtifactManager.getInstance(myProject).getArtifacts()) {
+      ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs);
+    }
+    final Set<VirtualFile> affectedOutputPaths = new HashSet<VirtualFile>();
+    CompilerUtil.computeIntersectingPaths(myProject, allOutputs, affectedOutputPaths);
+    affectedOutputPaths.addAll(ArtifactCompilerUtil.getArtifactOutputsContainingSourceFiles(myProject));
+
+    if (!affectedOutputPaths.isEmpty()) {
+      if (CompilerUtil.askUserToContinueWithNoClearing(myProject, affectedOutputPaths)) {
+        myShouldClearOutputDirectory = false;
+        return true;
+      }
+      else {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private void showConfigurationDialog(String moduleNameToSelect, String tabNameToSelect) {
+    ProjectSettingsService.getInstance(myProject).showModuleConfigurationDialog(moduleNameToSelect, tabNameToSelect);
+  }
+
+  private static VirtualFile lookupVFile(final LocalFileSystem lfs, final String path) {
+    final File file = new File(path);
+
+    VirtualFile vFile = lfs.findFileByIoFile(file);
+    if (vFile != null) {
+      return vFile;
+    }
+
+    final boolean justCreated = file.mkdirs();
+    vFile = lfs.refreshAndFindFileByIoFile(file);
+
+    if (vFile == null) {
+      assert false: "Virtual file not found for " + file.getPath() + "; mkdirs() exit code is " + justCreated + "; file exists()? " + file.exists();
+    }
+
+    return vFile;
+  }
+
+  private static class CacheDeferredUpdater {
+    private final Map<VirtualFile, List<Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>>> myData = new java.util.HashMap<VirtualFile, List<Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>>>();
+
+    public void addFileForUpdate(final FileProcessingCompiler.ProcessingItem item, FileProcessingCompilerStateCache cache) {
+      final VirtualFile file = item.getFile();
+      List<Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>> list = myData.get(file);
+      if (list == null) {
+        list = new ArrayList<Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>>();
+        myData.put(file, list);
+      }
+      list.add(new Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>(cache, item));
+    }
+
+    public void doUpdate() throws IOException{
+      final IOException[] ex = {null};
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          try {
+            for (Map.Entry<VirtualFile, List<Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem>>> entry : myData.entrySet()) {
+              for (Pair<FileProcessingCompilerStateCache, FileProcessingCompiler.ProcessingItem> pair : entry.getValue()) {
+                final FileProcessingCompiler.ProcessingItem item = pair.getSecond();
+                pair.getFirst().update(entry.getKey(), item.getValidityState());
+              }
+            }
+          }
+          catch (IOException e) {
+            ex[0] = e;
+          }
+        }
+      });
+      if (ex[0] != null) {
+        throw ex[0];
+      }
+    }
+  }
+
+  private static class TranslatorsOutputSink implements TranslatingCompiler.OutputSink {
+    final Map<String, Collection<TranslatingCompiler.OutputItem>> myPostponedItems = new HashMap<String, Collection<TranslatingCompiler.OutputItem>>();
+    private final CompileContextEx myContext;
+    private final TranslatingCompiler[] myCompilers;
+    private int myCurrentCompilerIdx;
+    private final Set<VirtualFile> myCompiledSources = new HashSet<VirtualFile>();
+    //private LinkedBlockingQueue<Future> myFutures = new LinkedBlockingQueue<Future>();
+
+    private TranslatorsOutputSink(CompileContextEx context, TranslatingCompiler[] compilers) {
+      myContext = context;
+      myCompilers = compilers;
+    }
+
+    public void setCurrentCompilerIndex(int index) {
+      myCurrentCompilerIdx = index;
+    }
+
+    public Set<VirtualFile> getCompiledSources() {
+      return Collections.unmodifiableSet(myCompiledSources);
+    }
+
+    public void add(final String outputRoot, final Collection<TranslatingCompiler.OutputItem> items, final VirtualFile[] filesToRecompile) {
+      for (TranslatingCompiler.OutputItem item : items) {
+        final VirtualFile file = item.getSourceFile();
+        if (file != null) {
+          myCompiledSources.add(file);
+        }
+      }
+      final TranslatingCompiler compiler = myCompilers[myCurrentCompilerIdx];
+      if (compiler instanceof IntermediateOutputCompiler) {
+        final LocalFileSystem lfs = LocalFileSystem.getInstance();
+        final List<VirtualFile> outputs = new ArrayList<VirtualFile>();
+        for (TranslatingCompiler.OutputItem item : items) {
+          final VirtualFile vFile = lfs.findFileByPath(item.getOutputPath());
+          if (vFile != null) {
+            outputs.add(vFile);
+          }
+        }
+        myContext.markGenerated(outputs);
+      }
+      final int nextCompilerIdx = myCurrentCompilerIdx + 1;
+      try {
+        if (nextCompilerIdx < myCompilers.length ) {
+          final Map<String, Collection<TranslatingCompiler.OutputItem>> updateNow = new java.util.HashMap<String, Collection<TranslatingCompiler.OutputItem>>();
+          // process postponed
+          for (Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry : myPostponedItems.entrySet()) {
+            final String outputDir = entry.getKey();
+            final Collection<TranslatingCompiler.OutputItem> postponed = entry.getValue();
+            for (Iterator<TranslatingCompiler.OutputItem> it = postponed.iterator(); it.hasNext();) {
+              TranslatingCompiler.OutputItem item = it.next();
+              boolean shouldPostpone = false;
+              for (int idx = nextCompilerIdx; idx < myCompilers.length; idx++) {
+                shouldPostpone = myCompilers[idx].isCompilableFile(item.getSourceFile(), myContext);
+                if (shouldPostpone) {
+                  break;
+                }
+              }
+              if (!shouldPostpone) {
+                // the file is not compilable by the rest of compilers, so it is safe to update it now
+                it.remove();
+                addItemToMap(updateNow, outputDir, item);
+              }
+            }
+          }
+          // process items from current compilation
+          for (TranslatingCompiler.OutputItem item : items) {
+            boolean shouldPostpone = false;
+            for (int idx = nextCompilerIdx; idx < myCompilers.length; idx++) {
+              shouldPostpone = myCompilers[idx].isCompilableFile(item.getSourceFile(), myContext);
+              if (shouldPostpone) {
+                break;
+              }
+            }
+            if (shouldPostpone) {
+              // the file is compilable by the next compiler in row, update should be postponed
+              addItemToMap(myPostponedItems, outputRoot, item);
+            }
+            else {
+              addItemToMap(updateNow, outputRoot, item);
+            }
+          }
+
+          if (updateNow.size() == 1) {
+            final Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry = updateNow.entrySet().iterator().next();
+            final String outputDir = entry.getKey();
+            final Collection<TranslatingCompiler.OutputItem> itemsToUpdate = entry.getValue();
+            TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputDir, itemsToUpdate, filesToRecompile);
+          }
+          else {
+            for (Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry : updateNow.entrySet()) {
+              final String outputDir = entry.getKey();
+              final Collection<TranslatingCompiler.OutputItem> itemsToUpdate = entry.getValue();
+              TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputDir, itemsToUpdate, VirtualFile.EMPTY_ARRAY);
+            }
+            if (filesToRecompile.length > 0) {
+              TranslatingCompilerFilesMonitor.getInstance().update(myContext, null, Collections.<TranslatingCompiler.OutputItem>emptyList(), filesToRecompile);
+            }
+          }
+        }
+        else {
+          TranslatingCompilerFilesMonitor.getInstance().update(myContext, outputRoot, items, filesToRecompile);
+        }
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        myContext.requestRebuildNextTime(e.getMessage());
+      }
+    }
+
+    private static void addItemToMap(Map<String, Collection<TranslatingCompiler.OutputItem>> map, String outputDir, TranslatingCompiler.OutputItem item) {
+      Collection<TranslatingCompiler.OutputItem> collection = map.get(outputDir);
+      if (collection == null) {
+        collection = new ArrayList<TranslatingCompiler.OutputItem>();
+        map.put(outputDir, collection);
+      }
+      collection.add(item);
+    }
+
+    public void flushPostponedItems() {
+      final TranslatingCompilerFilesMonitor filesMonitor = TranslatingCompilerFilesMonitor.getInstance();
+      try {
+        for (Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry : myPostponedItems.entrySet()) {
+          final String outputDir = entry.getKey();
+          final Collection<TranslatingCompiler.OutputItem> items = entry.getValue();
+          filesMonitor.update(myContext, outputDir, items, VirtualFile.EMPTY_ARRAY);
+        }
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        myContext.requestRebuildNextTime(e.getMessage());
+      }
+    }
+  }
+
+  private static class DependentClassesCumulativeFilter implements Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> {
+
+    private final TIntHashSet myProcessedNames = new TIntHashSet();
+    private final Set<VirtualFile> myProcessedFiles = new HashSet<VirtualFile>();
+
+    public Pair<int[], Set<VirtualFile>> fun(Pair<int[], Set<VirtualFile>> deps) {
+      final TIntHashSet currentDeps = new TIntHashSet(deps.getFirst());
+      currentDeps.removeAll(myProcessedNames.toArray());
+      myProcessedNames.addAll(deps.getFirst());
+
+      final Set<VirtualFile> depFiles = new HashSet<VirtualFile>(deps.getSecond());
+      depFiles.removeAll(myProcessedFiles);
+      myProcessedFiles.addAll(deps.getSecond());
+      return new Pair<int[], Set<VirtualFile>>(currentDeps.toArray(), depFiles);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java
new file mode 100644
index 0000000..102db7a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileScopeUtil.java
@@ -0,0 +1,106 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+import org.jetbrains.jps.builders.java.JavaModuleBuildTargetType;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class CompileScopeUtil {
+  public static void addScopesForModules(Collection<Module> modules, List<TargetTypeBuildScope> scopes) {
+    if (!modules.isEmpty()) {
+      for (JavaModuleBuildTargetType type : JavaModuleBuildTargetType.ALL_TYPES) {
+        TargetTypeBuildScope.Builder builder = TargetTypeBuildScope.newBuilder().setTypeId(type.getTypeId());
+        for (Module module : modules) {
+          builder.addTargetId(module.getName());
+        }
+        scopes.add(builder.build());
+      }
+    }
+  }
+
+  public static List<TargetTypeBuildScope> mergeScopes(List<TargetTypeBuildScope> scopes1, List<TargetTypeBuildScope> scopes2) {
+    if (scopes2.isEmpty()) return scopes1;
+    if (scopes1.isEmpty()) return scopes2;
+
+    Map<String, TargetTypeBuildScope> scopeById = new HashMap<String, TargetTypeBuildScope>();
+    mergeScopes(scopeById, scopes1);
+    mergeScopes(scopeById, scopes2);
+    return new ArrayList<TargetTypeBuildScope>(scopeById.values());
+  }
+
+  private static void mergeScopes(Map<String, TargetTypeBuildScope> scopeById, List<TargetTypeBuildScope> scopes) {
+    for (TargetTypeBuildScope scope : scopes) {
+      String id = scope.getTypeId();
+      TargetTypeBuildScope old = scopeById.get(id);
+      if (old == null) {
+        scopeById.put(id, scope);
+      }
+      else {
+        scopeById.put(id, mergeScope(old, scope));
+      }
+    }
+  }
+
+  private static TargetTypeBuildScope mergeScope(TargetTypeBuildScope scope1, TargetTypeBuildScope scope2) {
+    if (scope1.getAllTargets()) return scope1;
+    if (scope2.getAllTargets()) return scope2;
+    return TargetTypeBuildScope.newBuilder()
+      .setTypeId(scope1.getTypeId())
+      .addAllTargetId(scope1.getTargetIdList())
+      .addAllTargetId(scope2.getTargetIdList())
+      .build();
+  }
+
+  public static boolean allProjectModulesAffected(CompileContextImpl compileContext) {
+    final Set<Module> allModules = new HashSet<Module>(Arrays.asList(compileContext.getProjectCompileScope().getAffectedModules()));
+    allModules.removeAll(Arrays.asList(compileContext.getCompileScope().getAffectedModules()));
+    return allModules.isEmpty();
+  }
+
+  public static List<String> fetchFiles(CompileContextImpl context) {
+    if (context.isRebuild()) {
+      return Collections.emptyList();
+    }
+    final CompileScope scope = context.getCompileScope();
+    if (shouldFetchFiles(scope)) {
+      final List<String> paths = new ArrayList<String>();
+      for (VirtualFile file : scope.getFiles(null, true)) {
+        paths.add(file.getPath());
+      }
+      return paths;
+    }
+    return Collections.emptyList();
+  }
+
+  private static boolean shouldFetchFiles(CompileScope scope) {
+    if (scope instanceof CompositeScope) {
+      for (CompileScope compileScope : ((CompositeScope)scope).getScopes()) {
+        if (shouldFetchFiles(compileScope)) {
+          return true;
+        }
+      }
+    }
+    return scope instanceof OneProjectItemCompileScope || scope instanceof FileSetCompileScope;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java
new file mode 100644
index 0000000..5c147ee
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerCacheManager.java
@@ -0,0 +1,187 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.impl.generic.GenericCompilerCache;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.compiler.generic.GenericCompiler;
+import com.intellij.openapi.components.ProjectComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: May 4, 2008
+ */
+public class CompilerCacheManager implements ProjectComponent {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerCacheManager");
+  private final Map<Compiler, Object> myCompilerToCacheMap = new HashMap<Compiler, Object>();
+  private final Map<GenericCompiler<?,?,?>, GenericCompilerCache<?,?,?>> myGenericCachesMap = new HashMap<GenericCompiler<?,?,?>, GenericCompilerCache<?,?,?>>();
+  private final List<Disposable> myCacheDisposables = new ArrayList<Disposable>();
+  private final File myCachesRoot;
+  private final Project myProject;
+
+  public CompilerCacheManager(Project project) {
+    myProject = project;
+    myCachesRoot = CompilerPaths.getCacheStoreDirectory(project);
+  }
+
+  public static CompilerCacheManager getInstance(Project project) {
+    return project.getComponent(CompilerCacheManager.class);
+  }
+  
+  public void projectOpened() {
+  }
+
+  public void projectClosed() {
+  }
+
+  @NotNull
+  public String getComponentName() {
+    return "CompilerCacheManager";
+  }
+
+  public void initComponent() {
+  }
+
+  public void disposeComponent() {
+    flushCaches();
+  }
+  
+  private File getCompilerRootDir(final Compiler compiler) {
+    final File dir = new File(myCachesRoot, getCompilerIdString(compiler));
+    dir.mkdirs();
+    return dir;
+  }
+
+  public synchronized <Key, SourceState, OutputState> GenericCompilerCache<Key, SourceState, OutputState>
+                                 getGenericCompilerCache(final GenericCompiler<Key, SourceState, OutputState> compiler) throws IOException {
+    GenericCompilerCache<?,?,?> cache = myGenericCachesMap.get(compiler);
+    if (cache == null) {
+      final GenericCompilerCache<?,?,?> genericCache = new GenericCompilerCache<Key, SourceState, OutputState>(compiler, GenericCompilerRunner
+        .getGenericCompilerCacheDir(myProject, compiler));
+      myGenericCachesMap.put(compiler, genericCache);
+      myCacheDisposables.add(new Disposable() {
+        public void dispose() {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Closing cache for feneric compiler " + compiler.getId());
+          }
+          genericCache.close();
+        }
+      });
+      cache = genericCache;
+    }
+    //noinspection unchecked
+    return (GenericCompilerCache<Key, SourceState, OutputState>)cache;
+  }
+
+  public synchronized FileProcessingCompilerStateCache getFileProcessingCompilerCache(final FileProcessingCompiler compiler) throws IOException {
+    Object cache = myCompilerToCacheMap.get(compiler);
+    if (cache == null) {
+      final File compilerRootDir = getCompilerRootDir(compiler);
+      final FileProcessingCompilerStateCache stateCache = new FileProcessingCompilerStateCache(compilerRootDir, compiler);
+      myCompilerToCacheMap.put(compiler, stateCache);
+      myCacheDisposables.add(new Disposable() {
+        public void dispose() {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Closing cache for compiler " + compiler.getDescription() + "; cache root dir: " + compilerRootDir);
+          }
+          stateCache.close();
+        }
+      });
+      cache = stateCache;
+    }
+    else {
+      LOG.assertTrue(cache instanceof FileProcessingCompilerStateCache);
+    }
+    return (FileProcessingCompilerStateCache)cache;
+  }
+
+  public synchronized StateCache<ValidityState> getGeneratingCompilerCache(final GeneratingCompiler compiler) throws IOException {
+    Object cache = myCompilerToCacheMap.get(compiler);
+    if (cache == null) {
+      final File cacheDir = getCompilerRootDir(compiler);
+      final StateCache<ValidityState> stateCache = new StateCache<ValidityState>(new File(cacheDir, "timestamps")) {
+        public ValidityState read(DataInput stream) throws IOException {
+          return compiler.createValidityState(stream);
+        }
+  
+        public void write(ValidityState validityState, DataOutput out) throws IOException {
+          validityState.save(out);
+        }
+      };
+      myCompilerToCacheMap.put(compiler, stateCache);
+      myCacheDisposables.add(new Disposable() {
+        public void dispose() {
+          try {
+            stateCache.close();
+          }
+          catch (IOException e) {
+            LOG.info(e);
+          }
+        }
+      });
+      cache = stateCache;
+    }
+    return (StateCache<ValidityState>)cache;
+  }
+
+  public static String getCompilerIdString(Compiler compiler) {
+    @NonNls String description = compiler.getDescription();
+    return description.replaceAll("\\s+", "_").replaceAll("[\\.\\?]", "_").toLowerCase();
+  }
+  
+  public synchronized void flushCaches() {
+    for (Disposable disposable : myCacheDisposables) {
+      try {
+        disposable.dispose();
+      }
+      catch (Throwable e) {
+        LOG.info(e);
+      }
+    }
+    myCacheDisposables.clear();
+    myGenericCachesMap.clear();
+    myCompilerToCacheMap.clear();
+  }
+
+  public void clearCaches(final CompileContext context) {
+    flushCaches();
+    final File[] children = myCachesRoot.listFiles();
+    if (children != null) {
+      for (final File child : children) {
+        final boolean deleteOk = FileUtil.delete(child);
+        if (!deleteOk) {
+          context.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.failed.to.delete", child.getPath()), null, -1, -1);
+        }
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerContentIterator.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerContentIterator.java
new file mode 100644
index 0000000..c763480
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerContentIterator.java
@@ -0,0 +1,49 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.roots.ContentIterator;
+import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.util.Collection;
+
+public class CompilerContentIterator implements ContentIterator {
+  final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+  private final FileType myFileType;
+  private final FileIndex myFileIndex;
+  private final boolean myInSourceOnly;
+  private final Collection<VirtualFile> myFiles;
+
+  public CompilerContentIterator(FileType fileType, FileIndex fileIndex, boolean inSourceOnly, Collection<VirtualFile> files) {
+    myFileType = fileType;
+    myFileIndex = fileIndex;
+    myInSourceOnly = inSourceOnly;
+    myFiles = files;
+  }
+
+  public boolean processFile(VirtualFile fileOrDir) {
+    if (fileOrDir.isDirectory()) return true;
+    if (!fileOrDir.isInLocalFileSystem()) return true;
+    if (myInSourceOnly && !myFileIndex.isInSourceContent(fileOrDir)) return true;
+    if (myFileType == null || myFileType == fileOrDir.getFileType()) {
+      myFiles.add(fileOrDir);
+    }
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java
new file mode 100644
index 0000000..d50063d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerEncodingServiceImpl.java
@@ -0,0 +1,134 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.CompilerEncodingService;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.encoding.EncodingProjectManager;
+import com.intellij.openapi.vfs.encoding.EncodingProjectManagerImpl;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.nio.charset.Charset;
+import java.util.Collection;
+import java.util.LinkedHashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class CompilerEncodingServiceImpl extends CompilerEncodingService {
+  @NotNull private final Project myProject;
+  private final CachedValue<Map<Module, Set<Charset>>> myModuleFileEncodings;
+
+  public CompilerEncodingServiceImpl(@NotNull Project project) {
+    myProject = project;
+    myModuleFileEncodings = CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<Map<Module, Set<Charset>>>() {
+      @Override
+      public Result<Map<Module, Set<Charset>>> compute() {
+        Map<Module, Set<Charset>> result = computeModuleCharsetMap();
+        return Result.create(result, ProjectRootManager.getInstance(myProject),
+                             ((EncodingProjectManagerImpl)EncodingProjectManager.getInstance(myProject)).getModificationTracker());
+      }
+    }, false);
+  }
+
+  private Map<Module, Set<Charset>> computeModuleCharsetMap() {
+    final Map<Module, Set<Charset>> map = new THashMap<Module, Set<Charset>>();
+    final Map<VirtualFile, Charset> mappings = EncodingProjectManager.getInstance(myProject).getAllMappings();
+    ProjectFileIndex index = ProjectRootManager.getInstance(myProject).getFileIndex();
+    final CompilerManager compilerManager = CompilerManager.getInstance(myProject);
+    for (Map.Entry<VirtualFile, Charset> entry : mappings.entrySet()) {
+      final VirtualFile file = entry.getKey();
+      final Charset charset = entry.getValue();
+      if (file == null || charset == null || (!file.isDirectory() && !compilerManager.isCompilableFileType(file.getFileType()))
+          || !index.isInSourceContent(file)) continue;
+
+      final Module module = index.getModuleForFile(file);
+      if (module == null) continue;
+
+      Set<Charset> set = map.get(module);
+      if (set == null) {
+        set = new LinkedHashSet<Charset>();
+        map.put(module, set);
+
+        final VirtualFile sourceRoot = index.getSourceRootForFile(file);
+        VirtualFile current = file.getParent();
+        Charset parentCharset = null;
+        while (current != null) {
+          final Charset currentCharset = mappings.get(current);
+          if (currentCharset != null) {
+            parentCharset = currentCharset;
+          }
+          if (current.equals(sourceRoot)) {
+            break;
+          }
+          current = current.getParent();
+        }
+        if (parentCharset != null) {
+          set.add(parentCharset);
+        }
+      }
+      set.add(charset);
+    }
+    //todo[nik,jeka] perhaps we should take into account encodings of source roots only not individual files
+    for (Module module : ModuleManager.getInstance(myProject).getModules()) {
+      for (VirtualFile file : ModuleRootManager.getInstance(module).getSourceRoots(true)) {
+        Charset encoding = EncodingProjectManager.getInstance(myProject).getEncoding(file, true);
+        if (encoding != null) {
+          Set<Charset> charsets = map.get(module);
+          if (charsets == null) {
+            charsets = new LinkedHashSet<Charset>();
+            map.put(module, charsets);
+          }
+          charsets.add(encoding);
+        }
+      }
+    }
+    
+    return map;
+  }
+
+  @Override
+  @Nullable
+  public Charset getPreferredModuleEncoding(@NotNull Module module) {
+    final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
+    return ContainerUtil.getFirstItem(encodings, EncodingProjectManager.getInstance(myProject).getDefaultCharset());
+  }
+
+  @NotNull
+  @Override
+  public Collection<Charset> getAllModuleEncodings(@NotNull Module module) {
+    final Set<Charset> encodings = myModuleFileEncodings.getValue().get(module);
+    if (encodings != null) {
+      return encodings;
+    }
+    return ContainerUtil.createMaybeSingletonList(EncodingProjectManager.getInstance(myProject).getDefaultCharset());
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerErrorTreeView.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerErrorTreeView.java
new file mode 100644
index 0000000..d9fea53
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerErrorTreeView.java
@@ -0,0 +1,182 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.codeInsight.daemon.impl.actions.SuppressFix;
+import com.intellij.codeInsight.daemon.impl.actions.SuppressForClassFix;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.HelpID;
+import com.intellij.ide.errorTreeView.ErrorTreeElement;
+import com.intellij.ide.errorTreeView.NavigatableMessageElement;
+import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.module.LanguageLevelUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtilCore;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+public class CompilerErrorTreeView extends NewErrorTreeViewPanel {
+  public CompilerErrorTreeView(Project project, Runnable rerunAction) {
+    super(project, HelpID.COMPILER, true, true, rerunAction);
+  }
+
+  protected void fillRightToolbarGroup(DefaultActionGroup group) {
+    super.fillRightToolbarGroup(group);
+    group.add(new CompilerPropertiesAction());
+  }
+
+  protected void addExtraPopupMenuActions(DefaultActionGroup group) {
+    group.add(new ExcludeFromCompileAction(myProject, this));
+    group.addSeparator();
+    group.add(new SuppressJavacWarningsAction());
+    group.add(new SuppressJavacWarningForClassAction());
+    group.addSeparator();
+    ActionGroup popupGroup = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_COMPILER_ERROR_VIEW_POPUP);
+    if (popupGroup != null) {
+      for (AnAction action : popupGroup.getChildren(null)) {
+        group.add(action);
+      }
+    }
+  }
+
+  protected boolean shouldShowFirstErrorInEditor() {
+    return CompilerWorkspaceConfiguration.getInstance(myProject).AUTO_SHOW_ERRORS_IN_EDITOR;
+  }
+
+  private class SuppressJavacWarningsAction extends AnAction {
+    public void actionPerformed(final AnActionEvent e) {
+      final NavigatableMessageElement messageElement = (NavigatableMessageElement)getSelectedErrorTreeElement();
+      final String[] text = messageElement.getText();
+      final String id = text[0].substring(1, text[0].indexOf("]"));
+      final SuppressFix suppressInspectionFix = getSuppressAction(id);
+      final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
+      assert project != null;
+      final OpenFileDescriptor navigatable = (OpenFileDescriptor)messageElement.getNavigatable();
+      final PsiFile file = PsiManager.getInstance(project).findFile(navigatable.getFile());
+      assert file != null;
+      CommandProcessor.getInstance().executeCommand(project, new Runnable() {
+        public void run() {
+          ApplicationManager.getApplication().runWriteAction(new Runnable() {
+            public void run() {
+              try {
+                suppressInspectionFix.invoke(project, null, file.findElementAt(navigatable.getOffset()));
+              }
+              catch (IncorrectOperationException e1) {
+                LOG.error(e1);
+              }
+            }
+          });
+        }
+      }, suppressInspectionFix.getText(), null);
+    }
+
+    @Override
+    public void update(final AnActionEvent e) {
+      final Presentation presentation = e.getPresentation();
+      presentation.setVisible(false);
+      presentation.setEnabled(false);
+      final Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
+      if (project == null) {
+        return;
+      }
+      final ErrorTreeElement errorTreeElement = getSelectedErrorTreeElement();
+      if (errorTreeElement instanceof NavigatableMessageElement) {
+        final NavigatableMessageElement messageElement = (NavigatableMessageElement)errorTreeElement;
+        final String[] text = messageElement.getText();
+        if (text.length > 0) {
+          if (text[0].startsWith("[") && text[0].indexOf("]") != -1) {
+            final Navigatable navigatable = messageElement.getNavigatable();
+            if (navigatable instanceof OpenFileDescriptor) {
+              final OpenFileDescriptor fileDescriptor = (OpenFileDescriptor)navigatable;
+              final VirtualFile virtualFile = fileDescriptor.getFile();
+              final Module module = ModuleUtilCore.findModuleForFile(virtualFile, project);
+              if (module == null) {
+                return;
+              }
+              final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+              if (jdk == null) {
+                return;
+              }
+              final boolean is_1_5 = JavaSdk.getInstance().isOfVersionOrHigher(jdk, JavaSdkVersion.JDK_1_5);
+              if (!is_1_5) {
+                return;
+              }
+              final PsiFile psiFile = PsiManager.getInstance(project).findFile(virtualFile);
+              if (psiFile == null) {
+                return;
+              }
+              if (LanguageLevelUtil.getEffectiveLanguageLevel(module).compareTo(LanguageLevel.JDK_1_5) < 0) return;
+              final PsiElement context = psiFile.findElementAt(fileDescriptor.getOffset());
+              if (context == null) {
+                return;
+              }
+              final String id = text[0].substring(1, text[0].indexOf("]"));
+              final SuppressFix suppressInspectionFix = getSuppressAction(id);
+              final boolean available = suppressInspectionFix.isAvailable(project, null, context);
+              presentation.setEnabled(available);
+              presentation.setVisible(available);
+              if (available) {
+                presentation.setText(suppressInspectionFix.getText());
+              }
+            }
+          }
+        }
+      }
+    }
+
+    protected SuppressFix getSuppressAction(final String id) {
+      return new SuppressFix(id) {
+        @Override
+        @SuppressWarnings({"SimplifiableIfStatement"})
+        public boolean isAvailable(@NotNull final Project project, final Editor editor, @NotNull final PsiElement context) {
+          if (getContainer(context) instanceof PsiClass) return false;
+          return super.isAvailable(project, editor, context);
+        }
+
+        @Override
+        protected boolean use15Suppressions(final PsiDocCommentOwner container) {
+          return true;
+        }
+      };
+    }
+  }
+
+  private class SuppressJavacWarningForClassAction extends SuppressJavacWarningsAction {
+    @Override
+    protected SuppressFix getSuppressAction(final String id) {
+      return new SuppressForClassFix(id){
+        @Override
+        protected boolean use15Suppressions(final PsiDocCommentOwner container) {
+          return true;
+        }
+      };
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerPropertiesAction.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerPropertiesAction.java
new file mode 100644
index 0000000..5f1bf29
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerPropertiesAction.java
@@ -0,0 +1,42 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.options.CompilerConfigurable;
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 9/12/12
+*/
+class CompilerPropertiesAction extends AnAction {
+  public CompilerPropertiesAction() {
+    super(CompilerBundle.message("action.compiler.properties.text"), null, AllIcons.General.Settings);
+  }
+
+  public void actionPerformed(AnActionEvent e) {
+    Project project = PlatformDataKeys.PROJECT.getData(e.getDataContext());
+    if (project != null) {
+      ShowSettingsUtil.getInstance().editConfigurable(project, new CompilerConfigurable(project));
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java
new file mode 100644
index 0000000..1417fa6
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompilerUtil.java
@@ -0,0 +1,346 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 3, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.CommonBundle;
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.newvfs.RefreshQueue;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.util.*;
+
+public class CompilerUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.CompilerUtil");
+
+  public static String quotePath(String path) {
+    if(path != null && path.indexOf(' ') != -1) {
+      path = path.replaceAll("\\\\", "\\\\\\\\");
+      path = '"' + path + '"';
+    }
+    return path;
+  }
+
+  public static void collectFiles(Collection<File> container, File rootDir, FileFilter fileFilter) {
+    final File[] files = rootDir.listFiles(fileFilter);
+    if (files == null) {
+      return;
+    }
+    for (File file : files) {
+      if (file.isDirectory()) {
+        collectFiles(container, file, fileFilter);
+      }
+      else {
+        container.add(file);
+      }
+    }
+  }
+
+  public static Map<Module, List<VirtualFile>> buildModuleToFilesMap(CompileContext context, VirtualFile[] files) {
+    return buildModuleToFilesMap(context, Arrays.asList(files));
+  }
+
+
+  public static Map<Module, List<VirtualFile>> buildModuleToFilesMap(final CompileContext context, final List<VirtualFile> files) {
+    //assertion: all files are different
+    final Map<Module, List<VirtualFile>> map = new THashMap<Module, List<VirtualFile>>();
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        for (VirtualFile file : files) {
+          final Module module = context.getModuleByFile(file);
+
+          if (module == null) {
+            continue; // looks like file invalidated
+          }
+
+          List<VirtualFile> moduleFiles = map.get(module);
+          if (moduleFiles == null) {
+            moduleFiles = new ArrayList<VirtualFile>();
+            map.put(module, moduleFiles);
+          }
+          moduleFiles.add(file);
+        }
+      }
+    });
+    return map;
+  }
+
+
+  /**
+   * must not be called inside ReadAction
+   * @param files
+   */
+  public static void refreshIOFiles(@NotNull final Collection<File> files) {
+    if (!files.isEmpty()) {
+      LocalFileSystem.getInstance().refreshIoFiles(files);
+    }
+  }
+
+  public static void refreshIODirectories(@NotNull final Collection<File> files) {
+    final LocalFileSystem lfs = LocalFileSystem.getInstance();
+    final List<VirtualFile> filesToRefresh = new ArrayList<VirtualFile>();
+    for (File file : files) {
+      final VirtualFile virtualFile = lfs.refreshAndFindFileByIoFile(file);
+      if (virtualFile != null) {
+        filesToRefresh.add(virtualFile);
+      }
+    }
+    if (!filesToRefresh.isEmpty()) {
+      RefreshQueue.getInstance().refresh(false, true, null, filesToRefresh);
+    }
+  }
+
+  public static void refreshIOFile(final File file) {
+    final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+    if (vFile != null) {
+      vFile.refresh(false, false);
+    }
+  }
+
+  public static void addLocaleOptions(final List<String> commandLine, final boolean launcherUsed) {
+    // need to specify default encoding so that javac outputs messages in 'correct' language
+    //noinspection HardCodedStringLiteral
+    commandLine.add((launcherUsed? "-J" : "") + "-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + CharsetToolkit.getDefaultSystemCharset().name());
+    // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
+    //noinspection HardCodedStringLiteral
+    final String lang = System.getProperty("user.language");
+    if (lang != null) {
+      //noinspection HardCodedStringLiteral
+      commandLine.add((launcherUsed? "-J" : "") + "-Duser.language=" + lang);
+    }
+    //noinspection HardCodedStringLiteral
+    final String country = System.getProperty("user.country");
+    if (country != null) {
+      //noinspection HardCodedStringLiteral
+      commandLine.add((launcherUsed? "-J" : "") + "-Duser.country=" + country);
+    }
+    //noinspection HardCodedStringLiteral
+    final String region = System.getProperty("user.region");
+    if (region != null) {
+      //noinspection HardCodedStringLiteral
+      commandLine.add((launcherUsed? "-J" : "") + "-Duser.region=" + region);
+    }
+  }
+
+  public static void addTargetCommandLineSwitch(final ModuleChunk chunk, final List<String> commandLine) {
+    String optionValue = null;
+    CompilerConfiguration config = null;
+    final Module[] modules = chunk.getModules();
+    for (Module module : modules) {
+      if (config == null) {
+        config = CompilerConfiguration.getInstance(module.getProject());
+      }
+      final String moduleTarget = config.getBytecodeTargetLevel(module);
+      if (moduleTarget == null) {
+        continue;
+      }
+      if (optionValue == null) {
+        optionValue = moduleTarget;
+      }
+      else {
+        if (moduleTarget.compareTo(optionValue) < 0) {
+          optionValue = moduleTarget; // use the lower possible target among modules that form the chunk
+        }
+      }
+    }
+    if (optionValue != null) {
+      commandLine.add("-target");
+      commandLine.add(optionValue);
+    }
+  }
+
+  public static void addSourceCommandLineSwitch(final Sdk jdk, LanguageLevel chunkLanguageLevel, @NonNls final List<String> commandLine) {
+    final String versionString = jdk.getVersionString();
+    if (StringUtil.isEmpty(versionString)) {
+      throw new IllegalArgumentException(CompilerBundle.message("javac.error.unknown.jdk.version", jdk.getName()));
+    }
+
+    final LanguageLevel applicableLanguageLevel = getApplicableLanguageLevel(versionString, chunkLanguageLevel);
+    if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_8)) {
+      commandLine.add("-source");
+      commandLine.add("8");
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_7)) {
+      commandLine.add("-source");
+      commandLine.add("1.7");
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_6)) {
+      commandLine.add("-source");
+      commandLine.add("1.6");
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_5)) {
+      commandLine.add("-source");
+      commandLine.add("1.5");
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_4)) {
+      commandLine.add("-source");
+      commandLine.add("1.4");
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_3)) {
+      if (!(isOfVersion(versionString, "1.3") || isOfVersion(versionString, "1.2") || isOfVersion(versionString, "1.1"))) {
+        //noinspection HardCodedStringLiteral
+        commandLine.add("-source");
+        commandLine.add("1.3");
+      }
+    }
+  }
+
+  //todo[nik] rewrite using JavaSdkVersion#getMaxLanguageLevel
+  @NotNull
+  public static LanguageLevel getApplicableLanguageLevel(String versionString, @NotNull LanguageLevel languageLevel) {
+    final boolean is8OrNewer = isOfVersion(versionString, "1.8") || isOfVersion(versionString, "8.0");
+    final boolean is7OrNewer = is8OrNewer || isOfVersion(versionString, "1.7") || isOfVersion(versionString, "7.0");
+    final boolean is6OrNewer = is7OrNewer || isOfVersion(versionString, "1.6") || isOfVersion(versionString, "6.0");
+    final boolean is5OrNewer = is6OrNewer || isOfVersion(versionString, "1.5") || isOfVersion(versionString, "5.0");
+    final boolean is4OrNewer = is5OrNewer || isOfVersion(versionString, "1.4");
+    final boolean is3OrNewer = is4OrNewer || isOfVersion(versionString, "1.3");
+    final boolean is2OrNewer = is3OrNewer || isOfVersion(versionString, "1.2");
+    final boolean is1OrNewer = is2OrNewer || isOfVersion(versionString, "1.0") || isOfVersion(versionString, "1.1");
+    
+    if (!is1OrNewer) {
+      // unknown jdk version, cannot say anything about the corresponding language level, so leave it unchanged
+      return languageLevel;
+    }
+    // now correct the language level to be not higher than jdk used to compile
+    if (LanguageLevel.JDK_1_8.equals(languageLevel) && !is8OrNewer) {
+      languageLevel = LanguageLevel.JDK_1_7;
+    }
+    if (LanguageLevel.JDK_1_7.equals(languageLevel) && !is7OrNewer) {
+      languageLevel = LanguageLevel.JDK_1_6;
+    }
+    if (LanguageLevel.JDK_1_6.equals(languageLevel) && !is6OrNewer) {
+      languageLevel = LanguageLevel.JDK_1_5;
+    }
+    if (LanguageLevel.JDK_1_5.equals(languageLevel) && !is5OrNewer) {
+      languageLevel = LanguageLevel.JDK_1_4;
+    }
+    if (LanguageLevel.JDK_1_4.equals(languageLevel) && !is4OrNewer) {
+      languageLevel = LanguageLevel.JDK_1_3;
+    }
+    return languageLevel;
+  }
+
+  public static boolean isOfVersion(String versionString, String checkedVersion) {
+    return versionString.contains(checkedVersion);
+  }
+
+  public static <T extends Throwable> void runInContext(CompileContext context, String title, ThrowableRunnable<T> action) throws T {
+    if (title != null) {
+      context.getProgressIndicator().pushState();
+      context.getProgressIndicator().setText(title);
+    }
+    try {
+      action.run();
+    }
+    finally {
+      if (title != null) {
+        context.getProgressIndicator().popState();
+      }
+    }
+  }
+
+  public static void logDuration(final String activityName, long duration) {
+    LOG.info(activityName + " took " + duration + " ms: " + duration /60000 + " min " +(duration %60000)/1000 + "sec");
+  }
+
+  public static void clearOutputDirectories(final Collection<File> outputDirectories) {
+    final long start = System.currentTimeMillis();
+    // do not delete directories themselves, or we'll get rootsChanged() otherwise
+    final Collection<File> filesToDelete = new ArrayList<File>(outputDirectories.size() * 2);
+    for (File outputDirectory : outputDirectories) {
+      File[] files = outputDirectory.listFiles();
+      if (files != null) {
+        ContainerUtil.addAll(filesToDelete, files);
+      }
+    }
+    if (filesToDelete.size() > 0) {
+      FileUtil.asyncDelete(filesToDelete);
+
+      // ensure output directories exist
+      for (final File file : outputDirectories) {
+        file.mkdirs();
+      }
+      final long clearStop = System.currentTimeMillis();
+
+      refreshIODirectories(outputDirectories);
+
+      final long refreshStop = System.currentTimeMillis();
+
+      logDuration("Clearing output dirs", clearStop - start);
+      logDuration("Refreshing output directories", refreshStop - clearStop);
+    }
+  }
+
+  public static void computeIntersectingPaths(final Project project,
+                                                          final Collection<VirtualFile> outputPaths,
+                                                          final Collection<VirtualFile> result) {
+    for (Module module : ModuleManager.getInstance(project).getModules()) {
+      final ModuleRootManager rootManager = ModuleRootManager.getInstance(module);
+      final VirtualFile[] sourceRoots = rootManager.getSourceRoots();
+      for (final VirtualFile outputPath : outputPaths) {
+        for (VirtualFile sourceRoot : sourceRoots) {
+          if (VfsUtilCore.isAncestor(outputPath, sourceRoot, true) || VfsUtilCore.isAncestor(sourceRoot, outputPath, false)) {
+            result.add(outputPath);
+          }
+        }
+      }
+    }
+  }
+
+  public static boolean askUserToContinueWithNoClearing(Project project, Collection<VirtualFile> affectedOutputPaths) {
+    final StringBuilder paths = new StringBuilder();
+    for (final VirtualFile affectedOutputPath : affectedOutputPaths) {
+      if (paths.length() > 0) {
+        paths.append(",\n");
+      }
+      paths.append(affectedOutputPath.getPath().replace('/', File.separatorChar));
+    }
+    final int answer = Messages.showOkCancelDialog(project,
+                                                   CompilerBundle.message("warning.sources.under.output.paths", paths.toString()),
+                                                   CommonBundle.getErrorTitle(), Messages.getWarningIcon());
+    if (answer == Messages.OK) { // ok
+      return true;
+    }
+    else {
+      return false;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompositeScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompositeScope.java
new file mode 100644
index 0000000..2d18e44
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompositeScope.java
@@ -0,0 +1,106 @@
+/*
+ * 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: Feb 5, 2003
+ * Time: 4:17:58 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.ExportableUserDataHolderBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class CompositeScope extends ExportableUserDataHolderBase implements CompileScope{
+  private final List<CompileScope> myScopes = new ArrayList<CompileScope>();
+
+  public CompositeScope(CompileScope scope1, CompileScope scope2) {
+    addScope(scope1);
+    addScope(scope2);
+  }
+
+  public CompositeScope(CompileScope[] scopes) {
+    for (CompileScope scope : scopes) {
+      addScope(scope);
+    }
+  }
+
+  private void addScope(CompileScope scope) {
+    if (scope instanceof CompositeScope) {
+      final CompositeScope compositeScope = (CompositeScope)scope;
+      for (CompileScope childScope : compositeScope.myScopes) {
+        addScope(childScope);
+      }
+    }
+    else {
+      myScopes.add(scope);
+    }
+  }
+
+  @NotNull
+  public VirtualFile[] getFiles(FileType fileType, boolean inSourceOnly) {
+    Set<VirtualFile> allFiles = new THashSet<VirtualFile>();
+    for (CompileScope scope : myScopes) {
+      final VirtualFile[] files = scope.getFiles(fileType, inSourceOnly);
+      if (files.length > 0) {
+        ContainerUtil.addAll(allFiles, files);
+      }
+    }
+    return VfsUtil.toVirtualFileArray(allFiles);
+  }
+
+  public boolean belongs(String url) {
+    for (CompileScope scope : myScopes) {
+      if (scope.belongs(url)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  @NotNull
+  public Module[] getAffectedModules() {
+    Set<Module> modules = new HashSet<Module>();
+    for (final CompileScope compileScope : myScopes) {
+      ContainerUtil.addAll(modules, compileScope.getAffectedModules());
+    }
+    return modules.toArray(new Module[modules.size()]);
+  }
+
+  public <T> T getUserData(@NotNull Key<T> key) {
+    for (CompileScope compileScope : myScopes) {
+      T userData = compileScope.getUserData(key);
+      if (userData != null) {
+        return userData;
+      }
+    }
+    return super.getUserData(key);
+  }
+  
+  public Collection<CompileScope> getScopes() {
+    return Collections.unmodifiableList(myScopes);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ExcludeFromCompileAction.java b/java/compiler/impl/src/com/intellij/compiler/impl/ExcludeFromCompileAction.java
new file mode 100644
index 0000000..91055db
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ExcludeFromCompileAction.java
@@ -0,0 +1,78 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.ide.errorTreeView.ErrorTreeElement;
+import com.intellij.ide.errorTreeView.ErrorTreeNodeDescriptor;
+import com.intellij.ide.errorTreeView.GroupingElement;
+import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
+import com.intellij.ide.util.treeView.NodeDescriptor;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.Presentation;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.options.ExcludeEntryDescription;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 9/12/12
+*/
+class ExcludeFromCompileAction extends AnAction {
+  private final Project myProject;
+  private final NewErrorTreeViewPanel myErrorTreeView;
+
+  public ExcludeFromCompileAction(Project project, NewErrorTreeViewPanel errorTreeView) {
+    super(CompilerBundle.message("actions.exclude.from.compile.text"));
+    myProject = project;
+    myErrorTreeView = errorTreeView;
+  }
+
+  public void actionPerformed(AnActionEvent e) {
+    VirtualFile file = getSelectedFile();
+
+    if (file != null && file.isValid()) {
+      ExcludeEntryDescription description = new ExcludeEntryDescription(file, false, true, myProject);
+      ((CompilerConfigurationImpl) CompilerConfiguration.getInstance(myProject)).getExcludedEntriesConfiguration().addExcludeEntryDescription(description);
+      FileStatusManager.getInstance(myProject).fileStatusesChanged();
+    }
+  }
+
+  @Nullable
+  private VirtualFile getSelectedFile() {
+    final ErrorTreeNodeDescriptor descriptor = myErrorTreeView.getSelectedNodeDescriptor();
+    ErrorTreeElement element = descriptor != null? descriptor.getElement() : null;
+    if (element != null && !(element instanceof GroupingElement)) {
+      NodeDescriptor parent = descriptor.getParentDescriptor();
+      if (parent instanceof ErrorTreeNodeDescriptor) {
+        element = ((ErrorTreeNodeDescriptor)parent).getElement();
+      }
+    }
+    return element instanceof GroupingElement? ((GroupingElement)element).getFile() : null;
+  }
+
+  public void update(AnActionEvent e) {
+    final Presentation presentation = e.getPresentation();
+    final boolean isApplicable = getSelectedFile() != null;
+    presentation.setEnabled(isApplicable);
+    presentation.setVisible(isApplicable);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ExitException.java b/java/compiler/impl/src/com/intellij/compiler/impl/ExitException.java
new file mode 100644
index 0000000..b40d6f4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ExitException.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2011 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.compiler.impl;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 11/24/11
+*/
+public class ExitException extends Exception {
+  private final ExitStatus myStatus;
+
+  public ExitException(ExitStatus status) {
+    myStatus = status;
+  }
+
+  public ExitStatus getExitStatus() {
+    return myStatus;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ExitStatus.java b/java/compiler/impl/src/com/intellij/compiler/impl/ExitStatus.java
new file mode 100644
index 0000000..d44156b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ExitStatus.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2011 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.compiler.impl;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 11/24/11
+*/
+public class ExitStatus {
+  private final String myName;
+
+  ExitStatus(@NonNls String name) {
+    myName = name;
+  }
+
+  public String toString() {
+    return myName;
+  }
+
+  public static final ExitStatus CANCELLED = new ExitStatus("CANCELLED");
+  public static final ExitStatus ERRORS = new ExitStatus("ERRORS");
+  public static final ExitStatus SUCCESS = new ExitStatus("SUCCESS");
+  public static final ExitStatus UP_TO_DATE = new ExitStatus("UP_TO_DATE");
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileIndexCompileScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileIndexCompileScope.java
new file mode 100644
index 0000000..8f1f2dd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileIndexCompileScope.java
@@ -0,0 +1,46 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.ExportableUserDataHolderBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 18, 2003
+ */
+public abstract class FileIndexCompileScope extends ExportableUserDataHolderBase implements CompileScope {
+
+  protected abstract FileIndex[] getFileIndices();
+
+  @NotNull
+  public VirtualFile[] getFiles(final FileType fileType, final boolean inSourceOnly) {
+    final List<VirtualFile> files = new ArrayList<VirtualFile>();
+    final FileIndex[] fileIndices = getFileIndices();
+    for (final FileIndex fileIndex : fileIndices) {
+      fileIndex.iterateContent(new CompilerContentIterator(fileType, fileIndex, inSourceOnly, files));
+    }
+    return VfsUtil.toVirtualFileArray(files);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java
new file mode 100644
index 0000000..8087b42
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapter.java
@@ -0,0 +1,54 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.FileProcessingCompiler;
+import com.intellij.openapi.compiler.ValidityState;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 16
+ * @author 2003
+ */
+public class FileProcessingCompilerAdapter {
+  private final CompileContext myCompileContext;
+  private final FileProcessingCompiler myCompiler;
+
+  protected FileProcessingCompilerAdapter(CompileContext compileContext, FileProcessingCompiler compiler) {
+    myCompileContext = compileContext;
+    myCompiler = compiler;
+  }
+
+  public CompileContext getCompileContext() {
+    return myCompileContext;
+  }
+
+  public FileProcessingCompiler.ProcessingItem[] getProcessingItems() {
+    return myCompiler.getProcessingItems(getCompileContext());
+  }
+
+  public FileProcessingCompiler.ProcessingItem[] process(FileProcessingCompiler.ProcessingItem[] items) {
+    return myCompiler.process(getCompileContext(), items);
+  }
+
+  public final FileProcessingCompiler getCompiler() {
+    return myCompiler;
+  }
+
+  public void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state){}
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
new file mode 100644
index 0000000..f53e4df
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
@@ -0,0 +1,122 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ThrowableRunnable;
+
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * This is an adapter for running any FileProcessingCompiler as a compiler task
+ *
+ *
+ * @author Eugene Zhuravlev
+ *         Date: 9/5/12
+ */
+public class FileProcessingCompilerAdapterTask implements CompileTask{
+  private final FileProcessingCompiler myCompiler;
+
+  public FileProcessingCompilerAdapterTask(FileProcessingCompiler compiler) {
+    myCompiler = compiler;
+  }
+
+  public FileProcessingCompiler getCompiler() {
+    return myCompiler;
+  }
+
+  @Override
+  public boolean execute(CompileContext context) {
+    final Project project = context.getProject();
+    if (!CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
+      return true;
+    }
+    try {
+      final FileProcessingCompiler.ProcessingItem[] items = myCompiler.getProcessingItems(context);
+      if (items.length == 0) {
+        return true;
+      }
+      final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
+      final Ref<IOException> ex = new Ref<IOException>(null);
+
+      DumbService.getInstance(project).waitForSmartMode();
+
+      final FileProcessingCompilerStateCache cache = CompilerCacheManager.getInstance(project).getFileProcessingCompilerCache(myCompiler);
+      final boolean isMake = context.isMake();
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          try {
+            for (FileProcessingCompiler.ProcessingItem item : items) {
+              final VirtualFile file = item.getFile();
+              final String url = file.getUrl();
+              if (isMake && cache.getTimestamp(url) == file.getTimeStamp()) {
+                final ValidityState state = cache.getExtState(url);
+                final ValidityState itemState = item.getValidityState();
+                if (state != null ? state.equalsTo(itemState) : itemState == null) {
+                  continue;
+                }
+              }
+              toProcess.add(item);
+            }
+          }
+          catch (IOException e) {
+            ex.set(e);
+          }
+        }
+      });
+
+      if (ex.get() != null) {
+        throw ex.get();
+      }
+
+      if (toProcess.isEmpty()) {
+        return true;
+      }
+
+      final FileProcessingCompiler.ProcessingItem[] processed = myCompiler.process(context, toProcess.toArray(new FileProcessingCompiler.ProcessingItem[toProcess.size()]));
+
+      if (processed.length == 0) {
+        return true;
+      }
+
+      CompilerUtil.runInContext(context, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable<IOException>() {
+        public void run() throws IOException{
+          final List<VirtualFile> vFiles = new ArrayList<VirtualFile>(processed.length);
+          for (FileProcessingCompiler.ProcessingItem item : processed) {
+            vFiles.add(item.getFile());
+          }
+          LocalFileSystem.getInstance().refreshFiles(vFiles);
+          for (FileProcessingCompiler.ProcessingItem item : processed) {
+            cache.update(item.getFile(), item.getValidityState());
+          }
+        }
+      });
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java
new file mode 100644
index 0000000..050002d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerStateCache.java
@@ -0,0 +1,117 @@
+/*
+ * 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: Apr 1, 2003
+ * Time: 1:17:50 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.openapi.compiler.ValidityState;
+import com.intellij.openapi.compiler.ValidityStateFactory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.*;
+import java.util.Collection;
+
+public class FileProcessingCompilerStateCache {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.FileProcessingCompilerStateCache");
+  private final StateCache<MyState> myCache;
+
+  public FileProcessingCompilerStateCache(File storeDirectory, final ValidityStateFactory stateFactory) throws IOException {
+    myCache = new StateCache<MyState>(new File(storeDirectory, "timestamps")) {
+      public MyState read(DataInput stream) throws IOException {
+        return new MyState(stream.readLong(), stateFactory.createValidityState(stream));
+      }
+
+      public void write(MyState state, DataOutput out) throws IOException {
+        out.writeLong(state.getTimestamp());
+        final ValidityState extState = state.getExtState();
+        if (extState != null) {
+          extState.save(out);
+        }
+      }
+    };
+  }
+
+  public void update(VirtualFile sourceFile, ValidityState extState) throws IOException {
+    if (sourceFile.isValid()) {
+      // only mark as up-to-date if the file did not become invalid during make
+      myCache.update(sourceFile.getUrl(), new MyState(sourceFile.getTimeStamp(), extState));
+    }
+  }
+
+  public void remove(String url) throws IOException {
+    myCache.remove(url);
+  }
+
+  public long getTimestamp(String url) throws IOException {
+    final Serializable savedState = myCache.getState(url);
+    if (savedState != null) {
+      LOG.assertTrue(savedState instanceof MyState);
+    }
+    MyState state = (MyState)savedState;
+    return (state != null)? state.getTimestamp() : -1L;
+  }
+
+  public ValidityState getExtState(String url) throws IOException {
+    MyState state = myCache.getState(url);
+    return (state != null)? state.getExtState() : null;
+  }
+
+  public void force() {
+    myCache.force();
+  }
+
+  public Collection<String> getUrls() throws IOException {
+    return myCache.getUrls();
+  }
+
+  public boolean wipe() {
+    return myCache.wipe();
+  }
+
+  public void close() {
+    try {
+      myCache.close();
+    }
+    catch (IOException ignored) {
+      LOG.info(ignored);
+    }
+  }
+
+  private static class MyState implements Serializable {
+    private final long myTimestamp;
+    private final ValidityState myExtState;
+
+    public MyState(long timestamp, @Nullable ValidityState extState) {
+      myTimestamp = timestamp;
+      myExtState = extState;
+    }
+
+    public long getTimestamp() {
+      return myTimestamp;
+    }
+
+    public @Nullable ValidityState getExtState() {
+      return myExtState;
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileSetCompileScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileSetCompileScope.java
new file mode 100644
index 0000000..4a10ad3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileSetCompileScope.java
@@ -0,0 +1,128 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.ExportableUserDataHolderBase;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * @since Jan 20, 2003
+ */
+public class FileSetCompileScope extends ExportableUserDataHolderBase implements CompileScope {
+  private final Set<VirtualFile> myRootFiles = new HashSet<VirtualFile>();
+  private final Set<String> myDirectoryUrls = new HashSet<String>();
+  private Set<String> myUrls = null; // urls caching
+  private final Module[] myAffectedModules;
+
+  public FileSetCompileScope(final Collection<VirtualFile> files, Module[] modules) {
+    myAffectedModules = modules;
+    ApplicationManager.getApplication().runReadAction(
+      new Runnable() {
+        public void run() {
+          for (VirtualFile file : files) {
+            assert file != null;
+            addFile(file);
+          }
+        }
+      }
+    );
+  }
+
+  @NotNull
+  public Module[] getAffectedModules() {
+    return myAffectedModules;
+  }
+
+  public Collection<VirtualFile> getRootFiles() {
+    return Collections.unmodifiableCollection(myRootFiles);
+  }
+
+  @NotNull
+  public VirtualFile[] getFiles(final FileType fileType, boolean inSourceOnly) {
+    final List<VirtualFile> files = new ArrayList<VirtualFile>();
+    for (Iterator<VirtualFile> it = myRootFiles.iterator(); it.hasNext();) {
+      VirtualFile file = it.next();
+      if (!file.isValid()) {
+        it.remove();
+        continue;
+      }
+      if (file.isDirectory()) {
+        addRecursively(files, file, fileType);
+      }
+      else {
+        if (fileType == null || fileType.equals(file.getFileType())) {
+          files.add(file);
+        }
+      }
+    }
+    return VfsUtilCore.toVirtualFileArray(files);
+  }
+
+  public boolean belongs(String url) {
+    //url = CompilerUtil.normalizePath(url, '/');
+    if (getUrls().contains(url)) {
+      return true;
+    }
+    for (String directoryUrl : myDirectoryUrls) {
+      if (FileUtil.startsWith(url, directoryUrl)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private Set<String> getUrls() {
+    if (myUrls == null) {
+      myUrls = new HashSet<String>();
+      for (VirtualFile file : myRootFiles) {
+        String url = file.getUrl();
+        myUrls.add(url);
+      }
+    }
+    return myUrls;
+  }
+
+  private void addFile(VirtualFile file) {
+    if (file.isDirectory()) {
+      myDirectoryUrls.add(file.getUrl() + "/");
+    }
+    myRootFiles.add(file);
+    myUrls = null;
+  }
+
+  private static void addRecursively(final Collection<VirtualFile> container, VirtualFile fromDirectory, final FileType fileType) {
+    VfsUtilCore.visitChildrenRecursively(fromDirectory, new VirtualFileVisitor(VirtualFileVisitor.SKIP_ROOT) {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile child) {
+        if (!child.isDirectory() && (fileType == null || fileType.equals(child.getFileType()))) {
+          container.add(child);
+        }
+        return true;
+      }
+    });
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
new file mode 100644
index 0000000..3cba065
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
@@ -0,0 +1,338 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl;
+
+import com.intellij.compiler.impl.generic.GenericCompilerCache;
+import com.intellij.compiler.impl.generic.GenericCompilerPersistentData;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.RunResult;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.CompilerPaths;
+import com.intellij.openapi.compiler.generic.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Processor;
+import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.io.KeyDescriptor;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectHashingStrategy;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class GenericCompilerRunner {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.GenericCompilerRunner");
+  private static final Logger FULL_LOG = Logger.getInstance("#com.intellij.full-generic-compiler-log");
+  private CompileContext myContext;
+  private final boolean myForceCompile;
+  private final boolean myOnlyCheckStatus;
+  private final GenericCompiler<?,?,?>[] myCompilers;
+  private final Project myProject;
+
+  public GenericCompilerRunner(CompileContext context,
+                               boolean forceCompile,
+                               boolean onlyCheckStatus, final GenericCompiler[] compilers) {
+    myContext = context;
+    myForceCompile = forceCompile;
+    myOnlyCheckStatus = onlyCheckStatus;
+    myCompilers = compilers;
+    myProject = myContext.getProject();
+  }
+
+  public boolean invokeCompilers(GenericCompiler.CompileOrderPlace place) throws ExitException {
+    boolean didSomething = false;
+    try {
+      for (GenericCompiler<?,?,?> compiler : myCompilers) {
+        if (compiler.getOrderPlace().equals(place)) {
+          didSomething |= invokeCompiler(compiler);
+        }
+      }
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      myContext.requestRebuildNextTime(e.getMessage());
+      throw new ExitException(ExitStatus.ERRORS);
+    }
+    catch (ExitException e) {
+      throw e;
+    }
+    catch (ProcessCanceledException e) {
+      throw e;
+    }
+    catch (Exception e) {
+      LOG.info(e);
+      myContext.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("compiler.error.exception", e.getMessage()), null, -1, -1);
+    }
+    return didSomething;
+  }
+
+  private <Key, SourceState, OutputState> boolean invokeCompiler(GenericCompiler<Key, SourceState, OutputState> compiler) throws IOException,
+                                                                                                                                 ExitException {
+    return invokeCompiler(compiler, compiler.createInstance(myContext));
+  }
+
+  private <T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState>
+  boolean invokeCompiler(GenericCompiler<Key, SourceState, OutputState> compiler, final GenericCompilerInstance<T, Item, Key, SourceState, OutputState> instance) throws IOException,
+                                                                                                                                                                         ExitException {
+    final GenericCompilerCache<Key, SourceState, OutputState> cache = CompilerCacheManager.getInstance(myProject).getGenericCompilerCache(compiler);
+    GenericCompilerPersistentData
+      data = new GenericCompilerPersistentData(getGenericCompilerCacheDir(myProject, compiler), compiler.getVersion());
+    if (data.isVersionChanged()) {
+      LOG.info("Clearing cache for " + compiler.getDescription());
+      cache.wipe();
+      data.save();
+    }
+
+    final Set<String> targetsToRemove = new HashSet<String>(data.getAllTargets());
+    new ReadAction() {
+      protected void run(final Result result) {
+        for (T target : instance.getAllTargets()) {
+          targetsToRemove.remove(target.getId());
+        }
+      }
+    }.execute();
+
+    if (!myOnlyCheckStatus) {
+      for (final String target : targetsToRemove) {
+        final int id = data.removeId(target);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Removing obsolete target '" + target + "' (id=" + id + ")");
+        }
+
+        final List<Key> keys = new ArrayList<Key>();
+        CompilerUtil.runInContext(myContext, "Processing obsolete targets...", new ThrowableRunnable<IOException>() {
+          @Override
+          public void run() throws IOException {
+            cache.processSources(id, new CommonProcessors.CollectProcessor<Key>(keys));
+            List<GenericCompilerCacheState<Key, SourceState, OutputState>> obsoleteSources = new ArrayList<GenericCompilerCacheState<Key,SourceState,OutputState>>();
+            for (Key key : keys) {
+              final GenericCompilerCache.PersistentStateData<SourceState, OutputState> state = cache.getState(id, key);
+              obsoleteSources.add(new GenericCompilerCacheState<Key,SourceState,OutputState>(key, state.mySourceState, state.myOutputState));
+            }
+            instance.processObsoleteTarget(target, obsoleteSources);
+          }
+        });
+        checkForErrorsOrCanceled();
+        for (Key key : keys) {
+          cache.remove(id, key);
+        }
+      }
+    }
+
+    final List<T> selectedTargets = new ReadAction<List<T>>() {
+      protected void run(final Result<List<T>> result) {
+        result.setResult(instance.getSelectedTargets());
+      }
+    }.execute().getResultObject();
+
+    boolean didSomething = false;
+    for (T target : selectedTargets) {
+      int id = data.getId(target.getId());
+      didSomething |= processTarget(target, id, compiler, instance, cache);
+    }
+
+    data.save();
+    return didSomething;
+  }
+
+  private void checkForErrorsOrCanceled() throws ExitException {
+    if (myContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+      throw new ExitException(ExitStatus.ERRORS);
+    }
+    if (myContext.getProgressIndicator().isCanceled()) {
+      throw new ExitException(ExitStatus.CANCELLED);
+    }
+  }
+
+  public static File getGenericCompilerCacheDir(Project project, GenericCompiler<?,?,?> compiler) {
+    return new File(CompilerPaths.getCacheStoreDirectory(project), compiler.getId());
+  }
+
+  private <T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState>
+  boolean processTarget(T target, final int targetId, final GenericCompiler<Key, SourceState, OutputState> compiler, final GenericCompilerInstance<T, Item, Key, SourceState, OutputState> instance,
+                        final GenericCompilerCache<Key, SourceState, OutputState> cache) throws IOException, ExitException {
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Processing target '" + target + "' (id=" + targetId + ") by " + compiler);
+    }
+    final List<Item> items = instance.getItems(target);
+    checkForErrorsOrCanceled();
+
+    final List<GenericCompilerProcessingItem<Item, SourceState, OutputState>> toProcess = new ArrayList<GenericCompilerProcessingItem<Item,SourceState,OutputState>>();
+    final THashSet<Key> keySet = new THashSet<Key>(new SourceItemHashingStrategy<Key>(compiler));
+    final Ref<IOException> exception = Ref.create(null);
+    DumbService.getInstance(myProject).waitForSmartMode();
+    final Map<Item, SourceState> sourceStates = new HashMap<Item,SourceState>();
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          for (Item item : items) {
+            final Key key = item.getKey();
+            keySet.add(key);
+            if (item.isExcluded()) continue;
+
+            final GenericCompilerCache.PersistentStateData<SourceState, OutputState> data = cache.getState(targetId, key);
+            SourceState sourceState = data != null ? data.mySourceState : null;
+            final OutputState outputState = data != null ? data.myOutputState : null;
+            if (myForceCompile || sourceState == null || !item.isSourceUpToDate(sourceState)
+                               || outputState == null || !item.isOutputUpToDate(outputState)) {
+              sourceStates.put(item, item.computeSourceState());
+              toProcess.add(new GenericCompilerProcessingItem<Item,SourceState,OutputState>(item, sourceState, outputState));
+            }
+          }
+        }
+        catch (IOException e) {
+          exception.set(e);
+        }
+      }
+    });
+    if (!exception.isNull()) {
+      throw exception.get();
+    }
+
+    final List<Key> toRemove = new ArrayList<Key>();
+    cache.processSources(targetId, new Processor<Key>() {
+      @Override
+      public boolean process(Key key) {
+        if (!keySet.contains(key)) {
+          toRemove.add(key);
+        }
+        return true;
+      }
+    });
+
+    if (LOG.isDebugEnabled()) {
+      LOG.debug(toProcess.size() + " items will be processed, " + toRemove.size() + " items will be removed");
+      for (int i = 0; i < getItemsCountToShowInLog(toProcess.size()); i++) {
+        LOG.debug("to process:" + toProcess.get(i).getItem().getKey());
+      }
+      for (int i = 0; i < getItemsCountToShowInLog(toRemove.size()); i++) {
+        LOG.debug("to delete:" + toRemove.get(i));
+      }
+    }
+
+    if (toProcess.isEmpty() && toRemove.isEmpty()) {
+      return false;
+    }
+
+    if (myOnlyCheckStatus) {
+      throw new ExitException(ExitStatus.CANCELLED);
+    }
+
+    List<GenericCompilerCacheState<Key, SourceState, OutputState>> obsoleteItems = new ArrayList<GenericCompilerCacheState<Key,SourceState,OutputState>>();
+    for (Key key : toRemove) {
+      final GenericCompilerCache.PersistentStateData<SourceState, OutputState> data = cache.getState(targetId, key);
+      obsoleteItems.add(new GenericCompilerCacheState<Key,SourceState,OutputState>(key, data.mySourceState, data.myOutputState));
+    }
+
+    final List<Item> processedItems = new ArrayList<Item>();
+    final List<File> filesToRefresh = new ArrayList<File>();
+    final List<File> dirsToRefresh = new ArrayList<File>();
+    instance.processItems(target, toProcess, obsoleteItems, new GenericCompilerInstance.OutputConsumer<Item>() {
+      @Override
+      public void addFileToRefresh(@NotNull File file) {
+        filesToRefresh.add(file);
+      }
+
+      @Override
+      public void addDirectoryToRefresh(@NotNull File dir) {
+        dirsToRefresh.add(dir);
+      }
+
+      @Override
+      public void addProcessedItem(@NotNull Item sourceItem) {
+        processedItems.add(sourceItem);
+      }
+    });
+    checkForErrorsOrCanceled();
+
+    CompilerUtil.runInContext(myContext, CompilerBundle.message("progress.updating.caches"), new ThrowableRunnable<IOException>() {
+      @Override
+      public void run() throws IOException {
+        for (Key key : toRemove) {
+          cache.remove(targetId, key);
+        }
+        CompilerUtil.refreshIOFiles(filesToRefresh);
+        CompilerUtil.refreshIODirectories(dirsToRefresh);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("refreshed " + filesToRefresh.size() + " files and " + dirsToRefresh.size() + " dirs");
+          for (int i = 0; i < getItemsCountToShowInLog(filesToRefresh.size()); i++) {
+            LOG.debug("file: " + filesToRefresh.get(i));
+          }
+          for (int i = 0; i < getItemsCountToShowInLog(dirsToRefresh.size()); i++) {
+            LOG.debug("dir: " + dirsToRefresh.get(i));
+          }
+        }
+
+        final RunResult runResult = new ReadAction() {
+          protected void run(final Result result) throws Throwable {
+            for (Item item : processedItems) {
+              SourceState sourceState = sourceStates.get(item);
+              if (sourceState == null) {
+                sourceState = item.computeSourceState();
+              }
+              cache.putState(targetId, item.getKey(), sourceState, item.computeOutputState());
+            }
+          }
+        }.executeSilently();
+        Throwable throwable = runResult.getThrowable();
+        if (throwable instanceof IOException) throw (IOException) throwable;
+        else if (throwable != null) throw new RuntimeException(throwable);
+      }
+    });
+
+    return true;
+
+  }
+
+  private static int getItemsCountToShowInLog(final int size) {
+    if (size > 100 && !FULL_LOG.isDebugEnabled()) {
+      return 100;
+    }
+    return size;
+  }
+
+  private class SourceItemHashingStrategy<S> implements TObjectHashingStrategy<S> {
+    private KeyDescriptor<S> myKeyDescriptor;
+
+    public SourceItemHashingStrategy(GenericCompiler<S, ?, ?> compiler) {
+      myKeyDescriptor = compiler.getItemKeyDescriptor();
+    }
+
+    @Override
+    public int computeHashCode(S object) {
+      return myKeyDescriptor.getHashCode(object);
+    }
+
+    @Override
+    public boolean equals(S o1, S o2) {
+      return myKeyDescriptor.isEqual(o1, o2);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/InternedPath.java b/java/compiler/impl/src/com/intellij/compiler/impl/InternedPath.java
new file mode 100644
index 0000000..7914dc2
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/InternedPath.java
@@ -0,0 +1,79 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.containers.StringInterner;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jun 21, 2006
+ */
+public class InternedPath {
+  private final @NotNull List<String> myValue;
+
+  public InternedPath(StringInterner interner, String url, final char separator) {
+    myValue = convert(interner, url, separator);
+  }
+
+  public String toString() {
+    return join(myValue, '/');
+  }
+
+  public static List<String> convert(StringInterner interner, String value, char delim) {
+    final List<String> result = new ArrayList<String>();
+    int start = 0;
+    final int len = value.length();
+    for (int idx = 0; idx < len; idx++) {
+      if (value.charAt(idx) == delim) {
+        result.add(interner.intern(value.substring(start, idx)));
+        start = idx + 1;
+      }
+    }
+    if (start < value.length()) {
+      result.add(interner.intern(value.substring(start)));
+    }
+    if (len > 0 && value.charAt(len-1) == delim) { // ends with delimiter
+      result.add("");
+    }
+    return result;
+  }
+
+  public static String join(List<String> value, char separator) {
+    final int size = value.size();
+    if (size > 1) {
+      final StringBuilder builder = StringBuilderSpinAllocator.alloc();
+      try {
+        builder.append(value.get(0));
+        for (int idx = 1; idx < size; idx++) {
+          builder.append(separator).append(value.get(idx));
+        }
+        return builder.toString();
+      }
+      finally {
+        StringBuilderSpinAllocator.dispose(builder);
+      }
+    }
+    else if (size == 1){
+      return value.get(0);
+    }
+    return "";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ModuleCompileScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/ModuleCompileScope.java
new file mode 100644
index 0000000..3be5efc
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ModuleCompileScope.java
@@ -0,0 +1,177 @@
+/*
+ * 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: Jan 20, 2003
+ * Time: 5:34:19 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+public class ModuleCompileScope extends FileIndexCompileScope {
+  private final Project myProject;
+  private final Set<Module> myScopeModules;
+  private final Module[] myModules;
+
+  public ModuleCompileScope(final Module module, boolean includeDependentModules) {
+    myProject = module.getProject();
+    myScopeModules = new HashSet<Module>();
+    if (includeDependentModules) {
+      buildScopeModulesSet(module);
+    }
+    else {
+      myScopeModules.add(module);
+    }
+    myModules = ModuleManager.getInstance(myProject).getModules();
+  }
+
+  public ModuleCompileScope(Project project, final Module[] modules, boolean includeDependentModules) {
+    myProject = project;
+    myScopeModules = new HashSet<Module>();
+    for (Module module : modules) {
+      if (module == null) {
+        continue; // prevent NPE
+      }
+      if (includeDependentModules) {
+        buildScopeModulesSet(module);
+      }
+      else {
+        myScopeModules.add(module);
+      }
+    }
+    myModules = ModuleManager.getInstance(myProject).getModules();
+  }
+
+  private void buildScopeModulesSet(Module module) {
+    myScopeModules.add(module);
+    final Module[] dependencies = ModuleRootManager.getInstance(module).getDependencies();
+    for (Module dependency : dependencies) {
+      if (!myScopeModules.contains(dependency)) { // may be in case of module circular dependencies
+        buildScopeModulesSet(dependency);
+      }
+    }
+  }
+
+  @NotNull
+  public Module[] getAffectedModules() {
+    return myScopeModules.toArray(new Module[myScopeModules.size()]);
+  }
+
+  protected FileIndex[] getFileIndices() {
+    final FileIndex[] indices = new FileIndex[myScopeModules.size()];
+    int idx = 0;
+    for (final Module module : myScopeModules) {
+      indices[idx++] = ModuleRootManager.getInstance(module).getFileIndex();
+    }
+    return indices;
+  }
+
+  public boolean belongs(final String url) {
+    if (myScopeModules.isEmpty()) {
+      return false; // optimization
+    }
+    Module candidateModule = null;
+    int maxUrlLength = 0;
+    final ProjectFileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+    for (final Module module : myModules) {
+      final String[] contentRootUrls = getModuleContentUrls(module);
+      for (final String contentRootUrl : contentRootUrls) {
+        if (contentRootUrl.length() < maxUrlLength) {
+          continue;
+        }
+        if (!isUrlUnderRoot(url, contentRootUrl)) {
+          continue;
+        }
+        if (contentRootUrl.length() == maxUrlLength) {
+          if (candidateModule == null) {
+            candidateModule = module;
+          }
+          else {
+            // the same content root exists in several modules
+            if (!candidateModule.equals(module)) {
+              candidateModule = ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+                public Module compute() {
+                  final VirtualFile contentRootFile = VirtualFileManager.getInstance().findFileByUrl(contentRootUrl);
+                  if (contentRootFile != null) {
+                    return projectFileIndex.getModuleForFile(contentRootFile);
+                  }
+                  return null;
+                }
+              });
+            }
+          }
+        }
+        else {
+          maxUrlLength = contentRootUrl.length();
+          candidateModule = module;
+        }
+      }
+    }
+
+    if (candidateModule != null && myScopeModules.contains(candidateModule)) {
+      final ModuleRootManager moduleRootManager = ModuleRootManager.getInstance(candidateModule);
+      final String[] excludeRootUrls = moduleRootManager.getExcludeRootUrls();
+      for (String excludeRootUrl : excludeRootUrls) {
+        if (isUrlUnderRoot(url, excludeRootUrl)) {
+          return false;
+        }
+      }
+      final String[] sourceRootUrls = moduleRootManager.getSourceRootUrls();
+      for (String sourceRootUrl : sourceRootUrls) {
+        if (isUrlUnderRoot(url, sourceRootUrl)) {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  private static boolean isUrlUnderRoot(final String url, final String root) {
+    return (url.length() > root.length()) && url.charAt(root.length()) == '/' && FileUtil.startsWith(url, root);
+  }
+
+  private final Map<Module, String[]> myContentUrlsCache = new HashMap<Module, String[]>();
+
+  private String[] getModuleContentUrls(final Module module) {
+    String[] contentRootUrls = myContentUrlsCache.get(module);
+    if (contentRootUrls == null) {
+      contentRootUrls = ModuleRootManager.getInstance(module).getContentRootUrls();
+      myContentUrlsCache.put(module, contentRootUrls);
+    }
+    return contentRootUrls;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/OneProjectItemCompileScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/OneProjectItemCompileScope.java
new file mode 100644
index 0000000..4b0b653
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/OneProjectItemCompileScope.java
@@ -0,0 +1,80 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.ExportableUserDataHolderBase;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentIterator;
+import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+public class OneProjectItemCompileScope extends ExportableUserDataHolderBase implements CompileScope{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.OneProjectItemCompileScope");
+  private final Project myProject;
+  private final VirtualFile myFile;
+  private final String myUrl;
+
+  public OneProjectItemCompileScope(Project project, VirtualFile file) {
+    myProject = project;
+    myFile = file;
+    final String url = file.getUrl();
+    myUrl = file.isDirectory()? url + "/" : url;
+  }
+
+  @NotNull
+  public VirtualFile[] getFiles(final FileType fileType, final boolean inSourceOnly) {
+    final List<VirtualFile> files = new ArrayList<VirtualFile>(1);
+    final FileIndex projectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+    final ContentIterator iterator = new CompilerContentIterator(fileType, projectFileIndex, inSourceOnly, files);
+    if (myFile.isDirectory()){
+      projectFileIndex.iterateContentUnderDirectory(myFile, iterator);
+    }
+    else{
+      iterator.processFile(myFile);
+    }
+    return VfsUtil.toVirtualFileArray(files);
+  }
+
+  public boolean belongs(String url) {
+    if (myFile.isDirectory()){
+      return FileUtil.startsWith(url, myUrl);
+    }
+    return FileUtil.pathsEqual(url, myUrl);
+  }
+
+  @NotNull
+  public Module[] getAffectedModules() {
+    final Module module = ModuleUtil.findModuleForFile(myFile, myProject);
+    if (module == null) {
+      LOG.error("Module is null for file " + myFile.getPresentableUrl());
+      return Module.EMPTY_ARRAY;
+    }
+    return new Module[] {module};
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/OutputPathFinder.java b/java/compiler/impl/src/com/intellij/compiler/impl/OutputPathFinder.java
new file mode 100644
index 0000000..6a712d1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/OutputPathFinder.java
@@ -0,0 +1,219 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.HashMap;
+import java.util.HashSet;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 6, 2009
+ */
+public class OutputPathFinder {
+  private final Node myRoot = new Node("");
+
+  public OutputPathFinder(Set<File> outputDirs) {
+    for (File dir : outputDirs) {
+      final String path = FileUtil.toSystemIndependentName(dir.getPath());
+      Node node = myRoot;
+      int idx = path.startsWith("/")? 1 : 0;
+      int slashIndex = path.indexOf('/', idx);
+
+      for (; slashIndex >= 0; slashIndex = path.indexOf('/', idx)) {
+        final String name = path.substring(idx, slashIndex);
+        node = node.addChild(name);
+        idx = slashIndex + 1;
+      }
+
+      if (idx < path.length()) {
+        node = node.addChild(path.substring(idx));
+      }
+
+      node.setData(path);
+    }
+  }
+
+  @Nullable
+  public String lookupOutputPath(File outputFile) {
+    return lookupOutputPath(outputFile.getPath());
+  }
+
+  @Nullable
+  public String lookupOutputPath(String filePath) {
+    final String path = FileUtil.toSystemIndependentName(filePath);
+    Node node = myRoot;
+    int idx = path.startsWith("/")? 1 : 0;
+
+    return findOutputPath(path, idx, node);
+  }
+
+  private static @Nullable String findOutputPath(final String path, int idx, Node node) {
+    while (true) {
+      final int slashIndex = path.indexOf('/', idx);
+      final String name = slashIndex < idx? path.substring(idx) : path.substring(idx, slashIndex);
+      node = node.getChild(name);
+      if (node == null) {
+        return null;
+      }
+      if (node.isOutputRoot()) {
+        if (node.hasChildren() && slashIndex > idx) {
+          final String candidate = findOutputPath(path, slashIndex + 1, node);
+          if (candidate != null) {
+            return candidate;
+          }
+        }
+        return node.getData();
+      }
+      if (slashIndex < 0) {
+        return null;  // end of path reached
+      }
+      idx = slashIndex + 1;
+    }
+  }
+
+  private static class Node {
+    private final String myName;
+    @Nullable
+    private Object myChildren; // either a Node or a Map<String, Node> or a String  or a Pair<String, Node or NodeMap>
+
+    private Node(String name) {
+      myName = name;
+    }
+
+    public String getName() {
+      return myName;
+    }
+
+    public boolean isOutputRoot() {
+      return myChildren instanceof String || myChildren instanceof Pair;
+    }
+
+    public boolean hasChildren() {
+      return myChildren instanceof Map || myChildren instanceof Pair;
+    }
+
+    @Nullable
+    public String getData() {
+      if (myChildren instanceof String) {
+        return (String)myChildren;
+      }
+      if (myChildren instanceof Pair) {
+        //noinspection unchecked
+        return (String)((Pair)myChildren).first;
+      }
+      return null;
+    }
+
+    public void setData(String path) {
+      if (myChildren != null) {
+        if (myChildren instanceof String) {
+          myChildren = path;
+        }
+        else {
+          myChildren = new Pair(path, myChildren instanceof Pair? ((Pair)myChildren).second : myChildren);
+        }
+      }
+      else {
+        myChildren = path;
+      }
+    }
+
+    public Node addChild(String childName) {
+      if (myChildren == null) {
+        final Node node = new Node(childName);
+        myChildren = node;
+        return node;
+      }
+      if (myChildren instanceof String) {
+        final Node node = new Node(childName);
+        myChildren = new Pair(myChildren, node);
+        return node;
+      }
+
+      final Map<String, Node> map;
+      if (myChildren instanceof Map) {
+        map = (Map<String, Node>)myChildren;
+      }
+      else if (myChildren instanceof Node)  {
+        final Node existingChild = (Node)myChildren;
+        myChildren = map = new HashMap<String, Node>();
+        map.put(existingChild.getName(), existingChild);
+      }
+      else { // myChildren is a Pair
+        Object children = ((Pair)myChildren).second;
+        if (children instanceof Map) {
+          map = (Map<String, Node>)children;
+        }
+        else {
+          final Node existingChild = (Node)children;
+          myChildren = new Pair(((Pair)myChildren).first, map = new HashMap<String, Node>());
+          map.put(existingChild.getName(), existingChild);
+        }
+      }
+
+      Node node = map.get(childName);
+      if (node == null) {
+        map.put(childName, node = new Node(childName));
+      }
+      return node;
+    }
+
+    @Nullable
+    public Node getChild(String childName) {
+      final Object children = myChildren instanceof Pair? ((Pair)myChildren).second : myChildren;
+      if (children instanceof Node) {
+        final Node childNode = (Node)children;
+        return childName.equals(childNode.getName())? childNode : null;
+      }
+      if (children instanceof Map) {
+        return ((Map<String, Node>)myChildren).get(childName);
+      }
+      return null;
+    }
+  }
+
+
+  public static void main(String[] args) {
+    final Set<File> set = new HashSet<File>();
+    set.add(new File("/a/b/c"));
+    set.add(new File("a/b/d"));
+    set.add(new File("a/b/e"));
+    set.add(new File("/a/b/f/g"));
+    set.add(new File("/a/b/f/g/zzz"));
+
+    final OutputPathFinder finder = new OutputPathFinder(set);
+
+    System.out.println(finder.lookupOutputPath(new File("a/b")));
+    System.out.println(finder.lookupOutputPath(new File("a/b/c/dir1/dir2/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("a/b/d/dir1/dir2/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("a/b/jjjjj/dir1/dir2/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("a/b/e/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("a/b/File.class")));
+
+    System.out.println(finder.lookupOutputPath(new File("/a/b/f/g/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("/a/b/f/g/ttt/yy/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("/a/b/f/g/zzz/File.class")));
+    System.out.println(finder.lookupOutputPath(new File("/a/b/f/g/zzz/mmm/ttt/File.class")));
+
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/PackagingCompilerAdapter.java b/java/compiler/impl/src/com/intellij/compiler/impl/PackagingCompilerAdapter.java
new file mode 100644
index 0000000..d2f7826
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/PackagingCompilerAdapter.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.compiler.impl;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.PackagingCompiler;
+import com.intellij.openapi.compiler.ValidityState;
+import org.jetbrains.annotations.Nullable;
+
+public class PackagingCompilerAdapter extends FileProcessingCompilerAdapter{
+  private final PackagingCompiler myCompiler;
+
+  public PackagingCompilerAdapter(CompileContext compileContext, PackagingCompiler compiler) {
+    super(compileContext, compiler);
+    myCompiler = compiler;
+  }
+
+  public void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state) {
+    myCompiler.processOutdatedItem(context, url, state);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
new file mode 100644
index 0000000..320898a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewImpl.java
@@ -0,0 +1,163 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.compiler.ProblemsView;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.errorTreeView.ErrorTreeElement;
+import com.intellij.ide.errorTreeView.ErrorViewStructure;
+import com.intellij.ide.errorTreeView.GroupingElement;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowAnchor;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.pom.Navigatable;
+import com.intellij.ui.content.Content;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.util.concurrency.SequentialTaskExecutor;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.UUID;
+import java.util.concurrent.Executor;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 9/18/12
+ */
+public class ProblemsViewImpl extends ProblemsView{
+  private static final String PROBLEMS_TOOLWINDOW_ID = "Problems";
+  
+  private final ProblemsViewPanel myPanel;
+  private final SequentialTaskExecutor myViewUpdater = new SequentialTaskExecutor(new Executor() {
+    @Override
+    public void execute(Runnable command) {
+      ApplicationManager.getApplication().executeOnPooledThread(command);
+    }
+  });
+
+  public ProblemsViewImpl(final Project project, final ToolWindowManager wm) {
+    super(project);
+    myPanel = new ProblemsViewPanel(project);
+    Disposer.register(project, new Disposable() {
+      @Override
+      public void dispose() {
+        Disposer.dispose(myPanel);
+      }
+    });
+    UIUtil.invokeLaterIfNeeded(new Runnable() {
+      @Override
+      public void run() {
+        if (project.isDisposed()) {
+          return;
+        }
+        final ToolWindow tw = wm.registerToolWindow(PROBLEMS_TOOLWINDOW_ID, false, ToolWindowAnchor.BOTTOM, project);
+        tw.setIcon(AllIcons.Toolwindows.Problems);
+        final Content content = ContentFactory.SERVICE.getInstance().createContent(myPanel, "", false);
+        // todo: setup content?
+        tw.getContentManager().addContent(content);
+        Disposer.register(project, new Disposable() {
+          @Override
+          public void dispose() {
+            tw.getContentManager().removeAllContents(true);
+          }
+        });
+      }
+    });
+  }
+
+  @Override
+  public void clearOldMessages(@Nullable final CompileScope scope, @NotNull final UUID currentSessionId) {
+    myViewUpdater.execute(new Runnable() {
+      @Override
+      public void run() {
+        cleanupChildrenRecursively(myPanel.getErrorViewStructure().getRootElement(), scope, currentSessionId);
+        myPanel.reload();
+      }
+    });
+  }
+
+  private void cleanupChildrenRecursively(@NotNull final Object fromElement, final @Nullable CompileScope scope, @NotNull UUID currentSessionId) {
+    final ErrorViewStructure structure = myPanel.getErrorViewStructure();
+    for (ErrorTreeElement element : structure.getChildElements(fromElement)) {
+      if (element instanceof GroupingElement) {
+        if (scope != null) {
+          final VirtualFile file = ((GroupingElement)element).getFile();
+          if (file != null && !scope.belongs(file.getUrl())) {
+            continue; 
+          }
+        }
+        if (!currentSessionId.equals(element.getData())) {
+          structure.removeElement(element);
+        }
+        else {
+          cleanupChildrenRecursively(element, scope, currentSessionId);
+        }
+      }
+      else {
+        if (!currentSessionId.equals(element.getData())) {
+          structure.removeElement(element);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void addMessage(final int type,
+                         @NotNull final String[] text,
+                         @Nullable final String groupName,
+                         @Nullable final Navigatable navigatable,
+                         @Nullable final String exportTextPrefix, @Nullable final String rendererTextPrefix, @Nullable final UUID sessionId) {
+
+    myViewUpdater.execute(new Runnable() {
+      @Override
+      public void run() {
+        final ErrorViewStructure structure = myPanel.getErrorViewStructure();
+        final GroupingElement group = structure.lookupGroupingElement(groupName);
+        if (group != null && !sessionId.equals(group.getData())) {
+          structure.removeElement(group);
+        }
+        if (navigatable != null) {
+          myPanel.addMessage(type, text, groupName, navigatable, exportTextPrefix, rendererTextPrefix, sessionId);
+        }
+        else {
+          myPanel.addMessage(type, text, null, -1, -1, sessionId);
+        }
+      }
+    });
+  }
+
+  @Override
+  public void setProgress(String text, float fraction) {
+    myPanel.setProgress(text, fraction);
+  }
+
+  @Override
+  public void setProgress(String text) {
+    myPanel.setProgressText(text);
+  }
+
+  @Override
+  public void clearProgress() {
+    myPanel.clearProgressData();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java
new file mode 100644
index 0000000..d65451e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProblemsViewPanel.java
@@ -0,0 +1,55 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
+import com.intellij.openapi.actionSystem.DefaultActionGroup;
+import com.intellij.openapi.project.Project;
+
+public class ProblemsViewPanel extends NewErrorTreeViewPanel {
+  public ProblemsViewPanel(Project project) {
+    super(project, null, false, true, null);
+    myTree.getEmptyText().setText("No compilation problems found");
+  }
+
+
+  protected void fillRightToolbarGroup(DefaultActionGroup group) {
+    super.fillRightToolbarGroup(group);
+    group.add(new CompilerPropertiesAction());
+  }
+
+  protected void addExtraPopupMenuActions(DefaultActionGroup group) {
+    group.add(new ExcludeFromCompileAction(myProject, this));
+    // todo: do we need compiler's popup actions here?
+    //ActionGroup popupGroup = (ActionGroup)ActionManager.getInstance().getAction(IdeActions.GROUP_COMPILER_ERROR_VIEW_POPUP);
+    //if (popupGroup != null) {
+    //  for (AnAction action : popupGroup.getChildren(null)) {
+    //    group.add(action);
+    //  }
+    //}
+  }
+
+  @Override
+  protected boolean shouldShowFirstErrorInEditor() {
+    return false;
+  }
+
+  @Override
+  protected boolean canHideWarnings() {
+    return false;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/ProjectCompileScope.java b/java/compiler/impl/src/com/intellij/compiler/impl/ProjectCompileScope.java
new file mode 100644
index 0000000..ed41606
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/ProjectCompileScope.java
@@ -0,0 +1,71 @@
+/*
+ * 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: Jan 20, 2003
+ * Time: 5:34:19 PM
+ */
+package com.intellij.compiler.impl;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.FileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.annotations.NotNull;
+
+public class ProjectCompileScope extends FileIndexCompileScope {
+  private final Project myProject;
+
+  public ProjectCompileScope(final Project project) {
+    myProject = project;
+  }
+
+  protected FileIndex[] getFileIndices() {
+    return new FileIndex[] {ProjectRootManager.getInstance(myProject).getFileIndex()};
+  }
+
+  public boolean belongs(String url) {
+    final VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
+    if (file != null) {
+      for (FileIndex index : getFileIndices()) {
+        if (index.isInSourceContent(file)) {
+          return true;
+        }
+      }
+    }
+    else {
+      // the file might be deleted
+      for (VirtualFile root : ProjectRootManager.getInstance(myProject).getContentSourceRoots()) {
+        final String rootUrl = root.getUrl();
+        if (FileUtil.startsWith(url, rootUrl.endsWith("/")? rootUrl : rootUrl + "/")) {
+          return true;
+        }
+      }
+    }
+    return false;
+    //return !FileUtil.startsWith(url, myTempDirUrl);
+  }
+
+  @NotNull
+  public Module[] getAffectedModules() {
+    return ModuleManager.getInstance(myProject).getModules();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/SourceUrlClassNamePair.java b/java/compiler/impl/src/com/intellij/compiler/impl/SourceUrlClassNamePair.java
new file mode 100644
index 0000000..6d9a60d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/SourceUrlClassNamePair.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.compiler.impl;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jun 21, 2006
+ */
+public class SourceUrlClassNamePair {
+  private final String mySourceUrl;
+  private final @Nullable String myClassName;
+
+  public SourceUrlClassNamePair(String url, @Nullable String className) {
+    mySourceUrl = url;
+    myClassName = className;
+  }
+
+  public String getSourceUrl() {
+    return mySourceUrl;
+  }
+
+  public @Nullable String getClassName() {
+    return myClassName;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java
new file mode 100644
index 0000000..bd56b66
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/StateCache.java
@@ -0,0 +1,105 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.EnumeratorStringDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.Iterator;
+
+public abstract class StateCache<T> {
+  private PersistentHashMap<String, T> myMap;
+  private final File myBaseFile;
+
+  public StateCache(@NonNls File storePath) throws IOException {
+    myBaseFile = storePath;
+    myMap = createMap(storePath);
+  }
+
+  protected abstract T read(DataInput stream) throws IOException;
+
+  protected abstract void write(T t, DataOutput out) throws IOException;
+
+  public void force() {
+    myMap.force();
+  }
+  
+  public void close() throws IOException {
+    myMap.close();
+  }
+  
+  public boolean wipe() {
+    try {
+      myMap.close();
+    }
+    catch (IOException ignored) {
+    }
+    PersistentHashMap.deleteFilesStartingWith(myBaseFile);
+    try {
+      myMap = createMap(myBaseFile);
+    }
+    catch (IOException ignored) {
+      return false;
+    }
+    return true;
+  }
+
+  public void update(@NonNls String url, T state) throws IOException {
+    if (state != null) {
+      myMap.put(url, state);
+    }
+    else {
+      remove(url);
+    }
+  }
+
+  public void remove(String url) throws IOException {
+    myMap.remove(url);
+  }
+
+  public T getState(String url) throws IOException {
+    return myMap.get(url);
+  }
+
+  public Collection<String> getUrls() throws IOException {
+    return myMap.getAllKeysWithExistingMapping();
+  }
+
+  public Iterator<String> getUrlsIterator() throws IOException {
+    return myMap.getAllKeysWithExistingMapping().iterator();
+  }
+
+
+  private PersistentHashMap<String, T> createMap(final File file) throws IOException {
+    return new PersistentHashMap<String,T>(file, new EnumeratorStringDescriptor(), new DataExternalizer<T>() {
+      public void save(final DataOutput out, final T value) throws IOException {
+        StateCache.this.write(value, out);
+      }
+
+      public T read(final DataInput in) throws IOException {
+        return StateCache.this.read(in);
+      }
+    });
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
new file mode 100644
index 0000000..8ba9de9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TranslatingCompilerFilesMonitor.java
@@ -0,0 +1,1920 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.ProjectTopics;
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerIOUtil;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.make.MakeUtil;
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.*;
+import com.intellij.openapi.vfs.newvfs.FileAttribute;
+import com.intellij.openapi.vfs.newvfs.ManagingFS;
+import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.openapi.vfs.newvfs.persistent.FSRecords;
+import com.intellij.openapi.vfs.newvfs.persistent.PersistentFS;
+import com.intellij.util.Alarm;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.SLRUCache;
+import com.intellij.util.indexing.FileBasedIndex;
+import com.intellij.util.indexing.IndexInfrastructure;
+import com.intellij.util.io.*;
+import com.intellij.util.io.DataOutputStream;
+import com.intellij.util.messages.MessageBusConnection;
+import gnu.trove.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.*;
+import java.util.*;
+import java.util.concurrent.atomic.AtomicInteger;
+
+/**
+ * @author Eugene Zhuravlev
+ * @since Jun 3, 2008
+ *
+ * A source file is scheduled for recompilation if
+ * 1. its timestamp has changed
+ * 2. one of its corresponding output files was deleted
+ * 3. output root of containing module has changed
+ *
+ * An output file is scheduled for deletion if:
+ * 1. corresponding source file has been scheduled for recompilation (see above)
+ * 2. corresponding source file has been deleted
+ */
+public class TranslatingCompilerFilesMonitor implements ApplicationComponent {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.TranslatingCompilerFilesMonitor");
+  private static final boolean ourDebugMode = false;
+
+  private static final FileAttribute ourSourceFileAttribute = new FileAttribute("_make_source_file_info_", 3);
+  private static final FileAttribute ourOutputFileAttribute = new FileAttribute("_make_output_file_info_", 3);
+  private static final Key<Map<String, VirtualFile>> SOURCE_FILES_CACHE = Key.create("_source_url_to_vfile_cache_");
+
+  private final Object myDataLock = new Object();
+
+  private final TIntHashSet mySuspendedProjects = new TIntHashSet(); // projectId for all projects that should not be monitored
+
+  private final TIntObjectHashMap<TIntHashSet> mySourcesToRecompile = new TIntObjectHashMap<TIntHashSet>(); // ProjectId->set of source file paths
+  private PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> myOutputRootsStorage; // ProjectId->map[moduleId->Pair(outputDirId, testOutputDirId)]
+  
+  // Map: projectId -> Map{output path -> [sourceUrl; className]}
+  private final SLRUCache<Integer, Outputs> myOutputsToDelete = new SLRUCache<Integer, Outputs>(3, 3) {
+    @Override
+    public Outputs getIfCached(Integer key) {
+      final Outputs value = super.getIfCached(key);
+      if (value != null) {
+        value.allocate();
+      }
+      return value;
+    }
+
+    @NotNull
+    @Override
+    public Outputs get(Integer key) {
+      final Outputs value = super.get(key);
+      value.allocate();
+      return value;
+    }
+
+    @NotNull
+    @Override
+    public Outputs createValue(Integer key) {
+      try {
+        final String dirName = FSRecords.getNames().valueOf(key);
+        final File storeFile;
+        if (StringUtil.isEmpty(dirName)) {
+          storeFile = null;
+        }
+        else {
+          final File compilerCacheDir = CompilerPaths.getCacheStoreDirectory(dirName);
+          storeFile = compilerCacheDir.exists()? new File(compilerCacheDir, "paths_to_delete.dat") : null;
+        }
+        return new Outputs(storeFile, loadPathsToDelete(storeFile));
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        return new Outputs(null, new HashMap<String, SourceUrlClassNamePair>());
+      }
+    }
+
+    @Override
+    protected void onDropFromCache(Integer key, Outputs value) {
+      value.release();
+    }
+  };
+  private final SLRUCache<Project, File> myGeneratedDataPaths = new SLRUCache<Project, File>(8, 8) {
+    @NotNull
+    public File createValue(final Project project) {
+      Disposer.register(project, new Disposable() {
+        public void dispose() {
+          myGeneratedDataPaths.remove(project);
+        }
+      });
+      return CompilerPaths.getGeneratedDataDirectory(project);
+    }
+  };
+  private final SLRUCache<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> myProjectOutputRoots = new SLRUCache<Integer, TIntObjectHashMap<Pair<Integer, Integer>>>(2, 2) {
+    protected void onDropFromCache(Integer key, TIntObjectHashMap<Pair<Integer, Integer>> value) {
+      try {
+        myOutputRootsStorage.put(key, value);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+    }
+
+    @NotNull
+    public TIntObjectHashMap<Pair<Integer, Integer>> createValue(Integer key) {
+      TIntObjectHashMap<Pair<Integer, Integer>> map = null;
+      try {
+        ensureOutputStorageInitialized();
+        map = myOutputRootsStorage.get(key);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+      return map != null? map : new TIntObjectHashMap<Pair<Integer, Integer>>();
+    }
+  };
+  private final ProjectManager myProjectManager;
+  private final TIntIntHashMap myInitInProgress = new TIntIntHashMap(); // projectId for successfully initialized projects
+  private final Object myAsyncScanLock = new Object();
+
+  public TranslatingCompilerFilesMonitor(VirtualFileManager vfsManager, ProjectManager projectManager, Application application) {
+    myProjectManager = projectManager;
+
+    projectManager.addProjectManagerListener(new MyProjectManagerListener());
+    vfsManager.addVirtualFileListener(new MyVfsListener(), application);
+  }
+
+  public static TranslatingCompilerFilesMonitor getInstance() {
+    return ApplicationManager.getApplication().getComponent(TranslatingCompilerFilesMonitor.class);
+  }
+
+  public void suspendProject(Project project) {
+    final int projectId = getProjectId(project);
+
+    synchronized (myDataLock) {
+      if (!mySuspendedProjects.add(projectId)) {
+        return;
+      }
+      FileUtil.createIfDoesntExist(CompilerPaths.getRebuildMarkerFile(project));
+      // cleanup internal structures to free memory
+      mySourcesToRecompile.remove(projectId);
+      myOutputsToDelete.remove(projectId);
+      myGeneratedDataPaths.remove(project);
+    }
+
+    synchronized (myProjectOutputRoots) {
+      ensureOutputStorageInitialized();
+      myProjectOutputRoots.remove(projectId);
+      try {
+        myOutputRootsStorage.remove(projectId);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+    }
+  }
+
+  public void watchProject(Project project) {
+    synchronized (myDataLock) {
+      mySuspendedProjects.remove(getProjectId(project));
+    }
+  }
+
+  public boolean isSuspended(Project project) {
+    return isSuspended(getProjectId(project));
+  }
+
+  public boolean isSuspended(int projectId) {
+    synchronized (myDataLock) {
+      return mySuspendedProjects.contains(projectId);
+    }
+  }
+
+  @Nullable
+  public static VirtualFile getSourceFileByOutput(VirtualFile outputFile) {
+    final OutputFileInfo outputFileInfo = loadOutputInfo(outputFile);
+    if (outputFileInfo != null) {
+      final String path = outputFileInfo.getSourceFilePath();
+      if (path != null) {
+        return LocalFileSystem.getInstance().findFileByPath(path);
+      }
+    }
+    return null;
+  }
+
+  public void collectFiles(CompileContext context, final TranslatingCompiler compiler, Iterator<VirtualFile> scopeSrcIterator, boolean forceCompile,
+                           final boolean isRebuild,
+                           Collection<VirtualFile> toCompile,
+                           Collection<Trinity<File, String, Boolean>> toDelete) {
+    final Project project = context.getProject();
+    final int projectId = getProjectId(project);
+    final CompilerConfiguration configuration = CompilerConfiguration.getInstance(project);
+    final boolean _forceCompile = forceCompile || isRebuild;
+    final Set<VirtualFile> selectedForRecompilation = new HashSet<VirtualFile>();
+    synchronized (myDataLock) {
+      final TIntHashSet pathsToRecompile = mySourcesToRecompile.get(projectId);
+      if (_forceCompile || pathsToRecompile != null && !pathsToRecompile.isEmpty()) {
+        if (ourDebugMode) {
+          System.out.println("Analysing potentially recompilable files for " + compiler.getDescription());
+        }
+        while (scopeSrcIterator.hasNext()) {
+          final VirtualFile file = scopeSrcIterator.next();
+          if (!file.isValid()) {
+            if (LOG.isDebugEnabled() || ourDebugMode) {
+              LOG.debug("Skipping invalid file " + file.getPresentableUrl());
+              if (ourDebugMode) {
+                System.out.println("\t SKIPPED(INVALID) " + file.getPresentableUrl());
+              }
+            }
+            continue;
+          }
+          final int fileId = getFileId(file);
+          if (_forceCompile) {
+            if (compiler.isCompilableFile(file, context) && !configuration.isExcludedFromCompilation(file)) {
+              toCompile.add(file);
+              if (ourDebugMode) {
+                System.out.println("\t INCLUDED " + file.getPresentableUrl());
+              }
+              selectedForRecompilation.add(file);
+              if (pathsToRecompile == null || !pathsToRecompile.contains(fileId)) {
+                loadInfoAndAddSourceForRecompilation(projectId, file);
+              }
+            }
+            else {
+              if (ourDebugMode) {
+                System.out.println("\t NOT COMPILABLE OR EXCLUDED " + file.getPresentableUrl());
+              }
+            }
+          }
+          else if (pathsToRecompile.contains(fileId)) {
+            if (compiler.isCompilableFile(file, context) && !configuration.isExcludedFromCompilation(file)) {
+              toCompile.add(file);
+              if (ourDebugMode) {
+                System.out.println("\t INCLUDED " + file.getPresentableUrl());
+              }
+              selectedForRecompilation.add(file);
+            }
+            else {
+              if (ourDebugMode) {
+                System.out.println("\t NOT COMPILABLE OR EXCLUDED " + file.getPresentableUrl());
+              }
+            }
+          }
+          else {
+            if (ourDebugMode) {
+              System.out.println("\t NOT INCLUDED " + file.getPresentableUrl());
+            }
+          }
+        }
+      }
+      // it is important that files to delete are collected after the files to compile (see what happens if forceCompile == true)
+      if (!isRebuild) {
+        final Outputs outputs = myOutputsToDelete.get(projectId);
+        try {
+          final VirtualFileManager vfm = VirtualFileManager.getInstance();
+          final LocalFileSystem lfs = LocalFileSystem.getInstance();
+          final List<String> zombieEntries = new ArrayList<String>();
+          final Map<String, VirtualFile> srcFileCache = getFileCache(context);
+          for (Map.Entry<String, SourceUrlClassNamePair> entry : outputs.getEntries()) {
+            final String outputPath = entry.getKey();
+            final SourceUrlClassNamePair classNamePair = entry.getValue();
+            final String sourceUrl = classNamePair.getSourceUrl();
+
+            final VirtualFile srcFile;
+            if (srcFileCache.containsKey(sourceUrl)) {
+              srcFile = srcFileCache.get(sourceUrl);
+            }
+            else {
+              srcFile = vfm.findFileByUrl(sourceUrl);
+              srcFileCache.put(sourceUrl, srcFile);
+            }
+
+            final boolean sourcePresent = srcFile != null;
+            if (sourcePresent) {
+              if (!compiler.isCompilableFile(srcFile, context)) {
+                continue; // do not collect files that were compiled by another compiler
+              }
+              if (!selectedForRecompilation.contains(srcFile)) {
+                if (!isMarkedForRecompilation(projectId, getFileId(srcFile))) {
+                  if (LOG.isDebugEnabled() || ourDebugMode) {
+                    final String message = "Found zombie entry (output is marked, but source is present and up-to-date): " + outputPath;
+                    LOG.debug(message);
+                    if (ourDebugMode) {
+                      System.out.println(message);
+                    }
+                  }
+                  zombieEntries.add(outputPath);
+                }
+                continue;
+              }
+            }
+            if (lfs.findFileByPath(outputPath) != null) {
+              //noinspection UnnecessaryBoxing
+              final File file = new File(outputPath);
+              toDelete.add(new Trinity<File, String, Boolean>(file, classNamePair.getClassName(), Boolean.valueOf(sourcePresent)));
+              if (LOG.isDebugEnabled() || ourDebugMode) {
+                final String message = "Found file to delete: " + file;
+                LOG.debug(message);
+                if (ourDebugMode) {
+                  System.out.println(message);
+                }
+              }
+            }
+            else {
+              if (LOG.isDebugEnabled() || ourDebugMode) {
+                final String message = "Found zombie entry marked for deletion: " + outputPath;
+                LOG.debug(message);
+                if (ourDebugMode) {
+                  System.out.println(message);
+                }
+              }
+              // must be gagbage entry, should cleanup
+              zombieEntries.add(outputPath);
+            }
+          }
+          for (String path : zombieEntries) {
+            unmarkOutputPathForDeletion(projectId, path);
+          }
+        }
+        finally {
+          outputs.release();
+        }
+      }
+    }
+  }
+
+  private static Map<String, VirtualFile> getFileCache(CompileContext context) {
+    Map<String, VirtualFile> cache = context.getUserData(SOURCE_FILES_CACHE);
+    if (cache == null) {
+      context.putUserData(SOURCE_FILES_CACHE, cache = new HashMap<String, VirtualFile>());
+    }
+    return cache;
+  }
+
+  private static int getFileId(final VirtualFile file) {
+    return FileBasedIndex.getFileId(file);
+  }
+
+  private static VirtualFile findFileById(int id) {
+    return IndexInfrastructure.findFileById((PersistentFS)ManagingFS.getInstance(), id);
+  }
+
+  public void update(final CompileContext context, @Nullable final String outputRoot, final Collection<TranslatingCompiler.OutputItem> successfullyCompiled, final VirtualFile[] filesToRecompile)
+      throws IOException {
+    final Project project = context.getProject();
+    final int projectId = getProjectId(project);
+    if (!successfullyCompiled.isEmpty()) {
+      final LocalFileSystem lfs = LocalFileSystem.getInstance();
+      final IOException[] exceptions = {null};
+      // need read action here to ensure that no modifications were made to VFS while updating file attributes
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          try {
+            final Map<VirtualFile, SourceFileInfo> compiledSources = new HashMap<VirtualFile, SourceFileInfo>();
+            final Set<VirtualFile> forceRecompile = new HashSet<VirtualFile>();
+
+            for (TranslatingCompiler.OutputItem item : successfullyCompiled) {
+              final VirtualFile sourceFile = item.getSourceFile();
+              final boolean isSourceValid = sourceFile.isValid();
+              SourceFileInfo srcInfo = compiledSources.get(sourceFile);
+              if (isSourceValid && srcInfo == null) {
+                srcInfo = loadSourceInfo(sourceFile);
+                if (srcInfo != null) {
+                  srcInfo.clearPaths(projectId);
+                }
+                else {
+                  srcInfo = new SourceFileInfo();
+                }
+                compiledSources.put(sourceFile, srcInfo);
+              }
+
+              final String outputPath = item.getOutputPath();
+              if (outputPath != null) { // can be null for packageinfo
+                final VirtualFile outputFile = lfs.findFileByPath(outputPath);
+
+                //assert outputFile != null : "Virtual file was not found for \"" + outputPath + "\"";
+
+                if (outputFile != null) {
+                  if (!sourceFile.equals(outputFile)) {
+                    final String className = outputRoot == null? null : MakeUtil.relativeClassPathToQName(outputPath.substring(outputRoot.length()), '/');
+                    if (isSourceValid) {
+                      srcInfo.addOutputPath(projectId, outputPath);
+                      saveOutputInfo(outputFile, new OutputFileInfo(sourceFile.getPath(), className));
+                    }
+                    else {
+                      markOutputPathForDeletion(projectId, outputPath, className, sourceFile.getUrl());
+                    }
+                  }
+                }
+                else {  // output file was not found
+                  LOG.warn("TranslatingCompilerFilesMonitor.update():  Virtual file was not found for \"" + outputPath + "\"");
+                  if (isSourceValid) {
+                    forceRecompile.add(sourceFile);
+                  }
+                }
+              }
+            }
+            final long compilationStartStamp = ((CompileContextEx)context).getStartCompilationStamp();
+            for (Map.Entry<VirtualFile, SourceFileInfo> entry : compiledSources.entrySet()) {
+              final SourceFileInfo info = entry.getValue();
+              final VirtualFile file = entry.getKey();
+
+              final long fileStamp = file.getTimeStamp();
+              info.updateTimestamp(projectId, fileStamp);
+              saveSourceInfo(file, info);
+              if (LOG.isDebugEnabled() || ourDebugMode) {
+                final String message = "Unschedule recompilation (successfully compiled) " + file.getPresentableUrl();
+                LOG.debug(message);
+                if (ourDebugMode) {
+                  System.out.println(message);
+                }
+              }
+              removeSourceForRecompilation(projectId, Math.abs(getFileId(file)));
+              if (fileStamp > compilationStartStamp && !((CompileContextEx)context).isGenerated(file) || forceRecompile.contains(file)) {
+                // changes were made during compilation, need to re-schedule compilation
+                // it is important to invoke removeSourceForRecompilation() before this call to make sure
+                // the corresponding output paths will be scheduled for deletion
+                addSourceForRecompilation(projectId, file, info);
+              }
+            }
+          }
+          catch (IOException e) {
+            exceptions[0] = e;
+          }
+        }
+      });
+      if (exceptions[0] != null) {
+        throw exceptions[0];
+      }
+    }
+    
+    if (filesToRecompile.length > 0) {
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          for (VirtualFile file : filesToRecompile) {
+            if (file.isValid()) {
+              loadInfoAndAddSourceForRecompilation(projectId, file);
+            }
+          }
+        }
+      });
+    }
+  }
+
+  public void updateOutputRootsLayout(Project project) {
+    final TIntObjectHashMap<Pair<Integer, Integer>> map = buildOutputRootsLayout(new ProjectRef(project));
+    final int projectId = getProjectId(project);
+    synchronized (myProjectOutputRoots) {
+      myProjectOutputRoots.put(projectId, map);
+    }
+  }
+
+  @NotNull
+  public String getComponentName() {
+    return "TranslatingCompilerFilesMonitor";
+  }
+
+  public void initComponent() {
+    ensureOutputStorageInitialized();
+  }
+
+  private static File getOutputRootsFile() {
+    return new File(CompilerPaths.getCompilerSystemDirectory(), "output_roots.dat");
+  }
+
+  private static void deleteStorageFiles(File tableFile) {
+    final File[] files = tableFile.getParentFile().listFiles();
+    if (files != null) {
+      final String name = tableFile.getName();
+      for (File file : files) {
+        if (file.getName().startsWith(name)) {
+          FileUtil.delete(file);
+        }
+      }
+    }
+  }
+
+  private static Map<String, SourceUrlClassNamePair> loadPathsToDelete(@Nullable final File file) {
+    final Map<String, SourceUrlClassNamePair> map = new HashMap<String, SourceUrlClassNamePair>();
+    try {
+      if (file != null && file.length() > 0) {
+        final DataInputStream is = new DataInputStream(new BufferedInputStream(new FileInputStream(file)));
+        try {
+          final int size = is.readInt();
+          for (int i = 0; i < size; i++) {
+            final String _outputPath = CompilerIOUtil.readString(is);
+            final String srcUrl = CompilerIOUtil.readString(is);
+            final String className = CompilerIOUtil.readString(is);
+            map.put(FileUtil.toSystemIndependentName(_outputPath), new SourceUrlClassNamePair(srcUrl, className));
+          }
+        }
+        finally {
+          is.close();
+        }
+      }
+    }
+    catch (FileNotFoundException ignored) {
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    return map;
+  }
+
+  private void ensureOutputStorageInitialized() {
+    if (myOutputRootsStorage != null) {
+      return;
+    }
+    final File rootsFile = getOutputRootsFile();
+    try {
+      initOutputRootsFile(rootsFile);
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      deleteStorageFiles(rootsFile);
+      try {
+        initOutputRootsFile(rootsFile);
+      }
+      catch (IOException e1) {
+        LOG.error(e1);
+      }
+    }
+  }
+
+  private TIntObjectHashMap<Pair<Integer, Integer>> buildOutputRootsLayout(ProjectRef projRef) {
+    final TIntObjectHashMap<Pair<Integer, Integer>> map = new TIntObjectHashMap<Pair<Integer, Integer>>();
+    for (Module module : ModuleManager.getInstance(projRef.get()).getModules()) {
+      final CompilerModuleExtension manager = CompilerModuleExtension.getInstance(module);
+      if (manager != null) {
+        final VirtualFile output = manager.getCompilerOutputPath();
+        final int first = output != null? Math.abs(getFileId(output)) : -1;
+        final VirtualFile testsOutput = manager.getCompilerOutputPathForTests();
+        final int second = testsOutput != null? Math.abs(getFileId(testsOutput)) : -1;
+        map.put(getModuleId(module), new Pair<Integer, Integer>(first, second));
+      }
+    }
+    return map;
+  }
+
+  private void initOutputRootsFile(File rootsFile) throws IOException {
+    myOutputRootsStorage = new PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>>(rootsFile, EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<TIntObjectHashMap<Pair<Integer, Integer>>>() {
+      public void save(DataOutput out, TIntObjectHashMap<Pair<Integer, Integer>> value) throws IOException {
+        for (final TIntObjectIterator<Pair<Integer, Integer>> it = value.iterator(); it.hasNext();) {
+          it.advance();
+          DataInputOutputUtil.writeINT(out, it.key());
+          final Pair<Integer, Integer> pair = it.value();
+          DataInputOutputUtil.writeINT(out, pair.first);
+          DataInputOutputUtil.writeINT(out, pair.second);
+        }
+      }
+
+      public TIntObjectHashMap<Pair<Integer, Integer>> read(DataInput in) throws IOException {
+        final DataInputStream _in = (DataInputStream)in;
+        final TIntObjectHashMap<Pair<Integer, Integer>> map = new TIntObjectHashMap<Pair<Integer, Integer>>();
+        while (_in.available() > 0) {
+          final int key = DataInputOutputUtil.readINT(_in);
+          final int first = DataInputOutputUtil.readINT(_in);
+          final int second = DataInputOutputUtil.readINT(_in);
+          map.put(key, new Pair<Integer, Integer>(first, second));
+        }
+        return map;
+      }
+    });
+  }
+
+  public void disposeComponent() {
+    try {
+      synchronized (myProjectOutputRoots) {
+        myProjectOutputRoots.clear();
+      }
+    }
+    finally {
+      synchronized (myDataLock) {
+        myOutputsToDelete.clear();
+      }
+    }
+    
+    try {
+      final PersistentHashMap<Integer, TIntObjectHashMap<Pair<Integer, Integer>>> storage = myOutputRootsStorage;
+      if (storage != null) {
+        storage.close();
+      }
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      deleteStorageFiles(getOutputRootsFile());
+    }
+  }
+
+  private static void savePathsToDelete(final File file, final Map<String, SourceUrlClassNamePair> outputs) {
+    try {
+      FileUtil.createParentDirs(file);
+      final DataOutputStream os = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(file)));
+      try {
+        if (outputs != null) {
+          os.writeInt(outputs.size());
+          for (Map.Entry<String, SourceUrlClassNamePair> entry : outputs.entrySet()) {
+            CompilerIOUtil.writeString(entry.getKey(), os);
+            final SourceUrlClassNamePair pair = entry.getValue();
+            CompilerIOUtil.writeString(pair.getSourceUrl(), os);
+            CompilerIOUtil.writeString(pair.getClassName(), os);
+          }
+        }
+        else {
+          os.writeInt(0);
+        }
+      }
+      finally {
+        os.close();
+      }
+    }
+    catch (IOException e) {
+      LOG.error(e);
+    }
+  }
+
+  @Nullable
+  private static SourceFileInfo loadSourceInfo(final VirtualFile file) {
+    try {
+      final DataInputStream is = ourSourceFileAttribute.readAttribute(file);
+      if (is != null) {
+        try {
+          return new SourceFileInfo(is);
+        }
+        finally {
+          is.close();
+        }
+      }
+    }
+    catch (RuntimeException e) {
+      final Throwable cause = e.getCause();
+      if (cause instanceof IOException) {
+        LOG.info(e); // ignore IOExceptions
+      }
+      else {
+        throw e;
+      }
+    }
+    catch (IOException ignored) {
+      LOG.info(ignored);
+    }
+    return null;
+  }
+
+  public static void removeSourceInfo(VirtualFile file) {
+    saveSourceInfo(file, new SourceFileInfo());
+  }
+
+  private static void saveSourceInfo(VirtualFile file, SourceFileInfo descriptor) {
+    final java.io.DataOutputStream out = ourSourceFileAttribute.writeAttribute(file);
+    try {
+      try {
+        descriptor.save(out);
+      }
+      finally {
+        out.close();
+      }
+    }
+    catch (IOException ignored) {
+      LOG.info(ignored);
+    }
+  }
+
+  @Nullable
+  private static OutputFileInfo loadOutputInfo(final VirtualFile file) {
+    try {
+      final DataInputStream is = ourOutputFileAttribute.readAttribute(file);
+      if (is != null) {
+        try {
+          return new OutputFileInfo(is);
+        }
+        finally {
+          is.close();
+        }
+      }
+    }
+    catch (RuntimeException e) {
+      final Throwable cause = e.getCause();
+      if (cause instanceof IOException) {
+        LOG.info(e); // ignore IO exceptions
+      }
+      else {
+        throw e;
+      }
+    }
+    catch (IOException ignored) {
+      LOG.info(ignored);
+    }
+    return null;
+  }
+
+  private static void saveOutputInfo(VirtualFile file, OutputFileInfo descriptor) {
+    final java.io.DataOutputStream out = ourOutputFileAttribute.writeAttribute(file);
+    try {
+      try {
+        descriptor.save(out);
+      }
+      finally {
+        out.close();
+      }
+    }
+    catch (IOException ignored) {
+      LOG.info(ignored);
+    }
+  }
+
+  private int getProjectId(Project project) {
+    try {
+      return FSRecords.getNames().enumerate(CompilerPaths.getCompilerSystemDirectoryName(project));
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    return -1;
+  }
+
+  private int getModuleId(Module module) {
+    try {
+      return FSRecords.getNames().enumerate(module.getName().toLowerCase(Locale.US));
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    return -1;
+  }
+
+  private static class OutputFileInfo {
+    private final int mySourcePath;
+
+    private final int myClassName;
+
+    OutputFileInfo(final String sourcePath, @Nullable String className) throws IOException {
+      final PersistentStringEnumerator symtable = FSRecords.getNames();
+      mySourcePath = symtable.enumerate(sourcePath);
+      myClassName = className != null? symtable.enumerate(className) : -1;
+    }
+
+    OutputFileInfo(final DataInput in) throws IOException {
+      mySourcePath = in.readInt();
+      myClassName = in.readInt();
+    }
+
+    String getSourceFilePath() {
+      try {
+        return FSRecords.getNames().valueOf(mySourcePath);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+      return null;
+    }
+
+    @Nullable
+    public String getClassName() {
+      try {
+        return myClassName < 0? null : FSRecords.getNames().valueOf(myClassName);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+      return null;
+    }
+
+    public void save(final DataOutput out) throws IOException {
+      out.writeInt(mySourcePath);
+      out.writeInt(myClassName);
+    }
+  }
+
+  private static class SourceFileInfo {
+    private TIntLongHashMap myTimestamps; // ProjectId -> last compiled stamp
+    private TIntObjectHashMap<Serializable> myProjectToOutputPathMap; // ProjectId -> either a single output path or a set of output paths
+
+    private SourceFileInfo() {
+    }
+
+    private SourceFileInfo(@NotNull DataInput in) throws IOException {
+      final int projCount = DataInputOutputUtil.readINT(in);
+      for (int idx = 0; idx < projCount; idx++) {
+        final int projectId = DataInputOutputUtil.readINT(in);
+        final long stamp = DataInputOutputUtil.readTIME(in);
+        updateTimestamp(projectId, stamp);
+
+        final int pathsCount = DataInputOutputUtil.readINT(in);
+        for (int i = 0; i < pathsCount; i++) {
+          final int path = in.readInt();
+          addOutputPath(projectId, path);
+        }
+      }
+    }
+
+    public void save(@NotNull final DataOutput out) throws IOException {
+      final int[] projects = getProjectIds().toArray();
+      DataInputOutputUtil.writeINT(out, projects.length);
+      for (int projectId : projects) {
+        DataInputOutputUtil.writeINT(out, projectId);
+        DataInputOutputUtil.writeTIME(out, getTimestamp(projectId));
+        final Object value = myProjectToOutputPathMap != null? myProjectToOutputPathMap.get(projectId) : null;
+        if (value instanceof Integer) {
+          DataInputOutputUtil.writeINT(out, 1);
+          out.writeInt(((Integer)value).intValue());
+        }
+        else if (value instanceof TIntHashSet) {
+          final TIntHashSet set = (TIntHashSet)value;
+          DataInputOutputUtil.writeINT(out, set.size());
+          final IOException[] ex = new IOException[] {null};
+          set.forEach(new TIntProcedure() {
+            public boolean execute(final int value) {
+              try {
+                out.writeInt(value);
+                return true;
+              }
+              catch (IOException e) {
+                ex[0] = e;
+                return false;
+              }
+            }
+          });
+          if (ex[0] != null) {
+            throw ex[0];
+          }
+        }
+        else {
+          DataInputOutputUtil.writeINT(out, 0);
+        }
+      }
+    }
+
+    private void updateTimestamp(final int projectId, final long stamp) {
+      if (stamp > 0L) {
+        if (myTimestamps == null) {
+          myTimestamps = new TIntLongHashMap(1, 0.98f);
+        }
+        myTimestamps.put(projectId, stamp);
+      }
+      else {
+        if (myTimestamps != null) {
+          myTimestamps.remove(projectId);
+        }
+      }
+    }
+
+    TIntHashSet getProjectIds() {
+      final TIntHashSet result = new TIntHashSet();
+      if (myTimestamps != null) {
+        result.addAll(myTimestamps.keys());
+      }
+      if (myProjectToOutputPathMap != null) {
+        result.addAll(myProjectToOutputPathMap.keys());
+      }
+      return result;
+    }
+
+    private void addOutputPath(final int projectId, String outputPath) {
+      try {
+        addOutputPath(projectId, FSRecords.getNames().enumerate(outputPath));
+      }
+      catch (IOException e) {
+        LOG.info(e);
+      }
+    }
+
+    private void addOutputPath(final int projectId, final int outputPath) {
+      if (myProjectToOutputPathMap == null) {
+        myProjectToOutputPathMap = new TIntObjectHashMap<Serializable>(1, 0.98f);
+        myProjectToOutputPathMap.put(projectId, outputPath);
+      }
+      else {
+        final Object val = myProjectToOutputPathMap.get(projectId);
+        if (val == null)  {
+          myProjectToOutputPathMap.put(projectId, outputPath);
+        }
+        else {
+          TIntHashSet set;
+          if (val instanceof Integer)  {
+            set = new TIntHashSet();
+            set.add(((Integer)val).intValue());
+            myProjectToOutputPathMap.put(projectId, set);
+          }
+          else {
+            assert val instanceof TIntHashSet;
+            set = (TIntHashSet)val;
+          }
+          set.add(outputPath);
+        }
+      }
+    }
+
+    public boolean clearPaths(final int projectId){
+      if (myProjectToOutputPathMap != null) {
+        final Serializable removed = myProjectToOutputPathMap.remove(projectId);
+        return removed != null;
+      }
+      return false;
+    }
+
+    long getTimestamp(final int projectId) {
+      return myTimestamps == null? -1L : myTimestamps.get(projectId);
+    }
+
+    void processOutputPaths(final int projectId, final Proc proc){
+      if (myProjectToOutputPathMap != null) {
+        try {
+          final PersistentStringEnumerator symtable = FSRecords.getNames();
+          final Object val = myProjectToOutputPathMap.get(projectId);
+          if (val instanceof Integer)  {
+            proc.execute(projectId, symtable.valueOf(((Integer)val).intValue()));
+          }
+          else if (val instanceof TIntHashSet) {
+            ((TIntHashSet)val).forEach(new TIntProcedure() {
+              public boolean execute(final int value) {
+                try {
+                  proc.execute(projectId, symtable.valueOf(value));
+                  return true;
+                }
+                catch (IOException e) {
+                  LOG.info(e);
+                  return false;
+                }
+              }
+            });
+          }
+        }
+        catch (IOException e) {
+          LOG.info(e);
+        }
+      }
+    }
+
+    boolean isAssociated(int projectId, String outputPath) {
+      if (myProjectToOutputPathMap != null) {
+        try {
+          final Object val = myProjectToOutputPathMap.get(projectId);
+          if (val instanceof Integer)  {
+            return FileUtil.pathsEqual(outputPath, FSRecords.getNames().valueOf(((Integer)val).intValue()));
+          }
+          if (val instanceof TIntHashSet) {
+            final int _outputPath = FSRecords.getNames().enumerate(outputPath);
+            return ((TIntHashSet)val).contains(_outputPath);
+          }
+        }
+        catch (IOException e) {
+          LOG.info(e);
+        }
+      }
+      return false;
+    }
+  }
+
+  public List<String> getCompiledClassNames(VirtualFile srcFile, Project project) {
+    final SourceFileInfo info = loadSourceInfo(srcFile);
+    if (info == null) {
+      return Collections.emptyList();
+    }
+
+    final ArrayList<String> result = new ArrayList<String>();
+
+    info.processOutputPaths(getProjectId(project), new Proc() {
+      @Override
+      public boolean execute(int projectId, String outputPath) {
+        VirtualFile clsFile = LocalFileSystem.getInstance().findFileByPath(outputPath);
+        if (clsFile != null) {
+          OutputFileInfo outputInfo = loadOutputInfo(clsFile);
+          if (outputInfo != null) {
+            ContainerUtil.addIfNotNull(result, outputInfo.getClassName());
+          }
+        }
+        return true;
+      }
+    });
+    return result;
+  }
+
+
+  private interface FileProcessor {
+    void execute(VirtualFile file);
+  }
+
+  private static void processRecursively(VirtualFile file, final boolean dbOnly, final FileProcessor processor) {
+    if (!(file.getFileSystem() instanceof LocalFileSystem)) {
+      return;
+    }
+
+    final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    VfsUtilCore.visitChildrenRecursively(file, new VirtualFileVisitor() {
+      @NotNull @Override
+      public Result visitFileEx(@NotNull VirtualFile file) {
+        if (fileTypeManager.isFileIgnored(file)) {
+          return SKIP_CHILDREN;
+        }
+
+        if (!file.isDirectory()) {
+          processor.execute(file);
+        }
+        return CONTINUE;
+      }
+
+      @Nullable
+      @Override
+      public Iterable<VirtualFile> getChildrenIterable(@NotNull VirtualFile file) {
+        return file.isDirectory() && dbOnly ? ((NewVirtualFile)file).iterInDbChildren() : null;
+      }
+    });
+  }
+
+  // made public for tests
+  public void scanSourceContent(final ProjectRef projRef, final Collection<VirtualFile> roots, final int totalRootCount, final boolean isNewRoots) {
+    if (roots.isEmpty()) {
+      return;
+    }
+    final int projectId = getProjectId(projRef.get());
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Scanning source content for project projectId=" + projectId + "; url=" + projRef.get().getPresentableUrl());
+    }
+
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(projRef.get()).getFileIndex();
+    final ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+    int processed = 0;
+    for (VirtualFile srcRoot : roots) {
+      if (indicator != null) {
+        projRef.get();
+        indicator.setText2(srcRoot.getPresentableUrl());
+        indicator.setFraction(++processed / (double)totalRootCount);
+      }
+      if (isNewRoots) {
+        fileIndex.iterateContentUnderDirectory(srcRoot, new ContentIterator() {
+          public boolean processFile(final VirtualFile file) {
+            if (!file.isDirectory()) {
+              if (!isMarkedForRecompilation(projectId, Math.abs(getFileId(file)))) {
+                final SourceFileInfo srcInfo = loadSourceInfo(file);
+                if (srcInfo == null || srcInfo.getTimestamp(projectId) != file.getTimeStamp()) {
+                  addSourceForRecompilation(projectId, file, srcInfo);
+                }
+              }
+            }
+            else {
+              projRef.get();
+            }
+            return true;
+          }
+        });
+      }
+      else {
+        final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+        VfsUtilCore.visitChildrenRecursively(srcRoot, new VirtualFileVisitor() {
+          @Override
+          public boolean visitFile(@NotNull VirtualFile file) {
+            if (fileTypeManager.isFileIgnored(file)) {
+              return false;
+            }
+            final int fileId = getFileId(file);
+            if (fileId > 0 /*file is valid*/) {
+              if (file.isDirectory()) {
+                projRef.get();
+              }
+              else if (!isMarkedForRecompilation(projectId, fileId)) {
+                final SourceFileInfo srcInfo = loadSourceInfo(file);
+                if (srcInfo != null) {
+                  addSourceForRecompilation(projectId, file, srcInfo);
+                }
+              }
+            }
+            return true;
+          }
+        });
+      }
+    }
+  }
+
+  public void ensureInitializationCompleted(Project project, ProgressIndicator indicator) {
+    final int id = getProjectId(project);
+    synchronized (myAsyncScanLock) {
+      while (myInitInProgress.containsKey(id)) {
+        if (!project.isOpen() || project.isDisposed() || (indicator != null && indicator.isCanceled())) {
+          // makes no sense to continue waiting
+          break;
+        }
+        try {
+          myAsyncScanLock.wait(500);
+        }
+        catch (InterruptedException ignored) {
+          break;
+        }
+      }
+    }
+  }
+
+  private void markOldOutputRoots(final ProjectRef projRef, final TIntObjectHashMap<Pair<Integer, Integer>> currentLayout) {
+    final int projectId = getProjectId(projRef.get());
+
+    final TIntHashSet rootsToMark = new TIntHashSet();
+    synchronized (myProjectOutputRoots) {
+      final TIntObjectHashMap<Pair<Integer, Integer>> oldLayout = myProjectOutputRoots.get(projectId);
+      for (final TIntObjectIterator<Pair<Integer, Integer>> it = oldLayout.iterator(); it.hasNext();) {
+        it.advance();
+        final Pair<Integer, Integer> currentRoots = currentLayout.get(it.key());
+        final Pair<Integer, Integer> oldRoots = it.value();
+        if (shouldMark(oldRoots.first, currentRoots != null? currentRoots.first : -1)) {
+          rootsToMark.add(oldRoots.first);
+        }
+        if (shouldMark(oldRoots.second, currentRoots != null? currentRoots.second : -1)) {
+          rootsToMark.add(oldRoots.second);
+        }
+      }
+    }
+
+    for (TIntIterator it = rootsToMark.iterator(); it.hasNext();) {
+      final int id = it.next();
+      final VirtualFile outputRoot = findFileById(id);
+      if (outputRoot != null) {
+        processOldOutputRoot(projectId, outputRoot);
+      }
+    }
+  }
+
+  private static boolean shouldMark(Integer oldOutputRoot, Integer currentOutputRoot) {
+    return oldOutputRoot != null && oldOutputRoot.intValue() > 0 && !Comparing.equal(oldOutputRoot, currentOutputRoot);
+  }
+
+  private void processOldOutputRoot(final int projectId, VirtualFile outputRoot) {
+    // recursively mark all corresponding sources for recompilation
+    VfsUtilCore.visitChildrenRecursively(outputRoot, new VirtualFileVisitor() {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile file) {
+        if (!file.isDirectory()) {
+          // todo: possible optimization - process only those outputs that are not marked for deletion yet
+          final OutputFileInfo outputInfo = loadOutputInfo(file);
+          if (outputInfo != null) {
+            final String srcPath = outputInfo.getSourceFilePath();
+            final VirtualFile srcFile = srcPath != null? LocalFileSystem.getInstance().findFileByPath(srcPath) : null;
+            if (srcFile != null) {
+              loadInfoAndAddSourceForRecompilation(projectId, srcFile);
+            }
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  public void scanSourcesForCompilableFiles(final Project project) {
+    final int projectId = getProjectId(project);
+    if (isSuspended(projectId)) {
+      return;
+    }
+    startAsyncScan(projectId);
+    StartupManager.getInstance(project).runWhenProjectIsInitialized(new Runnable() {
+      public void run() {
+        new Task.Backgroundable(project, CompilerBundle.message("compiler.initial.scanning.progress.text"), false) {
+          public void run(@NotNull final ProgressIndicator indicator) {
+            final ProjectRef projRef = new ProjectRef(project);
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Initial sources scan for project hash=" + projectId + "; url="+ projRef.get().getPresentableUrl());
+            }
+            try {
+              final IntermediateOutputCompiler[] compilers =
+                  CompilerManager.getInstance(projRef.get()).getCompilers(IntermediateOutputCompiler.class);
+
+              final Set<VirtualFile> intermediateRoots = new HashSet<VirtualFile>();
+              if (compilers.length > 0) {
+                final Module[] modules = ModuleManager.getInstance(projRef.get()).getModules();
+                for (IntermediateOutputCompiler compiler : compilers) {
+                  for (Module module : modules) {
+                    if (module.isDisposed()) {
+                      continue;
+                    }
+                    final VirtualFile outputRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(CompilerPaths.getGenerationOutputPath(compiler, module, false));
+                    if (outputRoot != null) {
+                      intermediateRoots.add(outputRoot);
+                    }
+                    final VirtualFile testsOutputRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(CompilerPaths.getGenerationOutputPath(compiler, module, true));
+                    if (testsOutputRoot != null) {
+                      intermediateRoots.add(testsOutputRoot);
+                    }
+                  }
+                }
+              }
+
+              final List<VirtualFile> projectRoots = Arrays.asList(ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots());
+              final int totalRootsCount = projectRoots.size() + intermediateRoots.size();
+              scanSourceContent(projRef, projectRoots, totalRootsCount, true);
+
+              if (!intermediateRoots.isEmpty()) {
+                final FileProcessor processor = new FileProcessor() {
+                  public void execute(final VirtualFile file) {
+                    if (!isMarkedForRecompilation(projectId, Math.abs(getFileId(file)))) {
+                      final SourceFileInfo srcInfo = loadSourceInfo(file);
+                      if (srcInfo == null || srcInfo.getTimestamp(projectId) != file.getTimeStamp()) {
+                        addSourceForRecompilation(projectId, file, srcInfo);
+                      }
+                    }
+                  }
+                };
+                int processed = projectRoots.size();
+                for (VirtualFile root : intermediateRoots) {
+                  projRef.get();
+                  indicator.setText2(root.getPresentableUrl());
+                  indicator.setFraction(++processed / (double)totalRootsCount);
+                  processRecursively(root, false, processor);
+                }
+              }
+              
+              markOldOutputRoots(projRef, buildOutputRootsLayout(projRef));
+            }
+            catch (ProjectRef.ProjectClosedException swallowed) {
+            }
+            finally {
+              terminateAsyncScan(projectId, false);
+            }
+          }
+        }.queue();
+      }
+    });
+  }
+
+  private void terminateAsyncScan(int projectId, final boolean clearCounter) {
+    synchronized (myAsyncScanLock) {
+      int counter = myInitInProgress.remove(projectId);
+      if (clearCounter) {
+        myAsyncScanLock.notifyAll();
+      }
+      else {
+        if (--counter > 0) {
+          myInitInProgress.put(projectId, counter);
+        }
+        else {
+          myAsyncScanLock.notifyAll();
+        }
+      }
+    }
+  }
+
+  private void startAsyncScan(final int projectId) {
+    synchronized (myAsyncScanLock) {
+      int counter = myInitInProgress.get(projectId);
+      counter = (counter > 0)? counter + 1 : 1;
+      myInitInProgress.put(projectId, counter);
+      myAsyncScanLock.notifyAll();
+    }
+  }
+
+  private class MyProjectManagerListener extends ProjectManagerAdapter {
+
+    final Map<Project, MessageBusConnection> myConnections = new HashMap<Project, MessageBusConnection>();
+
+    public void projectOpened(final Project project) {
+      final MessageBusConnection conn = project.getMessageBus().connect();
+      myConnections.put(project, conn);
+      final ProjectRef projRef = new ProjectRef(project);
+      final int projectId = getProjectId(project);
+
+      if (CompilerWorkspaceConfiguration.getInstance(project).useOutOfProcessBuild()) {
+        suspendProject(project);
+      }
+      else {
+        watchProject(project);
+      }
+
+      conn.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootListener() {
+        private VirtualFile[] myRootsBefore;
+        private Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SWING_THREAD, project);
+
+        public void beforeRootsChange(final ModuleRootEvent event) {
+          if (isSuspended(projectId)) {
+            return;
+          }
+          try {
+            myRootsBefore = ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots();
+          }
+          catch (ProjectRef.ProjectClosedException e) {
+            myRootsBefore = null;
+          }
+        }
+
+        public void rootsChanged(final ModuleRootEvent event) {
+          if (isSuspended(projectId)) {
+            return;
+          }
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Before roots changed for projectId=" + projectId + "; url="+ project.getPresentableUrl());
+          }
+          try {
+            final VirtualFile[] rootsBefore = myRootsBefore;
+            myRootsBefore = null;
+            final VirtualFile[] rootsAfter = ProjectRootManager.getInstance(projRef.get()).getContentSourceRoots();
+            final Set<VirtualFile> newRoots = new HashSet<VirtualFile>();
+            final Set<VirtualFile> oldRoots = new HashSet<VirtualFile>();
+            {
+              if (rootsAfter.length > 0) {
+                ContainerUtil.addAll(newRoots, rootsAfter);
+              }
+              if (rootsBefore != null) {
+                newRoots.removeAll(Arrays.asList(rootsBefore));
+              }
+            }
+            {
+              if (rootsBefore != null) {
+                ContainerUtil.addAll(oldRoots, rootsBefore);
+              }
+              if (!oldRoots.isEmpty() && rootsAfter.length > 0) {
+                oldRoots.removeAll(Arrays.asList(rootsAfter));
+              }
+            }
+
+            myAlarm.cancelAllRequests(); // need alarm to deal with multiple rootsChanged events
+            myAlarm.addRequest(new Runnable() {
+              public void run() {
+                startAsyncScan(projectId);
+                new Task.Backgroundable(project, CompilerBundle.message("compiler.initial.scanning.progress.text"), false) {
+                  public void run(@NotNull final ProgressIndicator indicator) {
+                    try {
+                      if (newRoots.size() > 0) {
+                        scanSourceContent(projRef, newRoots, newRoots.size(), true);
+                      }
+                      if (oldRoots.size() > 0) {
+                        scanSourceContent(projRef, oldRoots, oldRoots.size(), false);
+                      }
+                      markOldOutputRoots(projRef, buildOutputRootsLayout(projRef));
+                    }
+                    catch (ProjectRef.ProjectClosedException swallowed) {
+                      // ignored
+                    }
+                    finally {
+                      terminateAsyncScan(projectId, false);
+                    }
+                  }
+                }.queue();
+              }
+            }, 500, ModalityState.NON_MODAL);
+          }
+          catch (ProjectRef.ProjectClosedException e) {
+            LOG.info(e);
+          }
+        }
+      });
+
+      scanSourcesForCompilableFiles(project);
+    }
+
+    public void projectClosed(final Project project) {
+      final int projectId = getProjectId(project);
+      terminateAsyncScan(projectId, true);
+      myConnections.remove(project).disconnect();
+      synchronized (myDataLock) {
+        mySourcesToRecompile.remove(projectId);
+        myOutputsToDelete.remove(projectId);  // drop cache to save memory
+      }
+    }
+  }
+
+  private class MyVfsListener extends VirtualFileAdapter {
+    public void propertyChanged(final VirtualFilePropertyEvent event) {
+      if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) {
+        final VirtualFile eventFile = event.getFile();
+        final VirtualFile parent = event.getParent();
+        if (parent != null) {
+          final String oldName = (String)event.getOldValue();
+          final String root = parent.getPath() + "/" + oldName;
+          final Set<File> toMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
+          if (eventFile.isDirectory()) {
+            VfsUtilCore.visitChildrenRecursively(eventFile, new VirtualFileVisitor() {
+              private StringBuilder filePath = new StringBuilder(root);
+
+              @Override
+              public boolean visitFile(@NotNull VirtualFile child) {
+                if (child.isDirectory()) {
+                  if (!Comparing.equal(child, eventFile)) {
+                    filePath.append("/").append(child.getName());
+                  }
+                }
+                else {
+                  String childPath = filePath.toString();
+                  if (!Comparing.equal(child, eventFile)) {
+                    childPath += "/" + child.getName();
+                  }
+                  toMark.add(new File(childPath));
+                }
+                return true;
+              }
+
+              @Override
+              public void afterChildrenVisited(@NotNull VirtualFile file) {
+                if (file.isDirectory() && !Comparing.equal(file, eventFile)) {
+                  filePath.delete(filePath.length() - file.getName().length() - 1, filePath.length());
+                }
+              }
+            });
+          }
+          else {
+            toMark.add(new File(root));
+          }
+          notifyFilesDeleted(toMark);
+        }
+        markDirtyIfSource(eventFile, false);
+      }
+    }
+
+    public void contentsChanged(final VirtualFileEvent event) {
+      markDirtyIfSource(event.getFile(), false);
+    }
+
+    public void fileCreated(final VirtualFileEvent event) {
+      processNewFile(event.getFile(), true);
+    }
+
+    public void fileCopied(final VirtualFileCopyEvent event) {
+      processNewFile(event.getFile(), true);
+    }
+
+    public void fileMoved(VirtualFileMoveEvent event) {
+      processNewFile(event.getFile(), true);
+    }
+
+    public void beforeFileDeletion(final VirtualFileEvent event) {
+      final VirtualFile eventFile = event.getFile();
+      if ((LOG.isDebugEnabled() && eventFile.isDirectory()) || ourDebugMode) {
+        final String message = "Processing file deletion: " + eventFile.getPresentableUrl();
+        LOG.debug(message);
+        if (ourDebugMode) {
+          System.out.println(message);
+        }
+      }
+
+      final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
+
+      processRecursively(eventFile, true, new FileProcessor() {
+        private final TIntArrayList myAssociatedProjectIds = new TIntArrayList();
+        
+        public void execute(final VirtualFile file) {
+          final String filePath = file.getPath();
+          pathsToMark.add(new File(filePath));
+          myAssociatedProjectIds.clear();
+          try {
+            final OutputFileInfo outputInfo = loadOutputInfo(file);
+            if (outputInfo != null) {
+              final String srcPath = outputInfo.getSourceFilePath();
+              final VirtualFile srcFile = srcPath != null? LocalFileSystem.getInstance().findFileByPath(srcPath) : null;
+              if (srcFile != null) {
+                final SourceFileInfo srcInfo = loadSourceInfo(srcFile);
+                if (srcInfo != null) {
+                  final boolean srcWillBeDeleted = VfsUtil.isAncestor(eventFile, srcFile, false);
+                  for (int projectId : srcInfo.getProjectIds().toArray()) {
+                    if (isSuspended(projectId)) {
+                      continue;
+                    }
+                    if (srcInfo.isAssociated(projectId, filePath)) {
+                      myAssociatedProjectIds.add(projectId);
+                      if (srcWillBeDeleted) {
+                        if (LOG.isDebugEnabled() || ourDebugMode) {
+                          final String message = "Unschedule recompilation because of deletion " + srcFile.getPresentableUrl();
+                          LOG.debug(message);
+                          if (ourDebugMode) {
+                            System.out.println(message);
+                          }
+                        }
+                        removeSourceForRecompilation(projectId, Math.abs(getFileId(srcFile)));
+                      }
+                      else {
+                        addSourceForRecompilation(projectId, srcFile, srcInfo);
+                      }
+                    }
+                  }
+                }
+              }
+            }
+
+            final SourceFileInfo srcInfo = loadSourceInfo(file);
+            if (srcInfo != null) {
+              final TIntHashSet projects = srcInfo.getProjectIds();
+              if (!projects.isEmpty()) {
+                final ScheduleOutputsForDeletionProc deletionProc = new ScheduleOutputsForDeletionProc(file.getUrl());
+                deletionProc.setRootBeingDeleted(eventFile);
+                final int sourceFileId = Math.abs(getFileId(file));
+                for (int projectId : projects.toArray()) {
+                  if (isSuspended(projectId)) {
+                    continue;
+                  }
+                  if (srcInfo.isAssociated(projectId, filePath)) {
+                    myAssociatedProjectIds.add(projectId);
+                  }
+                  // mark associated outputs for deletion
+                  srcInfo.processOutputPaths(projectId, deletionProc);
+                  if (LOG.isDebugEnabled() || ourDebugMode) {
+                    final String message = "Unschedule recompilation because of deletion " + file.getPresentableUrl();
+                    LOG.debug(message);
+                    if (ourDebugMode) {
+                      System.out.println(message);
+                    }
+                  }
+                  removeSourceForRecompilation(projectId, sourceFileId);
+                }
+              }
+            }
+          }
+          finally {
+            // it is important that update of myOutputsToDelete is done at the end
+            // otherwise the filePath of the file that is about to be deleted may be re-scheduled for deletion in addSourceForRecompilation()
+            myAssociatedProjectIds.forEach(new TIntProcedure() {
+              public boolean execute(int projectId) {
+                unmarkOutputPathForDeletion(projectId, filePath);
+                return true;
+              }
+            });
+          }
+        }
+      });
+
+      notifyFilesDeleted(pathsToMark);
+    }
+
+    public void beforeFileMovement(final VirtualFileMoveEvent event) {
+      markDirtyIfSource(event.getFile(), true);
+    }
+
+    private void markDirtyIfSource(final VirtualFile file, final boolean fromMove) {
+      final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
+      processRecursively(file, false, new FileProcessor() {
+        public void execute(final VirtualFile file) {
+          pathsToMark.add(new File(file.getPath()));
+          final SourceFileInfo srcInfo = file.isValid()? loadSourceInfo(file) : null;
+          if (srcInfo != null) {
+            for (int projectId : srcInfo.getProjectIds().toArray()) {
+              if (isSuspended(projectId)) {
+                if (srcInfo.clearPaths(projectId)) {
+                  srcInfo.updateTimestamp(projectId, -1L);
+                  saveSourceInfo(file, srcInfo);
+                }
+              }
+              else {
+                addSourceForRecompilation(projectId, file, srcInfo);
+                // when the file is moved to a new location, we should 'forget' previous associations
+                if (fromMove) {
+                  if (srcInfo.clearPaths(projectId)) {
+                    saveSourceInfo(file, srcInfo);
+                  }
+                }
+              }
+            }
+          }
+          else {
+            processNewFile(file, false);
+          }
+        }
+      });
+      if (fromMove) {
+        notifyFilesDeleted(pathsToMark);
+      }
+      else if (!isIgnoredOrUnderIgnoredDirectory(file)) {
+        notifyFilesChanged(pathsToMark);
+      }
+    }
+
+    private void processNewFile(final VirtualFile file, final boolean notifyServer) {
+      final Ref<Boolean> isInContent = Ref.create(false);
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        // need read action to ensure that the project was not disposed during the iteration over the project list
+        public void run() {
+          for (final Project project : myProjectManager.getOpenProjects()) {
+            if (!project.isInitialized()) {
+              continue; // the content of this project will be scanned during its post-startup activities
+            }
+            final int projectId = getProjectId(project);
+            final boolean projectSuspended = isSuspended(projectId);
+            final ProjectRootManager rootManager = ProjectRootManager.getInstance(project);
+            ProjectFileIndex fileIndex = rootManager.getFileIndex();
+            if (fileIndex.isInContent(file)) {
+              isInContent.set(true);
+            }
+
+            if (fileIndex.isInSourceContent(file)) {
+              final TranslatingCompiler[] translators = CompilerManager.getInstance(project).getCompilers(TranslatingCompiler.class);
+              processRecursively(file, false, new FileProcessor() {
+                public void execute(final VirtualFile file) {
+                  if (!projectSuspended && isCompilable(file)) {
+                    loadInfoAndAddSourceForRecompilation(projectId, file);
+                  }
+                }
+
+                boolean isCompilable(VirtualFile file) {
+                  for (TranslatingCompiler translator : translators) {
+                    if (translator.isCompilableFile(file, DummyCompileContext.getInstance())) {
+                      return true;
+                    }
+                  }
+                  return false;
+                }
+              });
+            }
+            else {
+              if (!projectSuspended && belongsToIntermediateSources(file, project)) {
+                processRecursively(file, false, new FileProcessor() {
+                  public void execute(final VirtualFile file) {
+                    loadInfoAndAddSourceForRecompilation(projectId, file);
+                  }
+                });
+              }
+            }
+          }
+        }
+      });
+      if (notifyServer && !isIgnoredOrUnderIgnoredDirectory(file)) {
+        final Set<File> pathsToMark = new THashSet<File>(FileUtil.FILE_HASHING_STRATEGY);
+        boolean dbOnly = !isInContent.get();
+        processRecursively(file, dbOnly, new FileProcessor() {
+          @Override
+          public void execute(VirtualFile file) {
+            pathsToMark.add(new File(file.getPath()));
+          }
+        });
+        notifyFilesChanged(pathsToMark);
+      }
+    }
+  }
+
+  private boolean isIgnoredOrUnderIgnoredDirectory(final VirtualFile file) {
+    FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    if (fileTypeManager.isFileIgnored(file)) {
+      return true;
+    }
+
+    //optimization: if file is in content of some project it's definitely not ignored
+    boolean isInContent = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      @Override
+      public Boolean compute() {
+        for (Project project : myProjectManager.getOpenProjects()) {
+          if (project.isInitialized() && ProjectRootManager.getInstance(project).getFileIndex().isInContent(file)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    });
+    if (isInContent) {
+      return false;
+    }
+
+    VirtualFile current = file.getParent();
+    while (current != null) {
+      if (fileTypeManager.isFileIgnored(current)) {
+        return true;
+      }
+      current = current.getParent();
+    }
+    return false;
+  }
+
+  private static void notifyFilesChanged(Collection<File> paths) {
+    if (!paths.isEmpty()) {
+      BuildManager.getInstance().notifyFilesChanged(paths);
+    }
+  }
+
+  private static void notifyFilesDeleted(Collection<File> paths) {
+    if (!paths.isEmpty()) {
+      BuildManager.getInstance().notifyFilesDeleted(paths);
+    }
+  }
+
+  private boolean belongsToIntermediateSources(VirtualFile file, Project project) {
+    return FileUtil.isAncestor(myGeneratedDataPaths.get(project), new File(file.getPath()), true);
+  }
+
+  private void loadInfoAndAddSourceForRecompilation(final int projectId, final VirtualFile srcFile) {
+    addSourceForRecompilation(projectId, srcFile, loadSourceInfo(srcFile));
+  }
+  private void addSourceForRecompilation(final int projectId, final VirtualFile srcFile, @Nullable final SourceFileInfo srcInfo) {
+    final boolean alreadyMarked;
+    synchronized (myDataLock) {
+      TIntHashSet set = mySourcesToRecompile.get(projectId);
+      if (set == null) {
+        set = new TIntHashSet();
+        mySourcesToRecompile.put(projectId, set);
+      }
+      alreadyMarked = !set.add(Math.abs(getFileId(srcFile)));
+      if (!alreadyMarked && (LOG.isDebugEnabled() || ourDebugMode)) {
+        final String message = "Scheduled recompilation " + srcFile.getPresentableUrl();
+        LOG.debug(message);
+        if (ourDebugMode) {
+          System.out.println(message);
+        }
+      }
+    }
+
+    if (!alreadyMarked && srcInfo != null) {
+      srcInfo.updateTimestamp(projectId, -1L);
+      srcInfo.processOutputPaths(projectId, new ScheduleOutputsForDeletionProc(srcFile.getUrl()));
+      saveSourceInfo(srcFile, srcInfo);
+    }
+  }
+
+  private void removeSourceForRecompilation(final int projectId, final int srcId) {
+    synchronized (myDataLock) {
+      TIntHashSet set = mySourcesToRecompile.get(projectId);
+      if (set != null) {
+        set.remove(srcId);
+        if (set.isEmpty()) {
+          mySourcesToRecompile.remove(projectId);
+        }
+      }
+    }
+  }
+  
+  public boolean isMarkedForCompilation(Project project, VirtualFile file) {
+    if (CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER) {
+      final CompilerManager compilerManager = CompilerManager.getInstance(project);
+      return !compilerManager.isUpToDate(compilerManager.createFilesCompileScope(new VirtualFile[]{file}));
+    }
+    return isMarkedForRecompilation(getProjectId(project), getFileId(file));
+  }
+  
+  private boolean isMarkedForRecompilation(int projectId, final int srcId) {
+    synchronized (myDataLock) {
+      final TIntHashSet set = mySourcesToRecompile.get(projectId);
+      return set != null && set.contains(srcId);
+    }
+  }
+  
+  private interface Proc {
+    boolean execute(final int projectId, String outputPath);
+  }
+  
+  private class ScheduleOutputsForDeletionProc implements Proc {
+    private final String mySrcUrl;
+    private final LocalFileSystem myFileSystem;
+    @Nullable
+    private VirtualFile myRootBeingDeleted;
+
+    private ScheduleOutputsForDeletionProc(final String srcUrl) {
+      mySrcUrl = srcUrl;
+      myFileSystem = LocalFileSystem.getInstance();
+    }
+
+    public void setRootBeingDeleted(@Nullable VirtualFile rootBeingDeleted) {
+      myRootBeingDeleted = rootBeingDeleted;
+    }
+
+    public boolean execute(final int projectId, String outputPath) {
+      final VirtualFile outFile = myFileSystem.findFileByPath(outputPath);
+      if (outFile != null) { // not deleted yet
+        if (myRootBeingDeleted != null && VfsUtil.isAncestor(myRootBeingDeleted, outFile, false)) {
+          unmarkOutputPathForDeletion(projectId, outputPath);
+        }
+        else {
+          final OutputFileInfo outputInfo = loadOutputInfo(outFile);
+          final String classname = outputInfo != null? outputInfo.getClassName() : null;
+          markOutputPathForDeletion(projectId, outputPath, classname, mySrcUrl);
+        }
+      }
+      return true;
+    }
+  }
+
+  private void markOutputPathForDeletion(final int projectId, final String outputPath, final String classname, final String srcUrl) {
+    final SourceUrlClassNamePair pair = new SourceUrlClassNamePair(srcUrl, classname);
+    synchronized (myDataLock) {
+      final Outputs outputs = myOutputsToDelete.get(projectId);
+      try {
+        outputs.put(outputPath, pair);
+        if (LOG.isDebugEnabled() || ourDebugMode) {
+          final String message = "ADD path to delete: " + outputPath + "; source: " + srcUrl;
+          LOG.debug(message);
+          if (ourDebugMode) {
+            System.out.println(message);
+          }
+        }
+      }
+      finally {
+        outputs.release();
+      }
+    }
+  }
+
+  private void unmarkOutputPathForDeletion(final int projectId, String outputPath) {
+    synchronized (myDataLock) {
+      final Outputs outputs = myOutputsToDelete.get(projectId);
+      try {
+        final SourceUrlClassNamePair val = outputs.remove(outputPath);
+        if (val != null) {
+          if (LOG.isDebugEnabled() || ourDebugMode) {
+            final String message = "REMOVE path to delete: " + outputPath;
+            LOG.debug(message);
+            if (ourDebugMode) {
+              System.out.println(message);
+            }
+          }
+        }
+      }
+      finally {
+        outputs.release();
+      }
+    }
+  }
+
+  public static final class ProjectRef extends Ref<Project> {
+    static class ProjectClosedException extends RuntimeException {
+    }
+
+    public ProjectRef(Project project) {
+      super(project);
+    }
+
+    public Project get() {
+      final Project project = super.get();
+      if (project != null && project.isDisposed()) {
+        throw new ProjectClosedException();
+      }
+      return project;
+    }
+  }
+  
+  private static class Outputs {
+    private boolean myIsDirty = false;
+    @Nullable
+    private final File myStoreFile;
+    private final Map<String, SourceUrlClassNamePair> myMap;
+    private final AtomicInteger myRefCount = new AtomicInteger(1);
+    
+    Outputs(@Nullable File storeFile, Map<String, SourceUrlClassNamePair> map) {
+      myStoreFile = storeFile;
+      myMap = map;
+    }
+
+    public Set<Map.Entry<String, SourceUrlClassNamePair>> getEntries() {
+      return Collections.unmodifiableSet(myMap.entrySet());
+    }
+    
+    public void put(String outputPath, SourceUrlClassNamePair pair) {
+      if (myStoreFile == null) {
+        return;
+      }
+      if (pair == null) {
+        remove(outputPath);
+      }
+      else {
+        myMap.put(outputPath, pair);
+        myIsDirty = true;
+      }
+    }
+    
+    public SourceUrlClassNamePair remove(String outputPath) {
+      if (myStoreFile == null) {
+        return null;
+      }
+      final SourceUrlClassNamePair removed = myMap.remove(outputPath);
+      myIsDirty |= removed != null;
+      return removed;
+    }
+    
+    void allocate() {
+      myRefCount.incrementAndGet();
+    }
+    
+    public void release() {
+      if (myRefCount.decrementAndGet() == 0) {
+        if (myIsDirty && myStoreFile != null) {
+          savePathsToDelete(myStoreFile, myMap);
+        }
+      }
+    }
+  }
+  
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java
new file mode 100644
index 0000000..0031966
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedMap.java
@@ -0,0 +1,239 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.util.containers.StringInterner;
+import com.intellij.util.containers.EmptyIterator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.Stack;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jun 18, 2006
+ */
+public class TreeBasedMap<T> {
+  private Node<T> myRoot = new Node<T>();
+  private final StringInterner myInterner;
+  private final char mySeparator;
+  private int mySize = 0;
+
+  public TreeBasedMap(StringInterner table, final char separator) {
+    myInterner = table;
+    mySeparator = separator;
+  }
+
+  private class Node<T> {
+    private boolean myMappingExists = false;
+    private T myValue = null;
+    private @Nullable HashMap<String, Node<T>> myChildren = null;
+
+    public void setValue(T value) {
+      myValue = value;
+      myMappingExists = true;
+    }
+
+    public T getValue() {
+      return myValue;
+    }
+
+    public void removeValue() {
+      myValue = null;
+      myMappingExists = false;
+    }
+
+    public boolean mappingExists() {
+      return myMappingExists;
+    }
+
+    @Nullable
+    public Node<T> findRelative(String text, boolean create, final StringInterner table) {
+      return findRelative(text, 0, create, table);
+    }
+
+    @Nullable
+    private Node<T> findRelative(final String text, final int nameStartIndex, final boolean create, final StringInterner table) {
+      if (myChildren == null && !create) {
+        return null;
+      }
+
+      final int textLen = text.length();
+      final int separatorIdx = text.indexOf(mySeparator, nameStartIndex);
+      final int childNameEnd = separatorIdx >= 0 ? separatorIdx : textLen;
+
+      if (myChildren != null) {
+        final Node<T> child = myChildren.get(text.substring(nameStartIndex, childNameEnd));
+        if (child != null) {
+          if (separatorIdx < 0) {
+            return child;
+          }
+          return child.findRelative(text, childNameEnd + 1, create, table);
+        }
+      }
+
+      if (create) {
+        return addChild(table, text, nameStartIndex, childNameEnd);
+      }
+
+      return null;
+    }
+
+    @NotNull
+    private Node<T> addChild(final StringInterner table, final String text, final int nameStartIndex, final int nameEndIndex) {
+      if (myChildren == null) {
+        myChildren = new HashMap<String, Node<T>>(3, 0.95f);
+      }
+
+      Node<T> newChild = new Node<T>();
+      final String key = table.intern(text.substring(nameStartIndex, nameEndIndex));
+      myChildren.put(key, newChild);
+
+      if (nameEndIndex == text.length()) {
+        return newChild;
+      }
+
+      Node<T> restNodes = newChild.findRelative(text, nameEndIndex + 1, true, table);
+      assert restNodes != null;
+      return restNodes;
+    }
+  }
+
+  public void put(String key, T value) {
+    final Node<T> node = myRoot.findRelative(key, true, myInterner);
+    assert node != null;
+    final boolean mappingExisted = node.mappingExists();
+    node.setValue(value);
+    if (!mappingExisted) {
+      mySize++;
+    }
+  }
+
+  public void remove(String key) {
+    final Node node = myRoot.findRelative(key, false, myInterner);
+    if (node != null && node.mappingExists()) {
+      node.removeValue();
+      mySize--;
+    }
+  }
+
+  public int size() {
+    return mySize;
+  }
+
+  public T get(String key) {
+    final Node<T> node = myRoot.findRelative(key, false, myInterner);
+    return (node != null && node.mappingExists()) ? node.getValue() : null;
+  }
+
+  public boolean containsKey(String key) {
+    final Node<T> node = myRoot.findRelative(key, false, myInterner);
+    return node != null && node.mappingExists();
+  }
+
+  public void removeAll() {
+    myRoot = new Node<T>();
+  }
+
+  public Iterator<String> getKeysIterator() {
+    return new KeysIterator();
+  }
+
+
+  private class KeysIterator implements Iterator<String> {
+    private final Stack<PathElement<T>> myCurrentNodePath = new Stack<PathElement<T>>();
+    private final StringBuilder myCurrentName = new StringBuilder();
+
+    public KeysIterator() {
+      pushNode("", myRoot);
+      findNextNode();
+    }
+
+    public boolean hasNext() {
+      return myCurrentNodePath.size() > 0;
+    }
+
+    public String next() {
+      final String key = myCurrentName.toString();
+      popNode();
+      findNextNode();
+      return key;
+    }
+
+    public void remove() {
+      throw new UnsupportedOperationException("Remove not supported");
+    }
+
+    private boolean pushNode(final @NotNull String name, @NotNull Node<T> node) {
+      final HashMap<String, Node<T>> childrenMap = node.myChildren;
+      final boolean hasChildren = childrenMap != null && childrenMap.size() > 0;
+      if (hasChildren || node.mappingExists()) {
+        myCurrentNodePath.push(new PathElement<T>(node, hasChildren? childrenMap.keySet().iterator() : EmptyIterator.<String>getInstance()));
+        if (myCurrentNodePath.size() > 2) {
+          // do not add separator before the Root and its direct child nodes 
+          myCurrentName.append(mySeparator);
+        }
+        myCurrentName.append(name);
+        return true;
+      }
+      return false;
+    }
+
+    private void popNode() {
+      myCurrentNodePath.pop();
+      final int separatorIndex = myCurrentName.lastIndexOf(String.valueOf(mySeparator));
+      if (separatorIndex >= 0) {
+        myCurrentName.replace(separatorIndex, myCurrentName.length(), "");
+      }
+      else {
+        myCurrentName.setLength(0);
+      }
+    }
+
+    private void findNextNode() {
+      MAIN_LOOP: while (!myCurrentNodePath.isEmpty()) {
+        final PathElement<T> element = myCurrentNodePath.peek();
+        final Iterator<String> childrenIterator = element.iterator;
+        final Node<T> currentNode = element.node;
+        while (childrenIterator.hasNext()) {
+          final String name = childrenIterator.next();
+          final Node<T> childNode = currentNode.myChildren.get(name);
+          if (pushNode(name, childNode)) {
+            continue MAIN_LOOP;
+          }
+        }
+        if (!currentNode.mappingExists()) {
+          popNode();
+        }
+        else {
+          break;
+        }
+      }
+    }
+  }
+
+  private class PathElement<T> {
+    final @NotNull Iterator<String> iterator;
+    final @NotNull Node<T> node;
+    public PathElement(@NotNull final Node<T> node, Iterator<String> iterator) {
+      this.node = node;
+      this.iterator = iterator;
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java
new file mode 100644
index 0000000..4fd3ee8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/TreeBasedPathsSet.java
@@ -0,0 +1,42 @@
+/*
+ * 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.compiler.impl;
+
+import com.intellij.util.containers.StringInterner;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jun 19, 2006
+ */
+public class TreeBasedPathsSet {
+  private final TreeBasedMap<Object> myMap;
+
+  public TreeBasedPathsSet(StringInterner interner, char separator) {
+    myMap = new TreeBasedMap<Object>(interner, separator);
+  }
+
+  public void add(String path) {
+    myMap.put(path, null);
+  }
+
+  public void remove(String path) {
+    myMap.remove(path);
+  }
+
+  public boolean contains(String path) {
+    return myMap.containsKey(path);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java
new file mode 100644
index 0000000..5741b9c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerCache.java
@@ -0,0 +1,178 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.generic;
+
+import com.intellij.openapi.compiler.generic.GenericCompiler;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.io.PersistentEnumerator;
+import com.intellij.util.io.PersistentHashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author nik
+ */
+public class GenericCompilerCache<Key, SourceState, OutputState> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.generic.GenericCompilerCache");
+  private PersistentHashMap<KeyAndTargetData<Key>, PersistentStateData<SourceState, OutputState>> myPersistentMap;
+  private File myCacheFile;
+  private final GenericCompiler<Key, SourceState, OutputState> myCompiler;
+
+  public GenericCompilerCache(GenericCompiler<Key, SourceState, OutputState> compiler, final File compilerCacheDir) throws IOException {
+    myCompiler = compiler;
+    myCacheFile = new File(compilerCacheDir, "timestamps");
+    createMap();
+  }
+
+  private void createMap() throws IOException {
+    try {
+      myPersistentMap = new PersistentHashMap<KeyAndTargetData<Key>, PersistentStateData<SourceState,OutputState>>(myCacheFile, new SourceItemDataDescriptor(myCompiler.getItemKeyDescriptor()),
+                                                                    new PersistentStateDataExternalizer(myCompiler));
+    }
+    catch (PersistentEnumerator.CorruptedException e) {
+      FileUtil.delete(myCacheFile);
+      throw e;
+    }
+  }
+
+  private KeyAndTargetData<Key> getKeyAndTargetData(Key key, int target) {
+    return new KeyAndTargetData<Key>(target, key);
+  }
+
+  public void wipe() throws IOException {
+    try {
+      myPersistentMap.close();
+    }
+    catch (IOException ignored) {
+    }
+    PersistentHashMap.deleteFilesStartingWith(myCacheFile);
+    createMap();
+  }
+
+  public void close() {
+    try {
+      myPersistentMap.close();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+  }
+
+  public void remove(int targetId, Key key) throws IOException {
+    myPersistentMap.remove(getKeyAndTargetData(key, targetId));
+  }
+
+  public PersistentStateData<SourceState, OutputState> getState(int targetId, Key key) throws IOException {
+    return myPersistentMap.get(getKeyAndTargetData(key, targetId));
+  }
+
+  public void processSources(final int targetId, final Processor<Key> processor) throws IOException {
+    myPersistentMap.processKeysWithExistingMapping(new Processor<KeyAndTargetData<Key>>() {
+      @Override
+      public boolean process(KeyAndTargetData<Key> data) {
+        return targetId == data.myTarget ? processor.process(data.myKey) : true;
+      }
+    });
+  }
+
+  public void putState(int targetId, @NotNull Key key, @NotNull SourceState sourceState, @NotNull OutputState outputState) throws IOException {
+    myPersistentMap.put(getKeyAndTargetData(key, targetId), new PersistentStateData<SourceState,OutputState>(sourceState, outputState));
+  }
+
+
+  private static class KeyAndTargetData<Key> {
+    public final int myTarget;
+    public final Key myKey;
+
+    private KeyAndTargetData(int target, Key key) {
+      myTarget = target;
+      myKey = key;
+    }
+  }
+
+  public static class PersistentStateData<SourceState, OutputState> {
+    public final SourceState mySourceState;
+    public final OutputState myOutputState;
+
+    private PersistentStateData(@NotNull SourceState sourceState, @NotNull OutputState outputState) {
+      mySourceState = sourceState;
+      myOutputState = outputState;
+    }
+  }
+  
+  private class SourceItemDataDescriptor implements KeyDescriptor<KeyAndTargetData<Key>> {
+    private final KeyDescriptor<Key> myKeyDescriptor;
+
+    public SourceItemDataDescriptor(KeyDescriptor<Key> keyDescriptor) {
+      myKeyDescriptor = keyDescriptor;
+    }
+
+    @Override
+    public boolean isEqual(KeyAndTargetData<Key> val1, KeyAndTargetData<Key> val2) {
+      return val1.myTarget == val2.myTarget;
+    }
+
+    @Override
+    public int getHashCode(KeyAndTargetData<Key> value) {
+      return value.myTarget + 239 * myKeyDescriptor.getHashCode(value.myKey);
+    }
+
+    @Override
+    public void save(DataOutput out, KeyAndTargetData<Key> value) throws IOException {
+      out.writeInt(value.myTarget);
+      myKeyDescriptor.save(out, value.myKey);
+    }
+
+
+    @Override
+    public KeyAndTargetData<Key> read(DataInput in) throws IOException {
+      int target = in.readInt();
+      final Key item = myKeyDescriptor.read(in);
+      return getKeyAndTargetData(item, target);
+    }
+  }
+
+  private class PersistentStateDataExternalizer implements DataExternalizer<PersistentStateData<SourceState, OutputState>> {
+    private DataExternalizer<SourceState> mySourceStateExternalizer;
+    private DataExternalizer<OutputState> myOutputStateExternalizer;
+
+    public PersistentStateDataExternalizer(GenericCompiler<Key,SourceState,OutputState> compiler) {
+      mySourceStateExternalizer = compiler.getSourceStateExternalizer();
+      myOutputStateExternalizer = compiler.getOutputStateExternalizer();
+    }
+
+    @Override
+    public void save(DataOutput out, PersistentStateData<SourceState, OutputState> value) throws IOException {
+      mySourceStateExternalizer.save(out, value.mySourceState);
+      myOutputStateExternalizer.save(out, value.myOutputState);
+    }
+
+    @Override
+    public PersistentStateData<SourceState, OutputState> read(DataInput in) throws IOException {
+      SourceState sourceState = mySourceStateExternalizer.read(in);
+      OutputState outputState = myOutputStateExternalizer.read(in);
+      return new PersistentStateData<SourceState,OutputState>(sourceState, outputState);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerPersistentData.java b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerPersistentData.java
new file mode 100644
index 0000000..513be6c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/generic/GenericCompilerPersistentData.java
@@ -0,0 +1,119 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.generic;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.io.IOUtil;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class GenericCompilerPersistentData {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.generic.GenericCompilerPersistentData");
+  private static final int VERSION = 1;
+  private File myFile;
+  private Map<String, Integer> myTarget2Id = new HashMap<String, Integer>();
+  private TIntHashSet myUsedIds = new TIntHashSet();
+  private boolean myVersionChanged;
+  private final int myCompilerVersion;
+
+  public GenericCompilerPersistentData(File cacheStoreDirectory, int compilerVersion) throws IOException {
+    myCompilerVersion = compilerVersion;
+    myFile = new File(cacheStoreDirectory, "info");
+    if (!myFile.exists()) {
+      LOG.info("Compiler info file doesn't exists: " + myFile.getAbsolutePath());
+      myVersionChanged = true;
+      return;
+    }
+
+    DataInputStream input = new DataInputStream(new BufferedInputStream(new FileInputStream(myFile)));
+    try {
+      final int dataVersion = input.readInt();
+      if (dataVersion != VERSION) {
+        LOG.info("Version of compiler info file (" + myFile.getAbsolutePath() + ") changed: " + dataVersion + " -> " + VERSION);
+        myVersionChanged = true;
+        return;
+      }
+
+      final int savedCompilerVersion = input.readInt();
+      if (savedCompilerVersion != compilerVersion) {
+        LOG.info("Compiler caches version changed (" + myFile.getAbsolutePath() + "): " + savedCompilerVersion + " -> " + compilerVersion);
+        myVersionChanged = true;
+        return;
+      }
+
+      int size = input.readInt();
+      while (size-- > 0) {
+        final String target = IOUtil.readString(input);
+        final int id = input.readInt();
+        myTarget2Id.put(target, id);
+        myUsedIds.add(id);
+      }
+    }
+    finally {
+      input.close();
+    }
+  }
+
+  public boolean isVersionChanged() {
+    return myVersionChanged;
+  }
+
+  public void save() throws IOException {
+    final DataOutputStream output = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(myFile)));
+    try {
+      output.writeInt(VERSION);
+      output.writeInt(myCompilerVersion);
+      output.writeInt(myTarget2Id.size());
+
+      for (Map.Entry<String, Integer> entry : myTarget2Id.entrySet()) {
+        IOUtil.writeString(entry.getKey(), output);
+        output.writeInt(entry.getValue());
+      }
+    }
+    finally {
+      output.close();
+    }
+  }
+
+  public int getId(@NotNull String target) {
+    if (myTarget2Id.containsKey(target)) {
+      return myTarget2Id.get(target);
+    }
+    int id = 0;
+    while (myUsedIds.contains(id)) {
+      id++;
+    }
+    myTarget2Id.put(target, id);
+    myUsedIds.add(id);
+    return id;
+  }
+
+  public Set<String> getAllTargets() {
+    return myTarget2Id.keySet();
+  }
+
+  public int removeId(String target) {
+    return myTarget2Id.remove(target);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java
new file mode 100644
index 0000000..c7269a4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/AnnotationProcessingCompiler.java
@@ -0,0 +1,151 @@
+/*
+ * 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: Jan 17, 2003
+ * Time: 3:22:59 PM
+ */
+package com.intellij.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerException;
+import com.intellij.compiler.impl.CompileContextExProxy;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+public class AnnotationProcessingCompiler implements TranslatingCompiler{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompiler");
+  private final Project myProject;
+  private final CompilerConfiguration myConfig;
+
+  public AnnotationProcessingCompiler(Project project) {
+    myProject = project;
+    myConfig = CompilerConfiguration.getInstance(project);
+  }
+
+  @NotNull
+  public String getDescription() {
+    return CompilerBundle.message("annotation.processing.compiler.description");
+  }
+
+  public boolean isCompilableFile(VirtualFile file, CompileContext context) {
+    if (!context.isAnnotationProcessorsEnabled()) {
+      return false;
+    } 
+    return file.getFileType() == StdFileTypes.JAVA && !isExcludedFromAnnotationProcessing(file, context);
+  }
+
+  public void compile(final CompileContext context, final Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
+    if (!context.isAnnotationProcessorsEnabled()) {
+      return;
+    }
+    final LocalFileSystem lfs = LocalFileSystem.getInstance();
+    final CompileContextEx _context = new CompileContextExProxy((CompileContextEx)context) {
+      public VirtualFile getModuleOutputDirectory(Module module) {
+        final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+        return path != null? lfs.findFileByPath(path) : null;
+      }
+
+      public VirtualFile getModuleOutputDirectoryForTests(Module module) {
+        return getModuleOutputDirectory(module);
+      }
+    };
+    final JavacCompiler javacCompiler = getBackEndCompiler();
+    final boolean processorMode = javacCompiler.setAnnotationProcessorMode(true);
+    final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), _context, javacCompiler, sink);
+    wrapper.setForceCompileTestsSeparately(true);
+    try {
+      wrapper.compile();
+    }
+    catch (CompilerException e) {
+      _context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+    }
+    catch (CacheCorruptedException e) {
+      LOG.info(e);
+      _context.requestRebuildNextTime(e.getMessage());
+    }
+    finally {
+      javacCompiler.setAnnotationProcessorMode(processorMode);
+      final Set<VirtualFile> dirsToRefresh = new HashSet<VirtualFile>();
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          for (Module module : moduleChunk.getNodes()) {
+            final VirtualFile out = _context.getModuleOutputDirectory(module);
+            if (out != null) {
+              dirsToRefresh.add(out);
+            }
+          }
+        }
+      });
+      for (VirtualFile root : dirsToRefresh) {
+        root.refresh(false, true);
+      }
+    }
+  }
+
+  private boolean isExcludedFromAnnotationProcessing(VirtualFile file, CompileContext context) {
+    if (!context.isAnnotationProcessorsEnabled()) {
+      return true;
+    }
+    final Module module = context.getModuleByFile(file);
+    if (module != null) {
+      if (!myConfig.getAnnotationProcessingConfiguration(module).isEnabled()) {
+        return true;
+      }
+      final String path = CompilerPaths.getAnnotationProcessorsGenerationPath(module);
+      final VirtualFile generationDir = path != null? LocalFileSystem.getInstance().findFileByPath(path) : null;
+      if (generationDir != null && VfsUtil.isAncestor(generationDir, file, false)) {
+        return true;
+      }
+    }
+    return myConfig.isExcludedFromCompilation(file);
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    final JavacCompiler compiler = getBackEndCompiler();
+    final boolean previousValue = compiler.setAnnotationProcessorMode(true);
+    try {
+      return compiler.checkCompiler(scope);
+    }
+    finally {
+      compiler.setAnnotationProcessorMode(previousValue);
+    }
+  }
+
+  private JavacCompiler getBackEndCompiler() {
+    CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)myConfig;
+    return configuration.getJavacCompiler();
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.java
new file mode 100644
index 0000000..9da4a39
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompiler.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.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.options.Configurable;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.Set;
+
+public interface BackendCompiler {
+  ExtensionPointName<BackendCompiler> EP_NAME = ExtensionPointName.create("com.intellij.java.compiler");
+
+  @NotNull @NonNls String getId(); // used for externalization
+  @NotNull String getPresentableName();
+  @NotNull Configurable createConfigurable();
+  @NotNull Set<FileType> getCompilableFileTypes();
+  @Nullable OutputParser createErrorParser(@NotNull String outputDir, Process process);
+  @Nullable OutputParser createOutputParser(@NotNull String outputDir);
+
+  boolean checkCompiler(final CompileScope scope);
+
+  @NotNull Process launchProcess(
+    @NotNull ModuleChunk chunk,
+    @NotNull String outputDir,
+    @NotNull CompileContext compileContext) throws IOException;
+
+  void compileFinished();
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java
new file mode 100644
index 0000000..a6567a5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/BackendCompilerWrapper.java
@@ -0,0 +1,1014 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.compiler.*;
+import com.intellij.compiler.classParsing.AnnotationConstantValue;
+import com.intellij.compiler.classParsing.MethodInfo;
+import com.intellij.compiler.impl.CompileDriver;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.make.Cache;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.compiler.make.MakeUtil;
+import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
+import com.intellij.ide.util.projectWizard.JavaModuleBuilder;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.module.JavaModuleType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.*;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScopes;
+import com.intellij.util.Chunk;
+import com.intellij.util.cls.ClsFormatException;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.asm4.ClassReader;
+import org.jetbrains.asm4.ClassWriter;
+
+import java.io.File;
+import java.io.IOException;
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.concurrent.ArrayBlockingQueue;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * @author Eugene Zhuravlev
+ * @since Jan 24, 2003
+ */
+public class BackendCompilerWrapper {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.BackendCompilerWrapper");
+
+  private final BackendCompiler myCompiler;
+
+  private final CompileContextEx myCompileContext;
+  private final List<VirtualFile> myFilesToCompile;
+  private final TranslatingCompiler.OutputSink mySink;
+  private final Chunk<Module> myChunk;
+  private final Project myProject;
+  private final Map<Module, VirtualFile> myModuleToTempDirMap = new THashMap<Module, VirtualFile>();
+  private final ProjectFileIndex myProjectFileIndex;
+  @NonNls private static final String PACKAGE_ANNOTATION_FILE_NAME = "package-info.java";
+  private static final FileObject myStopThreadToken = new FileObject(new File(""), new byte[0]);
+  public final Map<String, Set<CompiledClass>> myFileNameToSourceMap=  new THashMap<String, Set<CompiledClass>>();
+  private final Set<VirtualFile> myProcessedPackageInfos = new HashSet<VirtualFile>();
+  private final CompileStatistics myStatistics;
+  private volatile String myModuleName = null;
+  private boolean myForceCompileTestsSeparately = false;
+
+  public BackendCompilerWrapper(Chunk<Module> chunk, @NotNull final Project project,
+                                @NotNull List<VirtualFile> filesToCompile,
+                                @NotNull CompileContextEx compileContext,
+                                @NotNull BackendCompiler compiler, TranslatingCompiler.OutputSink sink) {
+    myChunk = chunk;
+    myProject = project;
+    myCompiler = compiler;
+    myCompileContext = compileContext;
+    myFilesToCompile = filesToCompile;
+    mySink = sink;
+    myProjectFileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+    CompileStatistics stat = compileContext.getUserData(CompileStatistics.KEY);
+    if (stat == null) {
+      stat = new CompileStatistics();
+      compileContext.putUserData(CompileStatistics.KEY, stat);
+    }
+    myStatistics = stat;
+  }
+
+  public void compile() throws CompilerException, CacheCorruptedException {
+    Application application = ApplicationManager.getApplication();
+    try {
+      if (!myFilesToCompile.isEmpty()) {
+        if (application.isUnitTestMode()) {
+          saveTestData();
+        }
+        compileModules(buildModuleToFilesMap(myFilesToCompile));
+      }
+    }
+    catch (SecurityException e) {
+      throw new CompilerException(CompilerBundle.message("error.compiler.process.not.started", e.getMessage()), e);
+    }
+    catch (IllegalArgumentException e) {
+      throw new CompilerException(e.getMessage(), e);
+    }
+    finally {
+      for (final VirtualFile file : myModuleToTempDirMap.values()) {
+        if (file != null) {
+          final File ioFile = new File(file.getPath());
+          FileUtil.asyncDelete(ioFile);
+        }
+      }
+      myModuleToTempDirMap.clear();
+    }
+
+    if (!myFilesToCompile.isEmpty() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
+      // package-info.java hack
+      final List<TranslatingCompiler.OutputItem> outputs = new ArrayList<TranslatingCompiler.OutputItem>();
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          for (final VirtualFile file : myFilesToCompile) {
+            if (PACKAGE_ANNOTATION_FILE_NAME.equals(file.getName()) && !myProcessedPackageInfos.contains(file)) {
+              outputs.add(new OutputItemImpl(file));
+            }
+          }
+        }
+      });
+      if (!outputs.isEmpty()) {
+        mySink.add(null, outputs, VirtualFile.EMPTY_ARRAY);
+      }
+    }
+  }
+
+  public boolean isForceCompileTestsSeparately() {
+    return myForceCompileTestsSeparately;
+  }
+
+  public void setForceCompileTestsSeparately(boolean forceCompileTestsSeparately) {
+    myForceCompileTestsSeparately = forceCompileTestsSeparately;
+  }
+
+  private Map<Module, List<VirtualFile>> buildModuleToFilesMap(final List<VirtualFile> filesToCompile) {
+    if (myChunk.getNodes().size() == 1) {
+      return Collections.singletonMap(myChunk.getNodes().iterator().next(), Collections.unmodifiableList(filesToCompile));
+    }
+    return CompilerUtil.buildModuleToFilesMap(myCompileContext, filesToCompile);
+  }
+
+  private void compileModules(final Map<Module, List<VirtualFile>> moduleToFilesMap) throws CompilerException {
+    try {
+      compileChunk(new ModuleChunk(myCompileContext, myChunk, moduleToFilesMap));
+    }
+    catch (IOException e) {
+      throw new CompilerException(e.getMessage(), e);
+    }
+  }
+
+  private void compileChunk(ModuleChunk chunk) throws IOException {
+    final String chunkPresentableName = getPresentableNameFor(chunk);
+    myModuleName = chunkPresentableName;
+
+    // validate encodings
+    if (chunk.getModuleCount() > 1) {
+      validateEncoding(chunk, chunkPresentableName);
+      // todo: validation for bytecode target?
+    }
+
+    runTransformingCompilers(chunk);
+
+
+    final List<OutputDir> outs = new ArrayList<OutputDir>();
+    File fileToDelete = getOutputDirsToCompileTo(chunk, outs);
+
+    try {
+      for (final OutputDir outputDir : outs) {
+        chunk.setSourcesFilter(outputDir.getKind());
+        doCompile(chunk, outputDir.getPath());
+      }
+    }
+    finally {
+      if (fileToDelete != null) {
+        FileUtil.asyncDelete(fileToDelete);
+      }
+    }
+  }
+
+  private void validateEncoding(ModuleChunk chunk, String chunkPresentableName) {
+    final CompilerEncodingService es = CompilerEncodingService.getInstance(myProject);
+    Charset charset = null;
+    for (Module module : chunk.getModules()) {
+      final Charset moduleCharset = es.getPreferredModuleEncoding(module);
+      if (charset == null) {
+        charset = moduleCharset;
+      }
+      else {
+        if (!Comparing.equal(charset, moduleCharset)) {
+          // warn user
+          final Charset chunkEncoding = CompilerEncodingService.getPreferredModuleEncoding(chunk);
+          final StringBuilder message = new StringBuilder();
+          message.append("Modules in chunk [");
+          message.append(chunkPresentableName);
+          message.append("] configured to use different encodings.\n");
+          if (chunkEncoding != null) {
+            message.append("\"").append(chunkEncoding.name()).append("\" encoding will be used to compile the chunk");
+          }
+          else {
+            message.append("Default compiler encoding will be used to compile the chunk");
+          }
+          myCompileContext.addMessage(CompilerMessageCategory.INFORMATION, message.toString(), null, -1, -1);
+          break;
+        }
+      }
+    }
+  }
+
+
+  private static String getPresentableNameFor(final ModuleChunk chunk) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      public String compute() {
+        final Module[] modules = chunk.getModules();
+        StringBuilder moduleName = new StringBuilder(Math.min(128, modules.length * 8));
+        for (int idx = 0; idx < modules.length; idx++) {
+          final Module module = modules[idx];
+          if (idx > 0) {
+            moduleName.append(", ");
+          }
+          moduleName.append(module.getName());
+          if (moduleName.length() > 128 && idx + 1 < modules.length /*name is already too long and seems to grow longer*/) {
+            moduleName.append("...");
+            break;
+          }
+        }
+        return moduleName.toString();
+      }
+    });
+  }
+
+  @Nullable
+  private File getOutputDirsToCompileTo(ModuleChunk chunk, final List<OutputDir> dirs) throws IOException {
+    File fileToDelete = null;
+    if (chunk.getModuleCount() == 1) { // optimization
+      final Module module = chunk.getModules()[0];
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          final String sourcesOutputDir = getOutputDir(module);
+          if (shouldCompileTestsSeparately(module)) {
+            if (sourcesOutputDir != null) {
+              dirs.add(new OutputDir(sourcesOutputDir, ModuleChunk.SOURCES));
+            }
+            final String testsOutputDir = getTestsOutputDir(module);
+            if (testsOutputDir == null) {
+              LOG.error("Tests output dir is null for module \"" + module.getName() + "\"");
+            }
+            else {
+              dirs.add(new OutputDir(testsOutputDir, ModuleChunk.TEST_SOURCES));
+            }
+          }
+          else { // both sources and test sources go into the same output
+            if (sourcesOutputDir == null) {
+              LOG.error("Sources output dir is null for module \"" + module.getName() + "\"");
+            }
+            else {
+              dirs.add(new OutputDir(sourcesOutputDir, ModuleChunk.ALL_SOURCES));
+            }
+          }
+        }
+      });
+    }
+    else { // chunk has several modules
+      final File outputDir = FileUtil.createTempDirectory("compile", "output");
+      fileToDelete = outputDir;
+      dirs.add(new OutputDir(outputDir.getPath(), ModuleChunk.ALL_SOURCES));
+    }
+    return fileToDelete;
+  }
+
+
+  private boolean shouldCompileTestsSeparately(Module module) {
+    if (myForceCompileTestsSeparately) {
+      return true;
+    }
+    final String moduleTestOutputDirectory = getTestsOutputDir(module);
+    if (moduleTestOutputDirectory == null) {
+      return false;
+    }
+    // here we have test output specified
+    final String moduleOutputDirectory = getOutputDir(module);
+    if (moduleOutputDirectory == null) {
+      // only test output is specified, so should return true
+      return true;
+    }
+    return !FileUtil.pathsEqual(moduleTestOutputDirectory, moduleOutputDirectory);
+  }
+
+  private void saveTestData() {
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        for (VirtualFile file : myFilesToCompile) {
+          CompilerManagerImpl.addCompiledPath(file.getPath());
+        }
+      }
+    });
+  }
+
+  private final Object lock = new Object();
+
+  private class SynchedCompilerParsing extends CompilerParsingThread {
+    private final ClassParsingThread myClassParsingThread;
+
+    private SynchedCompilerParsing(Process process,
+                                  final CompileContext context,
+                                  OutputParser outputParser,
+                                  ClassParsingThread classParsingThread,
+                                  boolean readErrorStream,
+                                  boolean trimLines) {
+      super(process, outputParser, readErrorStream, trimLines,context);
+      myClassParsingThread = classParsingThread;
+    }
+
+    public void setProgressText(String text) {
+      synchronized (lock) {
+        super.setProgressText(text);
+      }
+    }
+
+    public void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
+      synchronized (lock) {
+        super.message(category, message, url, lineNum, columnNum);
+      }
+    }
+
+    public void fileProcessed(String path) {
+      synchronized (lock) {
+        sourceFileProcessed();
+      }
+    }
+
+    protected void processCompiledClass(final FileObject classFileToProcess) throws CacheCorruptedException {
+      synchronized (lock) {
+        myClassParsingThread.addPath(classFileToProcess);
+      }
+    }
+  }
+
+  private void doCompile(@NotNull final ModuleChunk chunk, @NotNull String outputDir) throws IOException {
+    myCompileContext.getProgressIndicator().checkCanceled();
+
+    if (ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        return chunk.getFilesToCompile().isEmpty() ? Boolean.TRUE : Boolean.FALSE;
+      }
+    }).booleanValue()) {
+      return; // should not invoke javac with empty sources list
+    }
+
+    ModuleType moduleType = ModuleType.get(chunk.getModules()[0]);
+    if ((chunk.getJdk() == null || !(chunk.getJdk().getSdkType() instanceof JavaSdkType)) &&
+        !(moduleType instanceof JavaModuleType || moduleType.createModuleBuilder() instanceof JavaModuleBuilder)) {
+      // TODO
+      // don't try to compile non-java type module
+      return;
+    }
+
+    int exitValue = 0;
+    try {
+      final Process process = myCompiler.launchProcess(chunk, outputDir, myCompileContext);
+      final long compilationStart = System.currentTimeMillis();
+      final ClassParsingThread classParsingThread = new ClassParsingThread(isJdk6(chunk.getJdk()), outputDir);
+      final Future<?> classParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(classParsingThread);
+
+      OutputParser errorParser = myCompiler.createErrorParser(outputDir, process);
+      CompilerParsingThread errorParsingThread = errorParser == null
+                                                 ? null
+                                                 : new SynchedCompilerParsing(process, myCompileContext, errorParser, classParsingThread,
+                                                                              true, errorParser.isTrimLines());
+      Future<?> errorParsingThreadFuture = null;
+      if (errorParsingThread != null) {
+        errorParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(errorParsingThread);
+      }
+
+      OutputParser outputParser = myCompiler.createOutputParser(outputDir);
+      CompilerParsingThread outputParsingThread = outputParser == null
+                                                  ? null
+                                                  : new SynchedCompilerParsing(process, myCompileContext, outputParser, classParsingThread,
+                                                                               false, outputParser.isTrimLines());
+      Future<?> outputParsingThreadFuture = null;
+      if (outputParsingThread != null) {
+        outputParsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(outputParsingThread);
+      }
+
+      try {
+        exitValue = process.waitFor();
+      }
+      catch (InterruptedException e) {
+        process.destroy();
+        exitValue = process.exitValue();
+      }
+      catch (Error e) {
+        process.destroy();
+        exitValue = process.exitValue();
+        throw e;
+      }
+      finally {
+        if (CompileDriver.ourDebugMode) {
+          System.out.println("Compiler exit code is " + exitValue);
+        }
+        if (errorParsingThread != null) {
+          errorParsingThread.setProcessTerminated(true);
+        }
+        if (outputParsingThread != null) {
+          outputParsingThread.setProcessTerminated(true);
+        }
+        joinThread(errorParsingThreadFuture);
+        joinThread(outputParsingThreadFuture);
+        classParsingThread.stopParsing();
+        joinThread(classParsingThreadFuture);
+
+        registerParsingException(outputParsingThread);
+        registerParsingException(errorParsingThread);
+        assert outputParsingThread == null || !outputParsingThread.processing;
+        assert errorParsingThread == null || !errorParsingThread.processing;
+        assert classParsingThread == null || !classParsingThread.processing;
+      }
+    }
+    finally {
+      compileFinished(exitValue, chunk, outputDir);
+      myModuleName = null;
+    }
+  }
+
+  private static void joinThread(final Future<?> threadFuture) {
+    if (threadFuture != null) {
+      try {
+        threadFuture.get();
+      }
+      catch (InterruptedException ignored) {
+        LOG.info("Thread interrupted", ignored);
+      }
+      catch (ExecutionException ignored) {
+        LOG.info("Thread interrupted", ignored);
+      }
+    }
+  }
+
+  private void registerParsingException(final CompilerParsingThread outputParsingThread) {
+    Throwable error = outputParsingThread == null ? null : outputParsingThread.getError();
+    if (error != null) {
+      String message = error.getMessage();
+      if (error instanceof CacheCorruptedException) {
+        myCompileContext.requestRebuildNextTime(message);
+      }
+      else {
+        myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
+      }
+    }
+  }
+
+  private void runTransformingCompilers(final ModuleChunk chunk) {
+    final JavaSourceTransformingCompiler[] transformers =
+      CompilerManager.getInstance(myProject).getCompilers(JavaSourceTransformingCompiler.class);
+    if (transformers.length == 0) {
+      return;
+    }
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Running transforming compilers...");
+    }
+    final Module[] modules = chunk.getModules();
+    for (final JavaSourceTransformingCompiler transformer : transformers) {
+      final Map<VirtualFile, VirtualFile> originalToCopyFileMap = new HashMap<VirtualFile, VirtualFile>();
+      final Application application = ApplicationManager.getApplication();
+      application.invokeAndWait(new Runnable() {
+        public void run() {
+          for (final Module module : modules) {
+            for (final VirtualFile file : chunk.getFilesToCompile(module)) {
+              final VirtualFile untransformed = chunk.getOriginalFile(file);
+              if (transformer.isTransformable(untransformed)) {
+                application.runWriteAction(new Runnable() {
+                  public void run() {
+                    try {
+                      // if untransformed != file, the file is already a (possibly transformed) copy of the original 'untransformed' file.
+                      // If this is the case, just use already created copy and do not copy file content once again
+                      final VirtualFile fileCopy = untransformed.equals(file)? createFileCopy(getTempDir(module), file) : file;
+                      originalToCopyFileMap.put(file, fileCopy);
+                    }
+                    catch (IOException e) {
+                      // skip it
+                    }
+                  }
+                });
+              }
+            }
+          }
+        }
+      }, myCompileContext.getProgressIndicator().getModalityState());
+
+      // do actual transform
+      for (final Module module : modules) {
+        final List<VirtualFile> filesToCompile = chunk.getFilesToCompile(module);
+        for (int j = 0; j < filesToCompile.size(); j++) {
+          final VirtualFile file = filesToCompile.get(j);
+          final VirtualFile fileCopy = originalToCopyFileMap.get(file);
+          if (fileCopy != null) {
+            final boolean ok = transformer.transform(myCompileContext, fileCopy, chunk.getOriginalFile(file));
+            if (ok) {
+              chunk.substituteWithTransformedVersion(module, j, fileCopy);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  private VirtualFile createFileCopy(VirtualFile tempDir, final VirtualFile file) throws IOException {
+    final String fileName = file.getName();
+    if (tempDir.findChild(fileName) != null) {
+      int idx = 0;
+      while (true) {
+        //noinspection HardCodedStringLiteral
+        final String dirName = "dir" + idx++;
+        final VirtualFile dir = tempDir.findChild(dirName);
+        if (dir == null) {
+          tempDir = tempDir.createChildDirectory(this, dirName);
+          break;
+        }
+        if (dir.findChild(fileName) == null) {
+          tempDir = dir;
+          break;
+        }
+      }
+    }
+    return VfsUtilCore.copyFile(this, file, tempDir);
+  }
+
+  private VirtualFile getTempDir(Module module) throws IOException {
+    VirtualFile tempDir = myModuleToTempDirMap.get(module);
+    if (tempDir == null) {
+      final String projectName = myProject.getName();
+      final String moduleName = module.getName();
+      File tempDirectory = FileUtil.createTempDirectory(projectName, moduleName);
+      tempDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempDirectory);
+      if (tempDir == null) {
+        LOG.error("Cannot locate temp directory " + tempDirectory.getPath());
+      }
+      myModuleToTempDirMap.put(module, tempDir);
+    }
+    return tempDir;
+  }
+
+  private void compileFinished(int exitValue, final ModuleChunk chunk, final String outputDir) {
+    if (exitValue != 0 && !myCompileContext.getProgressIndicator().isCanceled() && myCompileContext.getMessageCount(CompilerMessageCategory.ERROR) == 0) {
+      myCompileContext.addMessage(CompilerMessageCategory.ERROR, CompilerBundle.message("error.compiler.internal.error", exitValue), null, -1, -1);
+    }
+
+    myCompiler.compileFinished();
+    final List<File> toRefresh = new ArrayList<File>();
+    final Map<String, Collection<TranslatingCompiler.OutputItem>> results = new HashMap<String, Collection<TranslatingCompiler.OutputItem>>();
+    try {
+      final FileTypeManager typeManager = FileTypeManager.getInstance();
+      final String outputDirPath = outputDir.replace(File.separatorChar, '/');
+      try {
+        for (final Module module : chunk.getModules()) {
+          for (final VirtualFile root : chunk.getSourceRoots(module)) {
+            final String packagePrefix = myProjectFileIndex.getPackageNameByDirectory(root);
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Building output items for " + root.getPresentableUrl() + "; output dir = " + outputDirPath + "; packagePrefix = \"" + packagePrefix + "\"");
+            }
+            buildOutputItemsList(outputDirPath, module, root, typeManager, root, packagePrefix, toRefresh, results);
+          }
+        }
+      }
+      catch (CacheCorruptedException e) {
+        myCompileContext.requestRebuildNextTime(CompilerBundle.message("error.compiler.caches.corrupted"));
+        if (LOG.isDebugEnabled()) {
+          LOG.debug(e);
+        }
+      }
+    }
+    finally {
+      CompilerUtil.refreshIOFiles(toRefresh);
+      for (Iterator<Map.Entry<String, Collection<TranslatingCompiler.OutputItem>>> it = results.entrySet().iterator(); it.hasNext();) {
+        Map.Entry<String, Collection<TranslatingCompiler.OutputItem>> entry = it.next();
+        mySink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
+        it.remove(); // to free memory
+      }
+    }
+    myFileNameToSourceMap.clear(); // clear the map before the next use
+  }
+
+  private void buildOutputItemsList(final String outputDir, final Module module, VirtualFile from,
+                                    final FileTypeManager typeManager,
+                                    final VirtualFile sourceRoot,
+                                    final String packagePrefix, final List<File> filesToRefresh, final Map<String, Collection<TranslatingCompiler.OutputItem>> results) throws CacheCorruptedException {
+    final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
+    final ModuleFileIndex fileIndex = ModuleRootManager.getInstance(module).getFileIndex();
+    final GlobalSearchScope srcRootScope = GlobalSearchScope.moduleScope(module).intersectWith(
+        GlobalSearchScopes.directoryScope(myProject, sourceRoot, true));
+    
+    final ContentIterator contentIterator = new ContentIterator() {
+      public boolean processFile(final VirtualFile child) {
+        try {
+          if (child.isValid()) {
+            if (!child.isDirectory() && myCompiler.getCompilableFileTypes().contains(child.getFileType())) {
+              updateOutputItemsList(outputDir, child, sourceRoot, packagePrefix, filesToRefresh, results, srcRootScope);
+            }
+          }
+          return true;
+        }
+        catch (CacheCorruptedException e) {
+          exRef.set(e);
+          return false;
+        }
+      }
+    };
+    if (fileIndex.isInContent(from)) {
+      // use file index for iteration to handle 'inner modules' and excludes properly
+      fileIndex.iterateContentUnderDirectory(from, contentIterator);
+    }
+    else {
+      // seems to be a root for generated sources
+      VfsUtilCore.visitChildrenRecursively(from, new VirtualFileVisitor() {
+        @Override
+        public boolean visitFile(@NotNull VirtualFile file) {
+          if (!file.isDirectory()) {
+            contentIterator.processFile(file);
+          }
+          return true;
+        }
+      });
+    }
+    final CacheCorruptedException exc = exRef.get();
+    if (exc != null) {
+      throw exc;
+    }
+  }
+
+  private void putName(String sourceFileName, int classQName, String relativePathToSource, String pathToClass) {
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Registering [sourceFileName, relativePathToSource, pathToClass] = [" + sourceFileName + "; " + relativePathToSource +
+                "; " + pathToClass + "]");
+    }
+    Set<CompiledClass> paths = myFileNameToSourceMap.get(sourceFileName);
+
+    if (paths == null) {
+      paths = new HashSet<CompiledClass>();
+      myFileNameToSourceMap.put(sourceFileName, paths);
+    }
+    paths.add(new CompiledClass(classQName, relativePathToSource, pathToClass));
+  }
+
+  private void updateOutputItemsList(final String outputDir, final VirtualFile srcFile,
+                                     VirtualFile sourceRoot,
+                                     final String packagePrefix, final List<File> filesToRefresh,
+                                     Map<String, Collection<TranslatingCompiler.OutputItem>> results,
+                                     final GlobalSearchScope srcRootScope) throws CacheCorruptedException {
+    final Cache newCache = myCompileContext.getDependencyCache().getNewClassesCache();
+    final Set<CompiledClass> paths = myFileNameToSourceMap.get(srcFile.getName());
+    if (paths == null || paths.isEmpty()) {
+      return;
+    }
+    final String filePath = "/" + calcPackagePath(srcFile, sourceRoot, packagePrefix);
+    for (final CompiledClass cc : paths) {
+      myCompileContext.getProgressIndicator().checkCanceled();
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Checking [pathToClass; relPathToSource] = " + cc);
+      }
+      
+      boolean pathsEquals = FileUtil.pathsEqual(filePath, cc.relativePathToSource);
+      if (!pathsEquals) {
+        final String qName = myCompileContext.getDependencyCache().resolve(cc.qName);
+        if (qName != null) {
+          pathsEquals = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+            public Boolean compute() {
+              final JavaPsiFacade facade = JavaPsiFacade.getInstance(myProject);
+              PsiClass psiClass = facade.findClass(qName, srcRootScope);
+              if (psiClass == null) {
+                final int dollarIndex = qName.indexOf("$");
+                if (dollarIndex >= 0) {
+                  final String topLevelClassName = qName.substring(0, dollarIndex);
+                  psiClass = facade.findClass(topLevelClassName, srcRootScope);
+                }
+              }
+              if (psiClass != null) {
+                final VirtualFile vFile = psiClass.getContainingFile().getVirtualFile();
+                return vFile != null && vFile.equals(srcFile);
+              }
+              return false;
+            }
+          });
+        }
+      }
+      
+      if (pathsEquals) {
+        final String outputPath = cc.pathToClass.replace(File.separatorChar, '/');
+        final Pair<String, String> realLocation = moveToRealLocation(outputDir, outputPath, srcFile, filesToRefresh);
+        if (realLocation != null) {
+          Collection<TranslatingCompiler.OutputItem> outputs = results.get(realLocation.getFirst());
+          if (outputs == null) {
+            outputs = new ArrayList<TranslatingCompiler.OutputItem>();
+            results.put(realLocation.getFirst(), outputs);
+          }
+          outputs.add(new OutputItemImpl(realLocation.getSecond(), srcFile));
+          if (PACKAGE_ANNOTATION_FILE_NAME.equals(srcFile.getName())) {
+            myProcessedPackageInfos.add(srcFile);
+          }
+          if (CompilerConfiguration.MAKE_ENABLED) {
+            newCache.setPath(cc.qName, realLocation.getSecond());
+          }
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Added output item: [outputDir; outputPath; sourceFile]  = [" + realLocation.getFirst() + "; " +
+                      realLocation.getSecond() + "; " + srcFile.getPresentableUrl() + "]");
+          }
+        }
+        else {
+          myCompileContext.addMessage(CompilerMessageCategory.ERROR, "Failed to copy from temporary location to output directory: " + outputPath + " (see idea.log for details)", null, -1, -1);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Failed to move to real location: " + outputPath + "; from " + outputDir);
+          }
+        }
+      }
+    }
+  }
+
+  /**
+   *
+   * @param srcFile
+   * @param sourceRoot
+   * @param packagePrefix
+   * @return A 'package'-path to a given src file relative to a specified root. "/" slashes must be used
+   */
+  protected static String calcPackagePath(VirtualFile srcFile, VirtualFile sourceRoot, String packagePrefix) {
+    final String prefix = packagePrefix != null && packagePrefix.length() > 0 ? packagePrefix.replace('.', '/') + "/" : "";
+    return prefix + VfsUtilCore.getRelativePath(srcFile, sourceRoot, '/');
+  }
+
+  @Nullable
+  private Pair<String, String> moveToRealLocation(String tempOutputDir, String pathToClass, VirtualFile sourceFile, final List<File> filesToRefresh) {
+    final Module module = myCompileContext.getModuleByFile(sourceFile);
+    if (module == null) {
+      final String message =
+        "Cannot determine module for source file: " + sourceFile.getPresentableUrl() + ";\nCorresponding output file: " + pathToClass;
+      LOG.info(message);
+      myCompileContext.addMessage(CompilerMessageCategory.WARNING, message, sourceFile.getUrl(), -1, -1);
+      // do not move: looks like source file has been invalidated, need recompilation
+      return new Pair<String, String>(tempOutputDir, pathToClass);
+    }
+    final String realOutputDir;
+    if (myCompileContext.isInTestSourceContent(sourceFile)) {
+      realOutputDir = getTestsOutputDir(module);
+      LOG.assertTrue(realOutputDir != null);
+    }
+    else {
+      realOutputDir = getOutputDir(module);
+      LOG.assertTrue(realOutputDir != null);
+    }
+
+    if (FileUtil.pathsEqual(tempOutputDir, realOutputDir)) { // no need to move
+      filesToRefresh.add(new File(pathToClass));
+      return new Pair<String, String>(realOutputDir, pathToClass);
+    }
+
+    final String realPathToClass = realOutputDir + pathToClass.substring(tempOutputDir.length());
+    final File fromFile = new File(pathToClass);
+    final File toFile = new File(realPathToClass);
+
+    boolean success = fromFile.renameTo(toFile);
+    if (!success) {
+      // assuming cause of the fail: intermediate dirs do not exist
+      FileUtil.createParentDirs(toFile);
+      // retry after making non-existent dirs
+      success = fromFile.renameTo(toFile);
+    }
+    if (!success) { // failed to move the file: e.g. because source and destination reside on different mountpoints.
+      try {
+        FileUtil.copy(fromFile, toFile);
+        FileUtil.delete(fromFile);
+        success = true;
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        success = false;
+      }
+    }
+    if (success) {
+      filesToRefresh.add(toFile);
+      return new Pair<String, String>(realOutputDir, realPathToClass);
+    }
+    return null;
+  }
+
+  private final Map<Module, String> myModuleToTestsOutput = new HashMap<Module, String>();
+
+  private String getTestsOutputDir(final Module module) {
+    if (myModuleToTestsOutput.containsKey(module)) {
+      return myModuleToTestsOutput.get(module);
+    }
+    final VirtualFile outputDirectory = myCompileContext.getModuleOutputDirectoryForTests(module);
+    final String out = outputDirectory != null? outputDirectory.getPath() : null;
+    myModuleToTestsOutput.put(module, out);
+    return out;
+  }
+
+  private final Map<Module, String> myModuleToOutput = new HashMap<Module, String>();
+
+  private String getOutputDir(final Module module) {
+    if (myModuleToOutput.containsKey(module)) {
+      return myModuleToOutput.get(module);
+    }
+    final VirtualFile outputDirectory = myCompileContext.getModuleOutputDirectory(module);
+    final String out = outputDirectory != null? outputDirectory.getPath() : null;
+    myModuleToOutput.put(module, out);
+    return out;
+  }
+
+  private void sourceFileProcessed() {
+    myStatistics.incFilesCount();
+    updateStatistics();
+  }
+
+  private void updateStatistics() {
+    final String msg;
+    String moduleName = myModuleName;
+    if (moduleName != null) {
+      msg = CompilerBundle.message("statistics.files.classes.module", myStatistics.getFilesCount(), myStatistics.getClassesCount(), moduleName);
+    }
+    else {
+      msg = CompilerBundle.message("statistics.files.classes", myStatistics.getFilesCount(), myStatistics.getClassesCount());
+    }
+    myCompileContext.getProgressIndicator().setText2(msg);
+    //myCompileContext.getProgressIndicator().setFraction(1.0* myProcessedFilesCount /myTotalFilesToCompile);
+  }
+
+  private class ClassParsingThread implements Runnable {
+    private final BlockingQueue<FileObject> myPaths = new ArrayBlockingQueue<FileObject>(50000);
+    private CacheCorruptedException myError = null;
+    private final boolean myAddNotNullAssertions;
+    private final boolean myIsJdk16;
+    private final String myOutputDir;
+
+    private ClassParsingThread(final boolean isJdk16, String outputDir) {
+      myIsJdk16 = isJdk16;
+      myOutputDir = FileUtil.toSystemIndependentName(outputDir);
+      myAddNotNullAssertions = CompilerConfiguration.getInstance(myProject).isAddNotNullAssertions();
+    }
+
+    private volatile boolean processing;
+    public void run() {
+      processing = true;
+      try {
+        while (true) {
+          FileObject path = myPaths.take();
+
+          if (path == myStopThreadToken) {
+            break;
+          }
+          processPath(path, myProject);
+        }
+      }
+      catch (InterruptedException e) {
+        LOG.error(e);
+      }
+      catch (CacheCorruptedException e) {
+        myError = e;
+      }
+      finally {
+        processing = false;
+      }
+    }
+
+    public void addPath(FileObject path) throws CacheCorruptedException {
+      if (myError != null) {
+        throw myError;
+      }
+      myPaths.offer(path);
+    }
+
+    public void stopParsing() {
+      myPaths.offer(myStopThreadToken);
+    }
+
+    private void processPath(FileObject fileObject, Project project) throws CacheCorruptedException {
+      File file = fileObject.getFile();
+      final String path = file.getPath();
+      try {
+        if (CompilerConfiguration.MAKE_ENABLED) {
+          byte[] fileContent = fileObject.getContent();
+          // the file is assumed to exist!
+          final DependencyCache dependencyCache = myCompileContext.getDependencyCache();
+          final int newClassQName = dependencyCache.reparseClassFile(file, fileContent);
+          final Cache newClassesCache = dependencyCache.getNewClassesCache();
+          final String sourceFileName = newClassesCache.getSourceFileName(newClassQName);
+          final String qName = dependencyCache.resolve(newClassQName);
+          String relativePathToSource = "/" + MakeUtil.createRelativePathToSource(qName, sourceFileName);
+          putName(sourceFileName, newClassQName, relativePathToSource, path);
+          boolean haveToInstrument = myAddNotNullAssertions && hasNotNullAnnotations(newClassesCache, dependencyCache.getSymbolTable(), newClassQName, project);
+
+          if (haveToInstrument) {
+            try {
+              ClassReader reader = new ClassReader(fileContent, 0, fileContent.length);
+              ClassWriter writer = new PsiClassWriter(myProject, myIsJdk16);
+
+              final NotNullVerifyingInstrumenter instrumenter = new NotNullVerifyingInstrumenter(writer);
+              reader.accept(instrumenter, 0);
+              if (instrumenter.isModification()) {
+                fileObject = new FileObject(file, writer.toByteArray());
+              }
+            }
+            catch (Exception ignored) {
+              LOG.info(ignored);
+            }
+          }
+
+          fileObject.save();
+        }
+        else {
+          final String _path = FileUtil.toSystemIndependentName(path);
+          final int dollarIndex = _path.indexOf('$');
+          final int tailIndex = dollarIndex >=0 ? dollarIndex : _path.length() - ".class".length();
+          final int slashIndex = _path.lastIndexOf('/');
+          final String sourceFileName = _path.substring(slashIndex + 1, tailIndex) + ".java";
+          String relativePathToSource = _path.substring(myOutputDir.length(), tailIndex) + ".java";
+          putName(sourceFileName, 0 /*doesn't matter here*/ , relativePathToSource.startsWith("/")? relativePathToSource : "/" + relativePathToSource, path);
+        }
+      }
+      catch (ClsFormatException e) {
+        final String m = e.getMessage();
+        String message = CompilerBundle.message("error.bad.class.file.format", StringUtil.isEmpty(m) ? path : m + "\n" + path);
+        myCompileContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
+        LOG.info(e);
+      }
+      catch (IOException e) {
+        myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+        LOG.info(e);
+      }
+      finally {
+        myStatistics.incClassesCount();
+        updateStatistics();
+      }
+    }
+  }
+
+  private static boolean hasNotNullAnnotations(final Cache cache, final SymbolTable symbolTable, final int className, Project project) throws CacheCorruptedException {
+    final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
+    final List<String> notNulls = manager.getNotNulls();
+    for (MethodInfo methodId : cache.getMethods(className)) {
+      for (AnnotationConstantValue annotation : methodId.getRuntimeInvisibleAnnotations()) {
+        if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) {
+          return true;
+        }
+      }
+      final AnnotationConstantValue[][] paramAnnotations = methodId.getRuntimeInvisibleParameterAnnotations();
+      for (AnnotationConstantValue[] _singleParamAnnotations : paramAnnotations) {
+        for (AnnotationConstantValue annotation : _singleParamAnnotations) {
+          if (notNulls.contains(symbolTable.getSymbol(annotation.getAnnotationQName()))) {
+            return true;
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private static boolean isJdk6(final Sdk jdk) {
+    return jdk != null && JavaSdk.getInstance().isOfVersionOrHigher(jdk, JavaSdkVersion.JDK_1_6);
+  }
+  
+  private static final class CompileStatistics {
+    private static final Key<CompileStatistics> KEY = Key.create("_Compile_Statistics_");
+    private int myClassesCount;
+    private int myFilesCount;
+
+    public int getClassesCount() {
+      return myClassesCount;
+    }
+
+    public int incClassesCount() {
+      return ++myClassesCount;
+    }
+
+    public int getFilesCount() {
+      return myFilesCount;
+    }
+
+    public int incFilesCount() {
+      return ++myFilesCount;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompiledClass.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompiledClass.java
new file mode 100644
index 0000000..4bfa519
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompiledClass.java
@@ -0,0 +1,56 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+/**
+* @author cdr
+*/
+final class CompiledClass {
+  public final int qName;
+  public final String relativePathToSource;
+  public final String pathToClass;
+
+  CompiledClass(final int qName, final String relativePathToSource, final String pathToClass) {
+    this.qName = qName;
+    this.relativePathToSource = relativePathToSource;
+    this.pathToClass = pathToClass;
+  }
+
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final CompiledClass that = (CompiledClass)o;
+
+    if (qName != that.qName) return false;
+    if (!pathToClass.equals(that.pathToClass)) return false;
+    if (!relativePathToSource.equals(that.relativePathToSource)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = qName;
+    result = 31 * result + relativePathToSource.hashCode();
+    result = 31 * result + pathToClass.hashCode();
+    return result;
+  }
+
+  public String toString() {
+    return "[" + pathToClass + ";" + relativePathToSource + "]";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java
new file mode 100644
index 0000000..38b6b2f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/CompilerParsingThread.java
@@ -0,0 +1,263 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompileDriver;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.SpinAllocator;
+import com.intellij.util.StringBuilderSpinAllocator;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class CompilerParsingThread implements Runnable, OutputParser.Callback {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompilerParsingThread");
+  @NonNls public static final String TERMINATION_STRING = "__terminate_read__";
+  private final Reader myCompilerOutStreamReader;
+  private Process myProcess;
+  private final OutputParser myOutputParser;
+  private final boolean myTrimLines;
+  private boolean mySkipLF = false;
+  private Throwable myError = null;
+  private final boolean myIsUnitTestMode;
+  private FileObject myClassFileToProcess = null;
+  private String myLastReadLine = null;
+  private String myPushBackLine = null;
+  private volatile boolean myProcessExited = false;
+  private final CompileContext myContext;
+  
+  public CompilerParsingThread(Process process, OutputParser outputParser, final boolean readErrorStream, boolean trimLines, CompileContext context) {
+    myProcess = process;
+    myOutputParser = outputParser;
+    myTrimLines = trimLines;
+    InputStream stream = readErrorStream ? process.getErrorStream() : process.getInputStream();
+    myCompilerOutStreamReader = stream == null ? null : new BufferedReader(new InputStreamReader(stream), 16384);
+    myIsUnitTestMode = ApplicationManager.getApplication().isUnitTestMode();
+    myContext = context;
+  }
+
+  volatile boolean processing;
+  public void run() {
+    processing = true;
+    try {
+      while (true) {
+        if (!myIsUnitTestMode && myProcess == null) {
+          break;
+        }
+        if (isCanceled()) {
+          break;
+        }
+        if (!myOutputParser.processMessageLine(this)) {
+          break;
+        }
+      }
+      if (myClassFileToProcess != null) {
+        processCompiledClass(myClassFileToProcess);
+        myClassFileToProcess = null;
+      }
+    }
+    catch (Throwable e) {
+      e.printStackTrace();
+      myError = e;
+      LOG.info(e);
+    }
+    finally {
+      killProcess();
+      processing = false;
+    }
+  }
+
+  private void killProcess() {
+    if (myProcess != null) {
+      myProcess.destroy();
+      myProcess = null;
+    }
+  }
+
+  public Throwable getError() {
+    return myError;
+  }
+
+  public String getCurrentLine() {
+    return myLastReadLine;
+  }
+
+  public final String getNextLine() {
+    final String pushBack = myPushBackLine;
+    if (pushBack != null) {
+      myPushBackLine = null;
+      myLastReadLine = pushBack;
+      return pushBack;
+    }
+    final String line = readLine(myCompilerOutStreamReader);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("LIne read: #" + line + "#");
+    }
+    if (CompileDriver.ourDebugMode) {
+      System.out.println("LIne read: #" + line + "#");
+    }
+    if (TERMINATION_STRING.equals(line)) {
+      myLastReadLine = null;
+    }
+    else {
+      myLastReadLine = line == null ? null : myTrimLines ? line.trim() : line;
+    }
+    return myLastReadLine;
+  }
+
+  @Override
+  public void pushBack(String line) {
+    myLastReadLine = null;
+    myPushBackLine = line;
+  }
+
+  public final void fileGenerated(FileObject path) {
+    // javac first logs file generated, then starts to write the file to disk,
+    // so this thread sometimes can stumble on not yet existing file,
+    // hence this complex logic
+    FileObject previousPath = myClassFileToProcess;
+    myClassFileToProcess = path;
+    if (previousPath != null) {
+      try {
+        processCompiledClass(previousPath);
+      }
+      catch (CacheCorruptedException e) {
+        if (CompileDriver.ourDebugMode) {
+          e.printStackTrace();
+        }
+        myError = e;
+        LOG.info(e);
+        killProcess();
+      }
+    }
+  }
+
+  protected boolean isCanceled() {
+    return myContext.getProgressIndicator().isCanceled();
+  }
+
+  public void setProgressText(String text) {
+    myContext.getProgressIndicator().setText(text);
+  }
+
+  public void fileProcessed(String path) {
+  }
+
+  public void message(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
+    myContext.addMessage(category, message, url, lineNum, columnNum);
+  }
+
+  protected void processCompiledClass(final FileObject classFileToProcess) throws CacheCorruptedException {
+  }
+
+
+  private String readLine(final Reader reader) {
+    StringBuilder buffer;
+    boolean releaseBuffer = true;
+    try {
+      buffer = StringBuilderSpinAllocator.alloc();
+    }
+    catch (SpinAllocator.AllocatorExhaustedException e) {
+      if (CompileDriver.ourDebugMode) {
+        e.printStackTrace();
+      }
+      LOG.info(e);
+      buffer = new StringBuilder();
+      releaseBuffer = false;
+    }
+
+    try {
+      boolean first = true;
+      while (true) {
+        int c = readNextByte(reader);
+        if (c == -1) break;
+        first = false;
+        if (c == '\n') {
+          if (mySkipLF) {
+            mySkipLF = false;
+            continue;
+          }
+          break;
+        }
+        else if (c == '\r') {
+          mySkipLF = true;
+          break;
+        }
+        else {
+          mySkipLF = false;
+          buffer.append((char)c);
+        }
+      }
+      if (first) {
+        return null;
+      }
+      return buffer.toString();
+    }
+    finally {
+      if (releaseBuffer) {
+        StringBuilderSpinAllocator.dispose(buffer);
+      }
+    }
+  }
+
+  private int readNextByte(final Reader reader) {
+    try {
+      while(!reader.ready()) {
+        if (isProcessTerminated()) {
+          if (reader.ready()) {
+            break;
+          }
+          return -1;
+        }
+        try {
+          Thread.sleep(1L);
+        }
+        catch (InterruptedException ignore) {
+        }
+      }
+      return reader.read();
+    }
+    catch (IOException e) {
+      if (CompileDriver.ourDebugMode) {
+        e.printStackTrace();
+      }
+      return -1; // When process terminated Process.getInputStream()'s underlying stream becomes closed on Linux.
+    }
+    catch (Throwable t) {
+      if (CompileDriver.ourDebugMode) {
+        t.printStackTrace();
+      }
+      return -1;
+    }
+  }
+
+  private boolean isProcessTerminated() {
+    return myProcessExited;
+  }
+
+  public void setProcessTerminated(final boolean procesExited) {
+    myProcessExited = procesExited;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java
new file mode 100644
index 0000000..5fd91b0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummySourceGeneratingCompiler.java
@@ -0,0 +1,137 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.SourceGeneratingCompiler;
+import com.intellij.openapi.compiler.ValidityState;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 9, 2004
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public class DummySourceGeneratingCompiler implements SourceGeneratingCompiler{
+  public static final String MODULE_NAME = "generated";
+  private final Project myProject;
+
+  public DummySourceGeneratingCompiler(Project project) {
+    myProject = project;
+  }
+
+  @Override
+  public VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile) {
+    return null;
+  }
+
+  public GenerationItem[] getGenerationItems(CompileContext context) {
+    final Module module = findMyModule();
+    return new GenerationItem[] {
+      new MyGenerationItem("aaa/p1.properties", module, false),
+      new MyGenerationItem("bbb/p2.properties", module, false),
+      new MyGenerationItem("bbb/ccc/p3.properties", module, false),
+      new MyGenerationItem("aaa/p1.properties", module, true),
+      new MyGenerationItem("bbb/p2-t.properties", module, true),
+      new MyGenerationItem("bbb/ccc/p3.properties", module, true)
+    };
+  }
+
+  private Module findMyModule() {
+    return ApplicationManager.getApplication().runReadAction(new Computable<Module>() {
+      public Module compute() {
+        Module[] modules = ModuleManager.getInstance(myProject).getModules();
+        for (Module module : modules) {
+          if (MODULE_NAME.equals(module.getName())) {
+            return module;
+          }
+        }
+        return null;
+      }
+    });
+  }
+
+  public GenerationItem[] generate(CompileContext context, GenerationItem[] items, final VirtualFile outputRootDirectory) {
+    final String rootPath = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      public String compute() {
+        return outputRootDirectory.getPath();
+      }
+    });
+    final List<GenerationItem> success = new ArrayList<GenerationItem>();
+    for (GenerationItem item1 : items) {
+      GenerationItem item = item1;
+      File file = new File(rootPath + File.separator + item.getPath());
+      FileUtil.createIfDoesntExist(file);
+      success.add(item);
+    }
+    return success.toArray(new GenerationItem[success.size()]);
+  }
+
+  @NotNull
+  public String getDescription() {
+    return "Dummy Source Generator";
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    return findMyModule() != null;
+  }
+
+  public ValidityState createValidityState(DataInput in) throws IOException {
+    return null;
+  }
+
+  private static class MyGenerationItem implements GenerationItem {
+    private final String myRelPath;
+    private final Module myModule;
+    private final boolean myIsTestSource;
+
+    public MyGenerationItem(String relPath, Module module, final boolean isTestSource) {
+      myRelPath = relPath;
+      myModule = module;
+      myIsTestSource = isTestSource;
+    }
+
+    public String getPath() {
+      return myRelPath;
+    }
+
+    public ValidityState getValidityState() {
+      return null;
+    }
+
+    public Module getModule() {
+      return myModule;
+    }
+
+    public boolean isTestSource() {
+      return myIsTestSource;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java
new file mode 100644
index 0000000..2931190
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTransformingCompiler.java
@@ -0,0 +1,78 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.JavaSourceTransformingCompiler;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+
+/**          
+ * @author Eugene Zhuravlev
+ *         Date: Jul 10, 2004
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public class DummyTransformingCompiler implements JavaSourceTransformingCompiler{
+  public boolean isTransformable(VirtualFile file) {
+    return "A.java".equals(file.getName());
+  }
+
+  public boolean transform(CompileContext context, final VirtualFile file, VirtualFile originalFile) {
+    System.out.println("DummyTransformingCompiler.transform");
+    final String url = ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      public String compute() {
+        return file.getPresentableUrl();
+      }
+    });
+    context.getProgressIndicator().setText("Transforming file: " + url);
+    try {
+      OutputStream os = new BufferedOutputStream(new FileOutputStream(new File(url)));
+      DataOutput out = new DataOutputStream(os);
+      out.writeBytes("package a; ");
+      out.writeBytes("public class A { public static void main(String[] args) { System.out.println(\"Hello from modified class\");} }");
+      os.close();
+      UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+        public void run() {
+          file.refresh(false, false);
+        }
+      });
+      return true;
+    }
+    catch (FileNotFoundException e) {
+      context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+    }
+    catch (IOException e) {
+      context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+    }
+    return false;
+  }
+
+  @NotNull
+  public String getDescription() {
+    return "a dummy compiler for testing";
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java
new file mode 100644
index 0000000..573b7e0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/DummyTranslatingCompiler.java
@@ -0,0 +1,93 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 4, 2007
+ */
+public class DummyTranslatingCompiler implements TranslatingCompiler, IntermediateOutputCompiler{
+  @NonNls private static final String DESCRIPTION = "DUMMY TRANSLATOR";
+  @NonNls private static final String FILETYPE_EXTENSION = ".dummy";
+
+  public boolean isCompilableFile(final VirtualFile file, final CompileContext context) {
+    return file.getName().endsWith(FILETYPE_EXTENSION);
+  }
+
+  public void compile(final CompileContext context, Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
+    final List<File> filesToRefresh = new ArrayList<File>();
+    final Map<String, Collection<OutputItem>> outputs = new HashMap<String, Collection<OutputItem>>();
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        for (final VirtualFile file : files) {
+          final Module module = context.getModuleByFile(file);
+          try {
+            final VirtualFile outputDir = context.getModuleOutputDirectory(module);
+            if (outputDir != null) {
+              final String outputDirPath = outputDir.getPath();
+              final File compiledFile = doCompile(outputDir, file);
+              filesToRefresh.add(compiledFile);
+              Collection<OutputItem> collection = outputs.get(outputDirPath);
+              if (collection == null) {
+                collection = new ArrayList<OutputItem>();
+                outputs.put(outputDirPath, collection);
+              }
+              collection.add(new OutputItemImpl(FileUtil.toSystemIndependentName(compiledFile.getPath()), file));
+            }
+          }
+          catch (IOException e) {
+            context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, 0, 0);
+          }
+        }
+      }
+    });
+    CompilerUtil.refreshIOFiles(filesToRefresh);
+    for (Map.Entry<String, Collection<OutputItem>> entry : outputs.entrySet()) {
+      sink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
+    }
+  }
+
+  private static File doCompile(VirtualFile out, VirtualFile src) throws IOException {
+    final String originalName = src.getName();
+    String compiledName = originalName.substring(0, originalName.length() - FILETYPE_EXTENSION.length());
+    final File destFile = new File(out.getPath(), compiledName + ".java");
+    FileUtil.copy(new File(src.getPath()), destFile);
+    return destFile;
+  }
+  
+  @NotNull
+  public String getDescription() {
+    return DESCRIPTION;
+  }
+
+  public boolean validateConfiguration(final CompileScope scope) {
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.java
new file mode 100644
index 0000000..9223cbd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ExternalCompiler.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.compiler.impl.javaCompiler;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.EnvironmentUtil;
+import com.intellij.util.StringBuilderSpinAllocator;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.IOException;
+import java.util.Collections;
+import java.util.Set;
+
+public abstract class ExternalCompiler implements BackendCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.ExternalCompiler");
+  private static final Set<FileType> COMPILABLE_TYPES = Collections.<FileType>singleton(StdFileTypes.JAVA);
+
+  @NotNull
+  public abstract String[] createStartupCommand(ModuleChunk chunk, CompileContext context, String outputPath)
+    throws IOException, IllegalArgumentException;
+
+  @NotNull
+  public Set<FileType> getCompilableFileTypes() {
+    return COMPILABLE_TYPES;
+  }
+
+  /**
+   * Checks if the compiler can compile the specified file.
+   *
+   * @param file    the file to check.
+   * @param context the context for the current compile operation.
+   * @return true if can compile the file, false otherwise. If the method returns false, <code>file</code>
+   *         will not be included in the list of files passed to {@link #compile(CompileContext, com.intellij.util.Chunk < com.intellij.openapi.module.Module >,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
+   */
+  public boolean isCompilableFile(VirtualFile file, CompileContext context) {
+    return getCompilableFileTypes().contains(file.getFileType());
+  }
+
+  @NotNull
+  public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
+    final String[] commands = createStartupCommand(chunk, compileContext, outputDir);
+
+    if (LOG.isDebugEnabled()) {
+      @NonNls final StringBuilder buf = StringBuilderSpinAllocator.alloc();
+      try {
+        buf.append("\n===================================Environment:===========================\n");
+        for (String pair : EnvironmentUtil.getEnvironment()) {
+          buf.append("\t").append(pair).append("\n");
+        }
+        buf.append("=============================================================================\n");
+        buf.append("Running compiler: ");
+        for (final String command : commands) {
+          buf.append(" ").append(command);
+        }
+
+        LOG.debug(buf.toString());
+      }
+      finally {
+        StringBuilderSpinAllocator.dispose(buf);
+      }
+    }
+
+    return Runtime.getRuntime().exec(commands);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java
new file mode 100644
index 0000000..4ce53a5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/FileObject.java
@@ -0,0 +1,73 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FileNotFoundException;
+import java.io.IOException;
+
+/**
+ * @author cdr
+ */
+public class FileObject {
+  private static final byte[] NOT_LOADED = ArrayUtil.EMPTY_BYTE_ARRAY;
+
+  private final File myFile;
+  private final byte[] myContent;
+
+  public FileObject(@NotNull File file, @NotNull byte[] content) {
+    myFile = file;
+    myContent = content;
+  }
+
+  public FileObject(File file) {
+    myFile = file;
+    myContent = NOT_LOADED;
+  }
+
+  public File getFile() {
+    return myFile;
+  }
+
+  public byte[] getContent() throws IOException {
+    if (myContent == NOT_LOADED) {
+      return FileUtil.loadFileBytes(myFile);
+    }
+    return myContent;
+  }
+
+  public void save() throws IOException {
+    if (myContent == NOT_LOADED) {
+      return; // already on disk
+    }
+    try {
+      FileUtil.writeToFile(myFile, myContent);
+    }
+    catch (FileNotFoundException e) {
+      FileUtil.createParentDirs(myFile);
+      FileUtil.writeToFile(myFile, myContent);
+    }
+  }
+
+  @Override
+  public String toString() {
+    return getFile().toString();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java
new file mode 100644
index 0000000..827c813
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/JavaCompiler.java
@@ -0,0 +1,94 @@
+/*
+ * 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: Jan 17, 2003
+ * Time: 3:22:59 PM
+ */
+package com.intellij.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerException;
+import com.intellij.compiler.impl.CompileDriver;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+
+public class JavaCompiler implements TranslatingCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.JavaCompiler");
+  private final Project myProject;
+
+  public JavaCompiler(Project project) {
+    myProject = project;
+  }
+
+  @NotNull
+  public String getDescription() {
+    return CompilerBundle.message("java.compiler.description");
+  }
+
+  public boolean isCompilableFile(VirtualFile file, CompileContext context) {
+    final BackendCompiler backEndCompiler = getBackEndCompiler();
+    if (backEndCompiler instanceof ExternalCompiler) {
+      return ((ExternalCompiler)backEndCompiler).isCompilableFile(file, context);
+    }
+    return backEndCompiler.getCompilableFileTypes().contains(file.getFileType());
+  }
+
+  public void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink) {
+    final BackendCompiler backEndCompiler = getBackEndCompiler();
+    final BackendCompilerWrapper wrapper = new BackendCompilerWrapper(moduleChunk, myProject, Arrays.asList(files), (CompileContextEx)context, backEndCompiler, sink);
+    try {
+      if (CompileDriver.ourDebugMode) {
+        System.out.println("Starting java compiler; with backend compiler: " + backEndCompiler.getClass().getName());
+      }
+      wrapper.compile();
+    }
+    catch (CompilerException e) {
+      if (CompileDriver.ourDebugMode) {
+        e.printStackTrace();
+      }
+      context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+      LOG.info(e);
+    }
+    catch (CacheCorruptedException e) {
+      if (CompileDriver.ourDebugMode) {
+        e.printStackTrace();
+      }
+      LOG.info(e);
+      context.requestRebuildNextTime(e.getMessage());
+    }
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    return getBackEndCompiler().checkCompiler(scope);
+  }
+
+  private BackendCompiler getBackEndCompiler() {
+    CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    return configuration.getDefaultCompiler();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java
new file mode 100644
index 0000000..864e4f8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/ModuleChunk.java
@@ -0,0 +1,343 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.module.LanguageLevelUtil;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.JdkOrderEntry;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.util.Chunk;
+import com.intellij.util.PathsList;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.OrderedSet;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Sep 29, 2004
+ */
+public class ModuleChunk extends Chunk<Module> {
+  private final CompileContextEx myContext;
+  private final Map<Module, List<VirtualFile>> myModuleToFilesMap = new THashMap<Module, List<VirtualFile>>();
+  private final Map<VirtualFile, VirtualFile> myTransformedToOriginalMap = new THashMap<VirtualFile, VirtualFile>();
+  private int mySourcesFilter = ALL_SOURCES;
+
+  public ModuleChunk(CompileContextEx context, Chunk<Module> chunk, Map<Module, List<VirtualFile>> moduleToFilesMap) {
+    super(chunk.getNodes());
+    myContext = context;
+    for (final Module module : chunk.getNodes()) {
+      final List<VirtualFile> files = moduleToFilesMap.get(module);
+      // Important!!! Collections in the myModuleToFilesMap must be modifiable copies of the corresponding collections
+      // from the moduleToFilesMap. This is needed to support SourceTransforming compilers
+      myModuleToFilesMap.put(module, files == null ? Collections.<VirtualFile>emptyList() : new ArrayList<VirtualFile>(files));
+    }
+  }
+
+  public static final int SOURCES = 0x1;
+  public static final int TEST_SOURCES = 0x2;
+  public static final int ALL_SOURCES = SOURCES | TEST_SOURCES;
+
+  public void setSourcesFilter(int filter) {
+    mySourcesFilter = filter;
+  }
+
+  public int getSourcesFilter() {
+    return mySourcesFilter;
+  }
+
+  public void substituteWithTransformedVersion(Module module, int fileIndex, VirtualFile transformedFile) {
+    final List<VirtualFile> moduleFiles = getFilesToCompile(module);
+    final VirtualFile currentFile = moduleFiles.get(fileIndex);
+    moduleFiles.set(fileIndex, transformedFile);
+    VirtualFile originalFile = myTransformedToOriginalMap.remove(currentFile);
+    if (originalFile == null) {
+      originalFile = currentFile;
+    }
+    myTransformedToOriginalMap.put(transformedFile, originalFile);
+  }
+
+  public VirtualFile getOriginalFile(VirtualFile file) {
+    final VirtualFile original = myTransformedToOriginalMap.get(file);
+    return original != null? original : file;
+  }
+
+  @NotNull
+  public List<VirtualFile> getFilesToCompile(Module forModule) {
+    return myModuleToFilesMap.get(forModule);
+  }
+
+  @NotNull
+  public List<VirtualFile> getFilesToCompile() {
+    if (getModuleCount() == 0) {
+      return Collections.emptyList();
+    }
+    final Set<Module> modules = getNodes();
+
+    final List<VirtualFile> filesToCompile = new ArrayList<VirtualFile>();
+    for (final Module module : modules) {
+      final List<VirtualFile> moduleCompilableFiles = getFilesToCompile(module);
+      if (mySourcesFilter == ALL_SOURCES) {
+        filesToCompile.addAll(moduleCompilableFiles);
+      }
+      else {
+        for (final VirtualFile file : moduleCompilableFiles) {
+          VirtualFile originalFile = myTransformedToOriginalMap.get(file);
+          if (originalFile == null) {
+            originalFile = file;
+          }
+          if (mySourcesFilter == TEST_SOURCES) {
+            if (myContext.isInTestSourceContent(originalFile)) {
+              filesToCompile.add(file);
+            }
+          }
+          else {
+            if (!myContext.isInTestSourceContent(originalFile)) {
+              filesToCompile.add(file);
+            }
+          }
+        }
+      }
+    }
+    return filesToCompile;
+  }
+
+  /**
+   * @return the jdk. Assumes that the jdk is the same for all modules
+   */
+  public Sdk getJdk() {
+    final Module module = getNodes().iterator().next();
+    return ModuleRootManager.getInstance(module).getSdk();
+  }
+
+  public VirtualFile[] getSourceRoots() {
+    return getSourceRoots(mySourcesFilter);
+  }
+
+  private VirtualFile[] getSourceRoots(final int sourcesFilter) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
+      public VirtualFile[] compute() {
+        return filterRoots(getAllSourceRoots(), getNodes().iterator().next().getProject(), sourcesFilter);
+      }
+    });
+  }
+
+  public VirtualFile[] getSourceRoots(final Module module) {
+    if (!getNodes().contains(module)) {
+      return VirtualFile.EMPTY_ARRAY;
+    }
+    return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile[]>() {
+      public VirtualFile[] compute() {
+        return filterRoots(myContext.getSourceRoots(module), module.getProject(), mySourcesFilter);
+      }
+    });
+  }
+
+  private VirtualFile[] filterRoots(VirtualFile[] roots, Project project, final int sourcesFilter) {
+    final List<VirtualFile> filteredRoots = new ArrayList<VirtualFile>(roots.length);
+    final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    for (final VirtualFile root : roots) {
+      if (sourcesFilter != ALL_SOURCES) {
+        if (myContext.isInTestSourceContent(root)) {
+          if ((sourcesFilter & TEST_SOURCES) == 0) {
+            continue;
+          }
+        }
+        else {
+          if ((sourcesFilter & SOURCES) == 0) {
+            continue;
+          }
+        }
+      }
+      if (compilerConfiguration.isExcludedFromCompilation(root)) {
+        continue;
+      }
+      filteredRoots.add(root);
+    }
+    return VfsUtil.toVirtualFileArray(filteredRoots);
+  }
+
+  private VirtualFile[] getAllSourceRoots() {
+    final Set<Module> modules = getNodes();
+    Set<VirtualFile> roots = new HashSet<VirtualFile>();
+    for (final Module module : modules) {
+      ContainerUtil.addAll(roots, myContext.getSourceRoots(module));
+    }
+    return VfsUtil.toVirtualFileArray(roots);
+  }
+
+  public String getCompilationClasspath() {
+    final OrderedSet<VirtualFile> cpFiles = getCompilationClasspathFiles();
+    return convertToStringPath(cpFiles);
+
+  }
+
+  public OrderedSet<VirtualFile> getCompilationClasspathFiles() {
+    return getCompilationClasspathFiles(true);
+  }
+
+  public OrderedSet<VirtualFile> getCompilationClasspathFiles(final boolean exportedOnly) {
+    final Set<Module> modules = getNodes();
+
+    OrderedSet<VirtualFile> cpFiles = new OrderedSet<VirtualFile>();
+    for (final Module module : modules) {
+      Collections.addAll(cpFiles, orderEnumerator(module, exportedOnly, new AfterJdkOrderEntryCondition()).getClassesRoots());
+    }
+    return cpFiles;
+  }
+
+  private OrderEnumerator orderEnumerator(Module module, boolean exportedOnly, Condition<OrderEntry> condition) {
+    OrderEnumerator enumerator = OrderEnumerator.orderEntries(module).compileOnly().satisfying(condition);
+    if ((mySourcesFilter & TEST_SOURCES) == 0) {
+      enumerator = enumerator.productionOnly();
+    }
+    enumerator = enumerator.recursively();
+    return exportedOnly ? enumerator.exportedOnly() : enumerator;
+  }
+
+  public String getCompilationBootClasspath() {
+    return convertToStringPath(getCompilationBootClasspathFiles());
+  }
+
+  public OrderedSet<VirtualFile> getCompilationBootClasspathFiles() {
+    return getCompilationBootClasspathFiles(true);
+  }
+
+  public OrderedSet<VirtualFile> getCompilationBootClasspathFiles(final boolean exportedOnly) {
+    final Set<Module> modules = getNodes();
+    final OrderedSet<VirtualFile> cpFiles = new OrderedSet<VirtualFile>();
+    final OrderedSet<VirtualFile> jdkFiles = new OrderedSet<VirtualFile>();
+    for (final Module module : modules) {
+      Collections.addAll(cpFiles, orderEnumerator(module, exportedOnly, new BeforeJdkOrderEntryCondition(module)).getClassesRoots());
+      Collections.addAll(jdkFiles, OrderEnumerator.orderEntries(module).sdkOnly().getClassesRoots());
+    }
+    cpFiles.addAll(jdkFiles);
+    return cpFiles;
+  }
+
+  private static String convertToStringPath(final OrderedSet<VirtualFile> cpFiles) {
+    PathsList classpath = new PathsList();
+    classpath.addVirtualFiles(cpFiles);
+    return classpath.getPathsString();
+  }
+
+  //private String tryZipFor(String outputDir) {
+  //  final File zip = CompilerPathsEx.getZippedOutputPath(myContext.getProject(), outputDir);
+  //  if (zip.exists()) {
+  //    try {
+  //      myContext.commitZip(outputDir); // flush unsaved data if any
+  //    }
+  //    catch (IOException e) {
+  //      LOG.info(e);
+  //    }
+  //    return zip.getPath();
+  //  }
+  //  return outputDir;
+  //}
+
+  public int getModuleCount() {
+    return getNodes().size();
+  }
+
+  public Module[] getModules() {
+    final Set<Module> nodes = getNodes();
+    return nodes.toArray(new Module[nodes.size()]);
+  }
+
+  public String getSourcePath() {
+    return getSourcePath(mySourcesFilter);
+  }
+
+  public String getSourcePath(final int sourcesFilter) {
+    if (getModuleCount() == 0) {
+      return "";
+    }
+    final VirtualFile[] filteredRoots = getSourceRoots(sourcesFilter);
+    final StringBuilder buffer = StringBuilderSpinAllocator.alloc();
+    try {
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          for (VirtualFile root : filteredRoots) {
+            if (buffer.length() > 0) {
+              buffer.append(File.pathSeparatorChar);
+            }
+            buffer.append(root.getPath().replace('/', File.separatorChar));
+          }
+        }
+      });
+      return buffer.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(buffer);
+    }
+  }
+
+  //the check for equal language levels is done elsewhere
+  public LanguageLevel getLanguageLevel() {
+    return LanguageLevelUtil.getEffectiveLanguageLevel(getNodes().iterator().next());
+  }
+
+  public Project getProject() {
+    return myContext.getProject();
+  }
+
+  private static class BeforeJdkOrderEntryCondition implements Condition<OrderEntry> {
+    private boolean myJdkFound;
+    private final Module myOwnerModule;
+
+    private BeforeJdkOrderEntryCondition(Module ownerModule) {
+      myOwnerModule = ownerModule;
+    }
+
+    @Override
+    public boolean value(OrderEntry orderEntry) {
+      if (orderEntry instanceof JdkOrderEntry && myOwnerModule.equals(orderEntry.getOwnerModule())) {
+        myJdkFound = true;
+      }
+      return !myJdkFound;
+    }
+  }
+
+  private static class AfterJdkOrderEntryCondition implements Condition<OrderEntry> {
+    private boolean myJdkFound;
+
+    @Override
+    public boolean value(OrderEntry orderEntry) {
+      if (orderEntry instanceof JdkOrderEntry) {
+        myJdkFound = true;
+        return false;
+      }
+      return myJdkFound;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputDir.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputDir.java
new file mode 100644
index 0000000..7d7b12d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputDir.java
@@ -0,0 +1,60 @@
+/*
+ * 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.compiler.impl.javaCompiler;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+* @author cdr
+*/
+class OutputDir {
+  private final String myPath;
+  private final int myKind;
+
+  OutputDir(@NotNull String path, int kind) {
+    myPath = path;
+    myKind = kind;
+  }
+
+  @NotNull
+  public String getPath() {
+    return myPath;
+  }
+
+  public int getKind() {
+    return myKind;
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) {
+      return true;
+    }
+    if (!(o instanceof OutputDir)) {
+      return false;
+    }
+
+    final OutputDir outputDir = (OutputDir)o;
+
+    return myKind == outputDir.myKind && myPath.equals(outputDir.myPath);
+
+  }
+
+  public int hashCode() {
+    int result = myPath.hashCode();
+    result = 29 * result + myKind;
+    return result;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java
new file mode 100644
index 0000000..eb5720c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/OutputItemImpl.java
@@ -0,0 +1,53 @@
+/*
+ * 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: Apr 1, 2003
+ * Time: 5:58:41 PM
+ */
+package com.intellij.compiler.impl.javaCompiler;
+
+import com.intellij.openapi.compiler.TranslatingCompiler;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+public class OutputItemImpl implements TranslatingCompiler.OutputItem{
+
+  private final String myOutputPath;
+  private final VirtualFile mySourceFile;
+
+  public OutputItemImpl(VirtualFile packageInfoFile) {
+    this(null, packageInfoFile);
+  }
+
+  /**
+   * @param outputPath absolute path of the output file ('/' slashes used)
+   * @param sourceFile corresponding source file
+   */
+  public OutputItemImpl(@Nullable String outputPath, VirtualFile sourceFile) {
+    myOutputPath = outputPath;
+    mySourceFile = sourceFile;
+  }
+
+  public String getOutputPath() {
+    return myOutputPath;
+  }
+
+  public VirtualFile getSourceFile() {
+    return mySourceFile;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java
new file mode 100644
index 0000000..d75fe63
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompAPIDriver.java
@@ -0,0 +1,180 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.sun.source.util.JavacTask;
+import com.sun.source.util.TaskEvent;
+import com.sun.source.util.TaskListener;
+import com.sun.tools.javac.api.JavacTool;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.tools.*;
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.lang.reflect.Field;
+import java.net.URI;
+import java.util.List;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;
+
+/**
+ * @author cdr
+ */
+@SuppressWarnings({"Since15"})
+class CompAPIDriver {
+  private final BlockingQueue<CompilationEvent> myCompilationResults = new LinkedBlockingQueue<CompilationEvent>();
+  private static final CompilationEvent GUARD = new CompilationEvent() {
+    @Override
+    protected void process(OutputParser.Callback callback) {
+    }
+
+    @Override
+    public String toString() {
+      return "FINISH";
+    }
+  };
+  private String myOutputDir;
+
+  private volatile boolean compiling;
+  private static final PrintWriter COMPILER_ERRORS = new PrintWriter(System.err);
+  @Nullable
+  private final String mySourcesEncoding;
+
+  CompAPIDriver(@Nullable String sourcesEncoding) {
+    mySourcesEncoding = sourcesEncoding;
+  }
+
+  public void compile(List<String> commandLine, List<File> paths, final String outputDir) {
+    myOutputDir = outputDir;
+    compiling = true;
+
+    assert myCompilationResults.isEmpty();
+    JavaCompiler compiler = JavacTool.create(); //use current classloader
+    StandardJavaFileManager standardFileManager = compiler.getStandardFileManager(null, null, null);
+    MyFileManager manager = new MyFileManager(this, outputDir, standardFileManager, mySourcesEncoding);
+
+    Iterable<? extends JavaFileObject> input = manager.getJavaFileObjectsFromFiles(paths);
+
+    DiagnosticListener<JavaFileObject> listener = new DiagnosticListener<JavaFileObject>() {
+      public void report(Diagnostic<? extends JavaFileObject> diagnostic) {
+        CompilationEvent event = CompilationEvent.diagnostic(diagnostic);
+        myCompilationResults.offer(event);
+      }
+    };
+    try {
+      JavaCompiler.CompilationTask task = compiler.getTask(COMPILER_ERRORS, manager, listener, commandLine, null, input);
+      ((JavacTask)task).setTaskListener(new TaskListener() {
+        public void started(TaskEvent taskEvent) {
+          JavaFileObject sourceFile = taskEvent.getSourceFile();
+          CompilationEvent event;
+          switch (taskEvent.getKind()) {
+            case ANALYZE:
+              event = CompilationEvent.progress("Analyzing ",sourceFile);
+              break;
+            case PARSE:
+              event = CompilationEvent.progress("Parsing ", sourceFile);
+              break;
+            default:
+              event = null;
+          }
+          if (event != null) {
+            myCompilationResults.offer(event);
+          }
+        }
+        public void finished(TaskEvent taskEvent) {
+          CompilationEvent event;
+          switch (taskEvent.getKind()) {
+            case ENTER:
+              event = CompilationEvent.fileProcessed();
+              break;
+            default:
+              event = null;
+          }
+          if (event != null) {
+            myCompilationResults.offer(event);
+          }
+        }
+      });
+      task.call();
+    }
+    catch (IllegalArgumentException e) {
+      final String message = "Javac in-process compiler error: " + e.getMessage();
+      myCompilationResults.offer(new CompilationEvent() {
+        @Override
+        protected void process(OutputParser.Callback callback) {
+          callback.message(CompilerMessageCategory.ERROR, message, null, -1, -1);
+        }
+      });
+    }
+    finally {
+      compiling = false;
+      myCompilationResults.offer(GUARD);
+      try {
+        manager.close();
+      }
+      catch (IOException ignored) {
+      }
+    }
+  }
+
+  private volatile boolean processing;
+  public void processAll(@NotNull OutputParser.Callback callback) {
+    try {
+      processing =  true;
+      while (true) {
+        CompilationEvent event = myCompilationResults.take();
+        if (event == GUARD) break;
+        event.process(callback);
+      }
+    }
+    catch (InterruptedException ignored) {
+    }
+    finally {
+      processing = false;
+    }
+  }
+
+  public void finish() {
+    assert !compiling : "still compiling to "+myOutputDir;
+    assert !processing;
+    //assert myCompilationResults.isEmpty() : myCompilationResults;
+    myCompilationResults.clear();
+    cleanupInternalFields();
+  }
+
+  private static void cleanupInternalFields() {
+    try {
+      Field freelist = Class.forName("com.sun.tools.javac.util.SharedNameTable").getDeclaredField("freelist");
+      freelist.setAccessible(true);
+      freelist.set(null, com.sun.tools.javac.util.List.nil());
+    }
+    catch (Exception ignored) {
+
+    }
+  }
+
+  public void offerClassFile(URI uri, byte[] bytes) {
+    CompilationEvent event = CompilationEvent.generateClass(uri, bytes);
+    myCompilationResults.offer(event);
+  }
+
+}
+
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java
new file mode 100644
index 0000000..0ca1e2b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilationEvent.java
@@ -0,0 +1,127 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import org.jetbrains.annotations.NonNls;
+
+import javax.tools.*;
+import java.io.File;
+import java.net.URI;
+
+/**
+ * @author cdr
+ */
+abstract class CompilationEvent {
+  protected abstract void process(OutputParser.Callback callback);
+  static CompilationEvent progress(final String title, final JavaFileObject fileObject) {
+    return new CompilationEvent() {
+      @Override
+      protected void process(OutputParser.Callback callback) {
+        showProgressFor(title, fileObject.toUri(), callback);
+      }
+
+      @NonNls
+      @Override
+      public String toString() {
+        return "Progress: "+title+" "+fileObject.toUri();
+      }
+    };
+  }
+
+  private static void showProgressFor(String title, URI uri, OutputParser.Callback callback) {
+    String normalizedPath;
+    try {
+      normalizedPath = new File(uri).getPath();
+    }
+    catch (IllegalArgumentException e) {
+      normalizedPath = uri.toString();
+    }
+    callback.setProgressText(title + StringUtil.last(normalizedPath, 100, true));
+  }
+
+  static CompilationEvent generateClass(final URI uri, final byte[] bytes) {
+    return new CompilationEvent() {
+      @Override
+      protected void process(OutputParser.Callback callback) {
+        showProgressFor("Writing ", uri, callback);
+        File file = new File(uri);
+        callback.fileGenerated(new FileObject(file,bytes));
+      }
+      @NonNls
+      @Override
+      public String toString() {
+        return "Write: "+uri;
+      }
+    };
+  }
+  static CompilationEvent diagnostic(final Diagnostic<? extends JavaFileObject> diagnostic) {
+    return new CompilationEvent() {
+      @Override
+      protected void process(OutputParser.Callback callback) {
+        JavaFileObject fileObject = diagnostic.getSource();
+        String message = diagnostic.getMessage(null);
+        String url;
+        if (fileObject == null) {
+          url = null;
+        }
+        else {
+          URI uri = fileObject.toUri();
+          if (uri.getScheme().equals("file")) {
+            url = VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(uri.getPath()));
+          }
+          else {
+            url = fileObject.toString();
+          }
+        }
+
+        CompilerMessageCategory category = diagnostic.getKind() == Diagnostic.Kind.ERROR
+                                           ? CompilerMessageCategory.ERROR
+                                           : diagnostic.getKind() == Diagnostic.Kind.WARNING ||
+                                             diagnostic.getKind() == Diagnostic.Kind.MANDATORY_WARNING
+                                             ? CompilerMessageCategory.WARNING
+                                             : CompilerMessageCategory.INFORMATION;
+        callback.message(category, message, url, (int)diagnostic.getLineNumber(), (int)diagnostic.getColumnNumber());
+      }
+      @NonNls
+      @Override
+      public String toString() {
+        return "Diagnostic: "+diagnostic;
+      }
+    };
+  }
+
+  public static CompilationEvent fileProcessed() {
+    return FILE_PROCESSED;
+  }
+  private static final CompilationEvent FILE_PROCESSED = new CompilationEvent() {
+    @Override
+    protected void process(OutputParser.Callback callback) {
+      callback.fileProcessed(null);
+    }
+
+    @NonNls
+    @Override
+    public String toString() {
+      return "Processed";
+    }
+  };
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java
new file mode 100644
index 0000000..c29b5c5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPICompiler.java
@@ -0,0 +1,206 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+
+public class CompilerAPICompiler implements BackendCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.api.CompilerAPICompiler");
+  private final Project myProject;
+  private static final Set<FileType> COMPILABLE_TYPES = Collections.<FileType>singleton(StdFileTypes.JAVA);
+
+  public CompilerAPICompiler(Project project) {
+    myProject = project;
+  }
+
+  public boolean checkCompiler(final CompileScope scope) {
+    return true;
+  }
+
+  @NotNull
+  @NonNls
+  public String getId() { // used for externalization
+    return JavaCompilers.JAVAC_API_ID;
+  }
+
+  @NotNull
+  public String getPresentableName() {
+    return "Javac in-process (Java6+ only)";
+  }
+
+  @NotNull
+  public Configurable createConfigurable() {
+    return new JavacConfigurable(CompilerAPIConfiguration.getOptions(myProject, CompilerAPIConfiguration.class));
+  }
+
+  @NotNull
+  public Set<FileType> getCompilableFileTypes() {
+    return COMPILABLE_TYPES;
+  }
+
+  @Nullable
+  public OutputParser createErrorParser(@NotNull final String outputDir, final Process process) {
+    return new OutputParser() {
+      public boolean processMessageLine(Callback callback) {
+        ((MyProcess)process).myCompAPIDriver.processAll(callback);
+        return false;
+      }
+    };
+  }
+
+  @Nullable
+  public OutputParser createOutputParser(@NotNull final String outputDir) {
+    return null;
+  }
+
+  public void compileFinished() {
+  }
+
+  @NotNull
+  public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
+    final IOException[] ex = {null};
+    @NonNls final List<String> commandLine = ApplicationManager.getApplication().runReadAction(new Computable<List<String>>() {
+      public List<String> compute() {
+        try {
+          List<String> commandLine = new ArrayList<String>();
+          final List<String> additionalOptions =
+            JavacCompiler.addAdditionalSettings(commandLine, CompilerAPIConfiguration.getOptions(myProject, CompilerAPIConfiguration.class), false, JavaSdkVersion.JDK_1_6, chunk, compileContext.isAnnotationProcessorsEnabled());
+
+          JavacCompiler.addCommandLineOptions(chunk, commandLine, outputDir, chunk.getJdk(), false,false, null, false, false, false);
+          commandLine.addAll(additionalOptions);
+          return commandLine;
+        }
+        catch (IOException e) {
+          ex[0] = e;
+        }
+        return null;
+      }
+    });
+    if (ex[0] != null) {
+      throw ex[0];
+    }
+    return new MyProcess(commandLine, chunk, outputDir, compileContext);
+  }
+
+  private static void compile(List<String> commandLine, ModuleChunk chunk, String outputDir, CompAPIDriver myCompAPIDriver) {
+    List<VirtualFile> filesToCompile = chunk.getFilesToCompile();
+    List<File> paths = new ArrayList<File>(filesToCompile.size());
+    for (VirtualFile file : filesToCompile) {
+      paths.add(new File(file.getPresentableUrl()));
+    }
+    myCompAPIDriver.compile(commandLine, paths, outputDir);
+  }
+
+  private static class MyProcess extends Process {
+    private final List<String> myCommandLine;
+    private final ModuleChunk myChunk;
+    private final String myOutputDir;
+    private final CompileContext myCompileContext;
+    private final CompAPIDriver myCompAPIDriver;
+
+    private MyProcess(List<String> commandLine, ModuleChunk chunk, String outputDir, CompileContext compileContext) {
+      myCommandLine = commandLine;
+      myChunk = chunk;
+      myOutputDir = outputDir;
+      myCompileContext = compileContext;
+      myCompAPIDriver = new CompAPIDriver(findEncodingValue(commandLine));
+    }
+
+    private static String findEncodingValue(List<String> commandLine) {
+      boolean found = false;
+      for (String param : commandLine) {
+        if (found) {
+          return param;
+        }
+        if ("-encoding".equalsIgnoreCase(param)) {
+          found = true;
+        }
+      }
+      return null;
+    }
+
+    public OutputStream getOutputStream() {
+      throw new UnsupportedOperationException();
+    }
+
+    public InputStream getInputStream() {
+      return null;
+    }
+
+    public InputStream getErrorStream() {
+      return null;
+    }
+
+    public void destroy() {
+      myCompAPIDriver.finish();
+    }
+
+    private int myExitCode;
+    public int waitFor() {
+      try {
+        myCommandLine.remove("-verbose");
+        compile(myCommandLine, myChunk, myOutputDir, myCompAPIDriver);
+        myExitCode = 0;
+        return myExitCode;
+      }
+      catch (Exception e) {
+        myCompileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+        LOG.info(e);
+        myExitCode = -1;
+        return -1;
+      }
+    }
+
+    public int exitValue() {
+      return myExitCode;
+    }
+
+    @Override
+    public String toString() {
+      return myChunk.toString();
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPIConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPIConfiguration.java
new file mode 100755
index 0000000..0784a67
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerAPIConfiguration.java
@@ -0,0 +1,36 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.components.StorageScheme;
+import com.intellij.openapi.project.Project;
+
+@State(
+  name = "CompilerAPISettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class CompilerAPIConfiguration extends JavacConfiguration {
+  public CompilerAPIConfiguration(Project project) {
+    super(project);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerPerfTestAction.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerPerfTestAction.java
new file mode 100644
index 0000000..1b6b355
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/CompilerPerfTestAction.java
@@ -0,0 +1,98 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileStatusNotification;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.List;
+import java.util.concurrent.TimeUnit;
+
+/**
+ * @author cdr
+ */
+public class CompilerPerfTestAction extends AnAction {
+  @Override
+  public void update(AnActionEvent e) {
+    Project project = e.getData(PlatformDataKeys.PROJECT);
+    e.getPresentation().setEnabled(project != null);
+  }
+
+  public void actionPerformed(AnActionEvent e) {
+    final Project project = e.getData(PlatformDataKeys.PROJECT);
+
+    final CompilerManager compilerManager = CompilerManager.getInstance(project);
+
+    final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    List<BackendCompiler> compilers = (List<BackendCompiler>)configuration.getRegisteredJavaCompilers();
+    final List<BackendCompiler> allCompilers = ContainerUtil.concat(compilers, compilers, compilers, compilers, compilers, compilers, compilers);
+    final int[] i = new int[1];
+
+    CompileStatusNotification callback = new CompileStatusNotification() {
+      volatile long start;
+      BackendCompiler compiler;
+
+      public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+        if (compiler == null) {
+          next();
+          return;
+        }
+        final long finish = System.currentTimeMillis();
+        System.out.println("Compiled with '" +
+                           compiler.getPresentableName() + "' " +
+                           " in " +
+                           TimeUnit.MILLISECONDS.toMinutes(finish - start) + "m" +
+                           TimeUnit.MILLISECONDS.toSeconds((finish - start)%60000) + "s" +
+                           " with " +
+                           errors +
+                           " errors, " +
+                           warnings +
+                           " warnings, aborted=" +
+                           aborted+"; free memory="+Runtime.getRuntime().freeMemory()+" bytes");
+        //ProfilingUtil.forceCaptureMemorySnapshot();
+        next();
+      }
+
+      void next() {
+        if (i[0] >= allCompilers.size()) return;
+        compiler = allCompilers.get(i[0]++);
+        if (compiler.getId().equals("Jikes")|| compiler.getId().contains("Eclipse")) {
+          next();
+          return;
+        }
+        boolean success = compiler.checkCompiler(compilerManager.createProjectCompileScope(project));
+        if (!success) {
+          next();
+          return;
+        }
+        configuration.setDefaultCompiler(compiler);
+        start = System.currentTimeMillis();
+        compilerManager.rebuild(this);
+      }
+    };
+
+    callback.finished(false,0,0,null);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java
new file mode 100644
index 0000000..b6866f0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/FileVirtualObject.java
@@ -0,0 +1,70 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import javax.tools.*;
+import java.io.ByteArrayInputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.net.URI;
+
+/**
+ * @author cdr
+ */
+@SuppressWarnings({"Since15"})
+public abstract class FileVirtualObject extends SimpleJavaFileObject {
+  public FileVirtualObject(URI uri, Kind kind) {
+    super(uri, kind);
+  }
+
+  protected abstract VirtualFile getVirtualFile();
+  @Override
+  public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+    VirtualFile virtualFile = getVirtualFile();
+    if (virtualFile == null) return null;
+    return LoadTextUtil.loadText(virtualFile);
+  }
+
+  @Override
+  public InputStream openInputStream() throws IOException {
+    // in-process compiler does not work well with zipped stream
+    byte[] bytes = getVirtualFile().contentsToByteArray();
+    return new ByteArrayInputStream(bytes);
+  }
+
+  @Override
+  public OutputStream openOutputStream() throws IOException {
+    return getVirtualFile().getOutputStream(this);
+  }
+
+  @Override
+  public String toString() {
+    return toUri().toString();
+  }
+  @Override
+  public int hashCode() {
+    return toUri().hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri());
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java
new file mode 100644
index 0000000..801fc75
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaIoFile.java
@@ -0,0 +1,94 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.tools.JavaFileObject;
+import javax.tools.SimpleJavaFileObject;
+import java.io.*;
+import java.net.URI;
+import java.net.URISyntaxException;
+
+/**
+* User: cdr
+*/
+@SuppressWarnings({"Since15"})
+class JavaIoFile extends SimpleJavaFileObject {
+  private final File myFile;
+  @Nullable
+  private final String myEncoding;
+
+  JavaIoFile(@NotNull File file, @NotNull Kind kind, @Nullable String encoding) {
+    super(convertToURI(file.getPath()), kind);
+    myFile = file;
+    myEncoding = encoding;
+  }
+
+  // File.toURI() asks for File.isDirectory which is too expensive
+  @NotNull
+  private static URI convertToURI(@NotNull String path) {
+    if (File.separatorChar != '/') {
+      path = path.replace(File.separatorChar, '/');
+    }
+    if (!StringUtil.startsWithChar(path, '/')) {
+      path = "/" + path;
+    }
+
+    if (path.startsWith("//")) {
+      path = "//" + path;
+    }
+    try {
+      return new URI("file", null, path, null);
+    }
+    catch (URISyntaxException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  @Override
+  public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+    return FileUtil.loadFile(myFile, myEncoding);
+  }
+
+  @Override
+  public InputStream openInputStream() throws IOException {
+    return new BufferedInputStream(new FileInputStream(myFile));
+  }
+
+  @Override
+  public OutputStream openOutputStream() throws IOException {
+    return new BufferedOutputStream(new FileOutputStream(myFile));
+  }
+
+  @Override
+  public String toString() {
+    return toUri().toString();
+  }
+
+  @Override
+  public int hashCode() {
+    return toUri().hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri());
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java
new file mode 100644
index 0000000..6fd1065
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualByIoFile.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.io.File;
+
+/**
+ * User: cdr
+ */
+@SuppressWarnings({"Since15"})
+class JavaVirtualByIoFile extends FileVirtualObject {
+  private final File myFile;
+
+  protected JavaVirtualByIoFile(File file, Kind kind) {
+    super(file.toURI(), kind);
+    myFile = file;
+  }
+
+  protected VirtualFile getVirtualFile() {
+    return LocalFileSystem.getInstance().findFileByIoFile(myFile);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java
new file mode 100644
index 0000000..abe8f24
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/JavaVirtualFile.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+* User: cdr
+*/
+@SuppressWarnings({"Since15"})
+class JavaVirtualFile extends FileVirtualObject {
+  private final VirtualFile myFile;
+
+  JavaVirtualFile(VirtualFile file, Kind kind) {
+    super(MyFileManager.createUri(file.getUrl()), kind);
+    myFile = file;
+  }
+
+  protected VirtualFile getVirtualFile() {
+    return myFile;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java
new file mode 100644
index 0000000..d46d504
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/MyFileManager.java
@@ -0,0 +1,260 @@
+/*
+ * 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.compiler.impl.javaCompiler.api;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.SmartList;
+import com.sun.tools.javac.util.ListBuffer;
+import gnu.trove.THashSet;
+import gnu.trove.TObjectHashingStrategy;
+
+import javax.tools.FileObject;
+import javax.tools.JavaFileObject;
+import javax.tools.StandardJavaFileManager;
+import java.io.File;
+import java.io.IOException;
+import java.net.URI;
+import java.util.*;
+
+/**
+* @author cdr
+*/
+class MyFileManager implements StandardJavaFileManager {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.api.MyFileManager");
+
+  private final String myOutputDir;
+  private final StandardJavaFileManager myStandardFileManager;
+  private final String myEncoding;
+  private final CompAPIDriver myCompAPIDriver;
+
+  MyFileManager(CompAPIDriver compAPIDriver, String outputDir, StandardJavaFileManager standardFileManager, String encoding) {
+    myCompAPIDriver = compAPIDriver;
+    myOutputDir = outputDir;
+    myStandardFileManager = standardFileManager;
+    myEncoding = encoding;
+  }
+
+  @Override
+  public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(Iterable<? extends File> files) {
+    int size = ((Collection)files).size();
+    List<JavaFileObject> result = new ArrayList<JavaFileObject>(size);
+
+    for (File file : files) {
+      JavaFileObject fileObject = new JavaIoFile(file, JavaFileObject.Kind.SOURCE, myEncoding);
+      result.add(fileObject);
+    }
+
+    return result;
+  }
+
+  @Override
+  public JavaFileObject getJavaFileForOutput(Location location, String name, JavaFileObject.Kind kind, FileObject fileObject) {
+    URI uri = toURI(myOutputDir, name, kind);
+    return new Output(uri, myCompAPIDriver, kind);
+  }
+
+  static URI createUri(String url) {
+    return URI.create(url.replaceAll(" ","%20"));
+  }
+
+  private static URI toURI(String outputDir, String name, JavaFileObject.Kind kind) {
+    return createUri("file:///" + outputDir.replace('\\','/') + "/" + name.replace('.', '/') + kind.extension);
+  }
+
+
+  @Override
+  public Iterable<JavaFileObject> list(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean recurse) throws IOException {
+    if (recurse) {
+      throw new IllegalArgumentException();
+    }
+    return findInside(location, packageName, kinds, false);
+  }
+
+  private List<JavaFileObject> findInside(Location location, String packageName, Set<JavaFileObject.Kind> kinds, boolean lookForFile)
+    throws IOException {
+    Iterable<? extends File> path = getLocation(location);
+    if (path == null) return Collections.emptyList();
+
+    String subdirectory = packageName.replace('.', '/');
+    List<JavaFileObject> results = null;
+
+    for (File directory : path) {
+      VirtualFile dir = LocalFileSystem.getInstance().findFileByIoFile(directory);
+      if (dir == null) continue;
+      if (!dir.isDirectory()) {
+        dir = JarFileSystem.getInstance().getJarRootForLocalFile(dir);
+        if (dir == null) continue;
+      }
+      VirtualFile virtualFile = StringUtil.isEmptyOrSpaces(subdirectory) ? dir : dir.findFileByRelativePath(subdirectory);
+      if (virtualFile == null) continue;
+
+      VirtualFile[] children;
+      if (lookForFile) {
+        if (!virtualFile.isDirectory()) {
+          children = new VirtualFile[]{virtualFile};
+        }
+        else continue;
+      }
+      else {
+        children = virtualFile.getChildren();
+      }
+      for (VirtualFile child : children) {
+        JavaFileObject.Kind kind = getKind("." + child.getExtension());
+        if (kinds == null || kinds.contains(kind)) {
+          if (results == null) results = new SmartList<JavaFileObject>();
+          if (kind == JavaFileObject.Kind.SOURCE && child.getFileSystem() instanceof JarFileSystem) continue;  //for some reasdon javac looks for java files inside jar
+
+          // use VFS to read content inside .jar
+          String childPath = child.getPath();
+          JavaFileObject fileObject = !childPath.contains("!/") ? new JavaIoFile(new File(childPath), kind, myEncoding) : new JavaVirtualFile(child, kind);
+          results.add(fileObject);
+        }
+      }
+    }
+
+    List<JavaFileObject> ret = results == null ? Collections.<JavaFileObject>emptyList() : results;
+
+    if (LOG.isDebugEnabled()) {
+      // for testing consistency
+      Collection c = (Collection)myStandardFileManager.list(location, packageName, kinds, false);
+      Collection<JavaFileObject> sup = new HashSet(c);
+      assert sup.size() == c.size();
+      assert new HashSet(c).equals(sup);
+
+      THashSet<JavaFileObject> s = new THashSet<JavaFileObject>(new TObjectHashingStrategy<JavaFileObject>() {
+        public int computeHashCode(JavaFileObject object) {
+          return object.getName().hashCode();
+        }
+
+        public boolean equals(JavaFileObject o1, JavaFileObject o2) {
+          return o1.getKind() == o2.getKind() && o1.toUri().equals(o2.toUri());
+        }
+      });
+      s.addAll(ret);
+
+      s.removeAll(sup);
+      if (ret.size() != sup.size()) {
+        assert false : "our implementation differs from javac'";
+      }
+    }
+
+    return ret;
+  }
+
+  private static JavaFileObject.Kind getKind(String name) {
+      if (name.endsWith(JavaFileObject.Kind.CLASS.extension))
+          return JavaFileObject.Kind.CLASS;
+      else if (name.endsWith(JavaFileObject.Kind.SOURCE.extension))
+          return JavaFileObject.Kind.SOURCE;
+      else if (name.endsWith(JavaFileObject.Kind.HTML.extension))
+          return JavaFileObject.Kind.HTML;
+      else
+          return JavaFileObject.Kind.OTHER;
+  }
+
+
+  @Override
+  public String inferBinaryName(Location location, JavaFileObject file) {
+    return FileUtil.getNameWithoutExtension(new File(file.getName()).getName());
+  }
+
+  ////////// delegates
+  @Override
+  public int isSupportedOption(String option) {
+    return myStandardFileManager.isSupportedOption(option);
+  }
+
+  @Override
+  public void close() throws IOException {
+    myStandardFileManager.close();
+  }
+
+  @Override
+  public void flush() throws IOException {
+    myStandardFileManager.flush();
+  }
+
+  @Override
+  public boolean handleOption(String current, Iterator<String> remaining) {
+    return myStandardFileManager.handleOption(current, remaining);
+  }
+
+  @Override
+  public ClassLoader getClassLoader(Location location) {
+    return myStandardFileManager.getClassLoader(location);
+  }
+
+  @Override
+  public boolean isSameFile(FileObject a, FileObject b) {
+    if (a instanceof FileVirtualObject && b instanceof FileVirtualObject || a instanceof Output && b instanceof Output) {
+      return a.equals(b);
+    }
+    return myStandardFileManager.isSameFile(a, b);
+  }
+
+  public Iterable<? extends JavaFileObject> getJavaFileObjects(File... files) {
+    return getJavaFileObjectsFromFiles(Arrays.asList(files));
+  }
+
+  public Iterable<? extends JavaFileObject> getJavaFileObjects(String... names) {
+    return getJavaFileObjectsFromStrings(Arrays.asList(names));
+  }
+  public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(Iterable<String> names) {
+    ListBuffer<File> files = new ListBuffer<File>();
+    for (String name : names) {
+      files.append(new File(name));
+    }
+    return getJavaFileObjectsFromFiles(files.toList());
+  }
+
+  public JavaFileObject getJavaFileForInput(Location location, String className, JavaFileObject.Kind kind) throws IOException {
+    List<JavaFileObject> result = findInside(location, className, kind == null ? null : Collections.singleton(kind), true);
+    if (!result.isEmpty()) {
+      return result.get(0);
+    }
+    return null;
+  }
+
+  @Override
+  public FileObject getFileForInput(Location location, String packageName, String relativeName) throws IOException {
+    return getJavaFileForInput(location, packageName + "/" + relativeName, getKind(relativeName));
+  }
+
+  @Override
+  public FileObject getFileForOutput(Location location, String packageName, String relativeName, FileObject sibling) throws IOException {
+    return getJavaFileForOutput(location, packageName + "/" + relativeName, getKind(relativeName), null);
+  }
+
+  @Override
+  public Iterable<? extends File> getLocation(Location location) {
+    return myStandardFileManager.getLocation(location);
+  }
+
+  @Override
+  public void setLocation(Location location, Iterable<? extends File> path) throws IOException {
+    myStandardFileManager.setLocation(location, path);
+  }
+
+  @Override
+  public boolean hasLocation(Location location) {
+    return myStandardFileManager.hasLocation(location);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java
new file mode 100644
index 0000000..8cdf09c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/api/Output.java
@@ -0,0 +1,80 @@
+/*
+ * Copyright 2000-2010 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.compiler.impl.javaCompiler.api;
+
+import org.jetbrains.annotations.Nullable;
+
+import javax.tools.*;
+import java.io.*;
+import java.net.URI;
+
+/**
+* User: cdr
+*/
+@SuppressWarnings({"ALL"})
+class Output extends SimpleJavaFileObject {
+  private final CompAPIDriver myCompAPIDriver;
+  @Nullable
+  private volatile byte[] myFileBytes;
+
+  Output(URI uri, CompAPIDriver compAPIDriver, final Kind kind) {
+    super(uri, kind);
+    myCompAPIDriver = compAPIDriver;
+  }
+
+  @Override
+  public ByteArrayOutputStream openOutputStream() {
+    return new ByteArrayOutputStream() {
+      @Override
+      public void close() throws IOException {
+        super.close();
+        final byte[] bytes = toByteArray();
+        myFileBytes = bytes;
+        if (Kind.CLASS.equals(kind)) {
+          myCompAPIDriver.offerClassFile(toUri(), bytes);
+        }
+      }
+    };
+  }
+
+  @Override
+  public InputStream openInputStream() throws IOException {
+    final byte[] bytes = myFileBytes;
+    if (bytes == null) {
+      throw new FileNotFoundException(toUri().getPath());
+    }
+    return new ByteArrayInputStream(bytes);
+  }
+
+  @Override
+  public CharSequence getCharContent(boolean ignoreEncodingErrors) throws IOException {
+    final byte[] bytes = myFileBytes;
+    if (bytes == null) {
+      throw null;
+    }
+    return new String(bytes);
+  }
+
+  @Override
+  public int hashCode() {
+    return toUri().hashCode();
+  }
+
+  @Override
+  public boolean equals(Object obj) {
+    return obj instanceof JavaFileObject && toUri().equals(((JavaFileObject)obj).toUri());
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java
new file mode 100644
index 0000000..615315d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompiler.java
@@ -0,0 +1,238 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+
+import java.io.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+                                        
+public class EclipseCompiler extends ExternalCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompiler");
+
+  private final Project myProject;
+  private final List<File> myTempFiles = new ArrayList<File>();
+  private static final String COMPILER_CLASS_NAME = "org.eclipse.jdt.core.compiler.batch.BatchCompiler";
+  @NonNls private static final String PATH_TO_COMPILER_JAR = findJarPah();
+
+  private static String findJarPah() {
+    try {
+      final Class<?> aClass = Class.forName(COMPILER_CLASS_NAME);
+      final String path = PathManager.getResourceRoot(aClass, "/" + aClass.getName().replace('.', '/') + ".class");
+      if (path != null) {
+        return path;
+      }
+    }
+    catch (ClassNotFoundException ignored) {
+    }
+
+    File dir = new File(PathManager.getLibPath());
+    File[] jars = dir.listFiles(new FilenameFilter() {
+      public boolean accept(File dir, String name) {
+        return name.startsWith("ecj-") && name.endsWith(".jar");
+      }
+    });
+    return jars.length == 0 ? dir + "/ecj-*.jar" : jars[0].getPath();
+  }
+
+  public EclipseCompiler(Project project) {
+    myProject = project;
+  }
+
+  public static boolean isInitialized() {
+    File file = new File(PATH_TO_COMPILER_JAR);
+    return file.exists();
+  }
+
+  public boolean checkCompiler(final CompileScope scope) {
+    if (!isInitialized()) {
+      Messages.showMessageDialog(
+        myProject,
+        CompilerBundle.message("eclipse.compiler.error.jar.not.found", PATH_TO_COMPILER_JAR),
+        CompilerBundle.message("compiler.eclipse.name"),
+        Messages.getErrorIcon()
+      );
+      return false;
+    }
+    return true;
+  }
+
+  @NonNls
+  public static String getCompilerClass() {
+    return "org.eclipse.jdt.internal.compiler.batch.Main";
+  }
+
+  @NotNull
+  public String getId() { // used for externalization
+    return JavaCompilers.ECLIPSE_ID;
+  }
+
+  @NotNull
+  public String getPresentableName() {
+    return CompilerBundle.message("compiler.eclipse.name");
+  }
+
+  @NotNull
+  public Configurable createConfigurable() {
+    return new EclipseCompilerConfigurable(EclipseCompilerConfiguration.getOptions(myProject, EclipseCompilerConfiguration.class));
+  }
+
+  public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
+    return new EclipseCompilerErrorParser();
+  }
+
+  @Nullable
+  public OutputParser createOutputParser(@NotNull final String outputDir) {
+    return new EclipseCompilerOutputParser(outputDir);
+  }
+
+  @NotNull
+  public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
+    throws IOException {
+
+    final ArrayList<String> commandLine = new ArrayList<String>();
+    final IOException[] ex = {null};
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          createStartupCommand(chunk, commandLine, outputPath, true);
+        }
+        catch (IOException e) {
+          ex[0] = e;
+        }
+      }
+    });
+    if (ex[0] != null) {
+      throw ex[0];
+    }
+    return ArrayUtil.toStringArray(commandLine);
+  }
+
+  private void createStartupCommand(final ModuleChunk chunk,
+                                    @NonNls final ArrayList<String> commandLine,
+                                    final String outputPath,
+                                    final boolean useTempFile) throws IOException {
+    final EclipseCompilerOptions options = EclipseCompilerConfiguration.getOptions(myProject, EclipseCompilerConfiguration.class);
+
+    final Sdk projectJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
+    final String vmExePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk);
+    commandLine.add(vmExePath);
+    commandLine.add("-Xmx" + options.MAXIMUM_HEAP_SIZE + "m");
+
+    CompilerUtil.addLocaleOptions(commandLine, false);
+
+    commandLine.add("-classpath");
+    commandLine.add(PATH_TO_COMPILER_JAR);
+    commandLine.add(getCompilerClass());
+
+    addCommandLineOptions(commandLine, chunk, outputPath, options, useTempFile, true);
+  }
+
+  public void addCommandLineOptions(@NotNull @NonNls final List<String> commandLine,
+                                    @NotNull final ModuleChunk chunk,
+                                    @NotNull final String outputPath,
+                                    @NotNull final EclipseCompilerOptions options,
+                                    final boolean useTempFile,
+                                    boolean quoteBootClasspath) throws IOException {
+    final Sdk jdk = chunk.getJdk();
+    CompilerUtil.addSourceCommandLineSwitch(jdk, chunk.getLanguageLevel(), commandLine);
+    CompilerUtil.addTargetCommandLineSwitch(chunk, commandLine);
+
+    final String bootCp = chunk.getCompilationBootClasspath();
+
+    final String classPath = chunk.getCompilationClasspath();
+
+    if (!StringUtil.isEmpty(bootCp)) {
+      commandLine.add("-bootclasspath");
+      // important: need to quote boot classpath if path to jdk contain spaces
+      commandLine.add(quoteBootClasspath ? CompilerUtil.quotePath(bootCp) : bootCp);
+    }
+
+    if (!StringUtil.isEmpty(classPath)) {
+      commandLine.add("-classpath");
+      commandLine.add(classPath);
+    }
+
+    commandLine.add("-d");
+    commandLine.add(outputPath.replace('/', File.separatorChar));
+
+    commandLine.add("-verbose");
+    StringTokenizer tokenizer = new StringTokenizer(new EclipseSettingsBuilder(options).getOptionsString(chunk), " ");
+    while (tokenizer.hasMoreTokens()) {
+      commandLine.add(tokenizer.nextToken());
+    }
+
+    final List<VirtualFile> files = chunk.getFilesToCompile();
+
+    if (useTempFile) {
+      File sourcesFile = FileUtil.createTempFile("javac", ".tmp");
+      sourcesFile.deleteOnExit();
+      myTempFiles.add(sourcesFile);
+      final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(sourcesFile)));
+      try {
+        for (final VirtualFile file : files) {
+          // Important: should use "/" slashes!
+          // but not for JDK 1.5 - see SCR 36673
+          final String path = file.getPath().replace('/', File.separatorChar);
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Adding path for compilation " + path);
+          }
+          writer.println(CompilerUtil.quotePath(path));
+        }
+      }
+      finally {
+        writer.close();
+      }
+      commandLine.add("@" + sourcesFile.getAbsolutePath());
+    }
+    else {
+      for (VirtualFile file : files) {
+        commandLine.add(file.getPath());
+      }
+    }
+  }
+
+  public void compileFinished() {
+    FileUtil.asyncDelete(myTempFiles);
+    myTempFiles.clear();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
new file mode 100644
index 0000000..d8a50af
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.form
@@ -0,0 +1,118 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompilerConfigurable">
+  <grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="79" y="160" width="584" height="236"/>
+    </constraints>
+    <properties/>
+    <clientProperties>
+      <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+    </clientProperties>
+    <border type="etched" title-resource-bundle="messages/CompilerBundle" title-key="eclipse.options.group.title"/>
+    <children>
+      <component id="8538e" class="javax.swing.JCheckBox" binding="myCbDeprecation">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="false"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.report.deprecated"/>
+        </properties>
+      </component>
+      <component id="3d38f" class="javax.swing.JCheckBox" binding="myCbDebuggingInfo">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="false"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.debugging.info"/>
+        </properties>
+      </component>
+      <component id="90803" class="javax.swing.JCheckBox" binding="myCbGenerateNoWarnings">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="false"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
+        </properties>
+      </component>
+      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="10" left="8" bottom="0" right="0"/>
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f8a80" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.additional.command.line.parameters"/>
+            </properties>
+          </component>
+          <component id="479c2" class="com.intellij.ui.RawCommandLineEditor" binding="myAdditionalOptionsField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+          <component id="327dc" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
+            </properties>
+          </component>
+          <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
+            <constraints>
+              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+                <preferred-size width="60" height="-1"/>
+              </grid>
+            </constraints>
+            <properties>
+              <margin top="0" left="2" bottom="0" right="0"/>
+              <text value="128"/>
+            </properties>
+            <clientProperties>
+              <caretAspectRatio class="java.lang.Float" value="0.04"/>
+            </clientProperties>
+          </component>
+          <component id="6f8c2" class="com.intellij.ui.components.JBLabel">
+            <constraints>
+              <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <enabled value="false"/>
+              <text value="(ineffective when &quot;Use external build&quot; is on)"/>
+            </properties>
+          </component>
+          <hspacer id="a1325">
+            <constraints>
+              <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </hspacer>
+        </children>
+      </grid>
+      <vspacer id="af30">
+        <constraints>
+          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <component id="4eacb" class="javax.swing.JCheckBox" binding="myCbProceedOnErrors">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Proceed on errors"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.java
new file mode 100644
index 0000000..ad9cb1d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfigurable.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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.options.ComparingUtils;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.ui.RawCommandLineEditor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
+
+import javax.swing.*;
+
+/**
+ * @author cdr
+ */
+public class EclipseCompilerConfigurable implements Configurable {
+  private JPanel myPanel;
+  private JCheckBox myCbDeprecation;
+  private JCheckBox myCbDebuggingInfo;
+  private JCheckBox myCbGenerateNoWarnings;
+  private RawCommandLineEditor myAdditionalOptionsField;
+  private JTextField myJavacMaximumHeapField;
+  private JCheckBox myCbProceedOnErrors;
+  private final EclipseCompilerOptions myCompilerSettings;
+
+  public EclipseCompilerConfigurable(EclipseCompilerOptions options) {
+    myCompilerSettings = options;
+    myAdditionalOptionsField.setDialogCaption(CompilerBundle.message("java.compiler.option.additional.command.line.parameters"));
+  }
+
+  public String getDisplayName() {
+    return null;
+  }
+
+  @Nullable
+  @NonNls
+  public String getHelpTopic() {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public boolean isModified() {
+    boolean isModified = ComparingUtils.isModified(myJavacMaximumHeapField, myCompilerSettings.MAXIMUM_HEAP_SIZE);
+
+    isModified |= ComparingUtils.isModified(myCbDeprecation, myCompilerSettings.DEPRECATION);
+    isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myCompilerSettings.DEBUGGING_INFO);
+    isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myCompilerSettings.GENERATE_NO_WARNINGS);
+    isModified |= ComparingUtils.isModified(myCbProceedOnErrors, myCompilerSettings.PROCEED_ON_ERROR);
+    isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myCompilerSettings.ADDITIONAL_OPTIONS_STRING);
+    return isModified;
+  }
+
+  public void apply() throws ConfigurationException {
+
+    try {
+      myCompilerSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
+      if(myCompilerSettings.MAXIMUM_HEAP_SIZE < 1) {
+        myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
+      }
+    }
+    catch(NumberFormatException exception) {
+      myCompilerSettings.MAXIMUM_HEAP_SIZE = 128;
+    }
+
+    myCompilerSettings.DEPRECATION =  myCbDeprecation.isSelected();
+    myCompilerSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
+    myCompilerSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
+    myCompilerSettings.PROCEED_ON_ERROR = myCbProceedOnErrors.isSelected();
+    myCompilerSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText();
+  }
+
+  public void reset() {
+    myJavacMaximumHeapField.setText(Integer.toString(myCompilerSettings.MAXIMUM_HEAP_SIZE));
+    myCbDeprecation.setSelected(myCompilerSettings.DEPRECATION);
+    myCbDebuggingInfo.setSelected(myCompilerSettings.DEBUGGING_INFO);
+    myCbGenerateNoWarnings.setSelected(myCompilerSettings.GENERATE_NO_WARNINGS);
+    myCbProceedOnErrors.setSelected(myCompilerSettings.PROCEED_ON_ERROR);
+    myAdditionalOptionsField.setText(myCompilerSettings.ADDITIONAL_OPTIONS_STRING);
+  }
+
+  public void disposeUIResources() {
+
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfiguration.java
new file mode 100755
index 0000000..4efbdcd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerConfiguration.java
@@ -0,0 +1,45 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
+
+@State(
+  name = "EclipseCompilerSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class EclipseCompilerConfiguration implements PersistentStateComponent<EclipseCompilerOptions> {
+  private final EclipseCompilerOptions mySettings = new EclipseCompilerOptions();
+
+  @NotNull
+  public EclipseCompilerOptions getState() {
+    return mySettings;
+  }
+
+  public void loadState(EclipseCompilerOptions state) {
+    XmlSerializerUtil.copyBean(state, mySettings);
+  }
+
+  public static EclipseCompilerOptions getOptions(Project project, Class<? extends EclipseCompilerConfiguration> aClass) {
+    return ServiceManager.getService(project, aClass).getState();
+  }}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerDriver.java
new file mode 100644
index 0000000..9538c16
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerDriver.java
@@ -0,0 +1,255 @@
+/*
+ * 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 Alexey
+ */
+
+package com.intellij.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.eclipse.jdt.core.compiler.IProblem;
+import org.eclipse.jdt.core.compiler.InvalidInputException;
+import org.eclipse.jdt.internal.compiler.*;
+import org.eclipse.jdt.internal.compiler.Compiler;
+import org.eclipse.jdt.internal.compiler.ast.CompilationUnitDeclaration;
+import org.eclipse.jdt.internal.compiler.batch.CompilationUnit;
+import org.eclipse.jdt.internal.compiler.batch.FileSystem;
+import org.eclipse.jdt.internal.compiler.batch.Main;
+import org.eclipse.jdt.internal.compiler.env.INameEnvironment;
+import org.eclipse.jdt.internal.compiler.problem.DefaultProblemFactory;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.io.StringWriter;
+import java.util.Locale;
+import java.util.Map;
+import java.util.concurrent.BlockingQueue;
+import java.util.concurrent.LinkedBlockingQueue;    
+
+public class EclipseCompilerDriver {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseCompilerDriver");
+
+  private String[] sourceFilePaths;
+  private Map compilerOptions;
+  private final BlockingQueue<CompilationResult> myCompilationResults = new LinkedBlockingQueue<CompilationResult>();
+  private FileSystem classPath;
+
+  private void parseCommandLine(String[] args) throws InvalidInputException {
+    StringWriter err = new StringWriter();
+    Main driver = new Main(null, new PrintWriter(err), false);
+    driver.configure(args);
+    StringBuffer buffer = err.getBuffer();
+    if (buffer.length() != 0) {
+      throw new InvalidInputException(buffer.toString());
+    }
+    sourceFilePaths = driver.filenames;
+    compilerOptions = driver.options;
+    classPath = driver.getLibraryAccess();
+  }
+
+  private CompilationUnit[] getCompilationUnits() {
+    int fileCount = sourceFilePaths.length;
+    CompilationUnit[] units = new CompilationUnit[fileCount];
+    final String defaultEncoding = null;
+
+    for (int i = 0; i < fileCount; i++) {
+      units[i] = new MyCompilationUnit(sourceFilePaths[i], defaultEncoding);
+    }
+    return units;
+  }
+
+  private ICompilerRequestor getBatchRequestor(final CompileContext compileContext) {
+    return new ICompilerRequestor() {
+      public void acceptResult(CompilationResult compilationResult) {
+        ProgressIndicator progress = compileContext.getProgressIndicator();
+        if (progress != null) {
+          progress.checkCanceled();
+        }
+        myCompilationResults.offer(compilationResult);
+      }
+    };
+  }
+
+  private static final CompilationResult END_OF_STREAM = new CompilationResult(new char[0], 0, 0, 0);
+
+  private INameEnvironment getEnvironment() {
+    return classPath;
+  }
+
+  private static IProblemFactory getProblemFactory() {
+    return new DefaultProblemFactory(Locale.getDefault());
+  }
+
+  private static IErrorHandlingPolicy getHandlingPolicy() {
+    return new IErrorHandlingPolicy() {
+      public boolean proceedOnErrors() {
+        return false; // stop if there are some errors
+      }
+
+      public boolean stopOnFirstError() {
+        return false;
+      }
+    };
+  }
+
+  private Map getCompilerOptions() {
+    return compilerOptions;
+  }
+
+
+  private void compile(final CompileContext compileContext) {
+    final INameEnvironment environment = getEnvironment();
+
+    Compiler compiler =
+      new Compiler(
+        environment,
+        getHandlingPolicy(),
+        getCompilerOptions(),
+        getBatchRequestor(compileContext),
+        getProblemFactory()){
+        protected void handleInternalException(Throwable internalException, CompilationUnitDeclaration unit, CompilationResult result) {
+          if (internalException instanceof ProcessCanceledException) throw (ProcessCanceledException)internalException;
+          super.handleInternalException(internalException, unit, result);
+        }
+      };
+    compiler.parseThreshold = 2500;
+    try {
+      compiler.compile(getCompilationUnits());
+    }
+    catch (ProcessCanceledException e) {
+      //compileContext.addMessage(CompilerMessageCategory.ERROR, "Canceled",null,-1,-1);
+    }
+    catch (Exception e) {
+      ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
+      if (indicator == null || !indicator.isCanceled()) {
+        compileContext.addMessage(CompilerMessageCategory.ERROR, "Internal Error: "+e.toString(),null,-1,-1);
+      }
+    }
+    finally {
+      myCompilationResults.offer(END_OF_STREAM);
+      environment.cleanup();
+    }
+  }
+
+  public boolean processMessageLine(final OutputParser.Callback callback, final String outputDir, Project project) {
+    ProgressManager.checkCanceled();
+    CompilationResult result;
+    try {
+      result = myCompilationResults.take();
+    }
+    catch (InterruptedException e) {
+      LOG.error(e);
+      return true;
+    }
+    if (result == END_OF_STREAM) {
+      return false;
+    }
+
+    String file = String.valueOf(result.getFileName());
+    callback.setProgressText(CompilerBundle.message("eclipse.compiler.parsing", file));
+    callback.fileProcessed(file);
+
+    ClassFile[] classFiles = result.getClassFiles();
+    for (ClassFile classFile : classFiles) {
+      String filePath = String.valueOf(classFile.fileName());
+      String relativePath = FileUtil.toSystemDependentName(filePath + ".class");
+      String path = FileUtil.toSystemDependentName(outputDir) + File.separatorChar + relativePath;
+
+      byte[] bytes = classFile.getBytes();
+      File out = new File(path);
+
+      callback.fileGenerated(new FileObject(out,bytes));
+    }
+    IProblem[] problems = result.getProblems();
+    if (problems != null) {
+      for (IProblem problem : problems) {
+        CompilerMessageCategory category = problem.isError() ? CompilerMessageCategory.ERROR
+                                           : problem.isWarning() ? CompilerMessageCategory.WARNING :
+                                             CompilerMessageCategory.INFORMATION;
+        String filePath = String.valueOf(problem.getOriginatingFileName());
+        String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(filePath));
+        int lineNumber = problem.getSourceLineNumber();
+        int sourceStart = problem.getSourceStart();
+        int column = getColumn(url, lineNumber, sourceStart, project);
+        callback.message(category, problem.getMessage(), url, lineNumber, column);
+      }
+    }
+    return true;
+  }
+
+  private static int getColumn(final String url, final int lineNumber, final int sourceStart, final Project project) {
+    if (sourceStart == 0) return 0;
+    return ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
+      public Integer compute() {
+        VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
+        if (file == null) return 0;
+        Document document = FileDocumentManager.getInstance().getDocument(file);
+        if (document == null) return 0;
+        int lineStartOffset = document.getLineStartOffset(lineNumber - 1);
+
+        String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(file, project);
+        int offsetInVirtualFile = sourceStart - (lineNumber - 1) * (lineSeparator.length() - 1);
+        return offsetInVirtualFile - lineStartOffset + 1;
+      }
+    }).intValue();
+  }
+
+  public void parseCommandLineAndCompile(final String[] finalCmds, final CompileContext compileContext) throws Exception {
+    parseCommandLine(finalCmds);
+
+    compile(compileContext);
+  }
+
+  private static class MyCompilationUnit extends CompilationUnit {
+    private final String myDefaultEncoding;
+
+    private MyCompilationUnit(final String sourceFilePath, final String defaultEncoding) {
+      super(null, sourceFilePath, defaultEncoding);
+      myDefaultEncoding = defaultEncoding;
+    }
+
+    public char[] getContents() {
+      final String fileName = String.valueOf(getFileName());
+      try {
+        ProgressManager.checkCanceled();
+        return FileUtil.loadFileText(new File(fileName), myDefaultEncoding);
+      }
+      catch (IOException e) {
+        LOG.error(e);
+      }
+      return null;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerErrorParser.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerErrorParser.java
new file mode 100644
index 0000000..aa87dcb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerErrorParser.java
@@ -0,0 +1,131 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EclipseCompilerErrorParser extends OutputParser {
+
+  private final StringBuilder problemText = new StringBuilder();
+
+  public boolean processMessageLine(Callback callback) {
+    @NonNls String line = callback.getNextLine();
+    if (line == null) {
+      spitOutProblem(callback);
+      return false;
+    }
+    if (line.trim().length() == 0) {
+      return true;
+    }
+    if (line.equals("----------")) {
+      spitOutProblem(callback);
+      problemText.setLength(0);
+      return true;
+    }
+    problemText.append(line);
+    problemText.append("\n");
+    return true;
+  }
+
+  private void spitOutProblem(final Callback callback) {
+    final String problem = problemText.toString();
+    if (problem.trim().length() == 0) return;
+
+    @NonNls final String problemTemplate = "(\\d*)\\. (\\w*) in (.*)" +
+                                           "\\s*\\(at line (\\d*)\\)\n" +
+                                           "\\s*(.*)\n" +
+                                           "(\\s*)\\^+\n" +
+                                           "(.*)\\s*";
+    final Pattern PATTERN = Pattern.compile(problemTemplate, Pattern.DOTALL);
+    Matcher matcher = PATTERN.matcher(problem);
+    if (matcher.matches()) {
+      //String seqN = matcher.group(1);
+      @NonNls String problemType = matcher.group(2);
+      String path = matcher.group(3).trim();
+      String lineNum = matcher.group(4);
+      String codeSnippet = matcher.group(5);
+      String indentWhiteSpace = matcher.group(6);
+      String message = matcher.group(7).trim();
+
+      CompilerMessageCategory messageCategory;
+      if ("WARNING".equals(problemType)) {
+        messageCategory = CompilerMessageCategory.WARNING;
+      }
+      else if ("ERROR".equals(problemType)) {
+        messageCategory = CompilerMessageCategory.ERROR;
+      }
+      else {
+        messageCategory = CompilerMessageCategory.INFORMATION;
+      }
+      final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, FileUtil.toSystemIndependentName(path));
+      final int line = Integer.parseInt(lineNum);
+      int col = indentWhiteSpace.length();
+      final String offendingCode = codeSnippet.substring(col-1);
+
+      // try to find similar text inside source file                   
+      int colFromFile = ApplicationManager.getApplication().runReadAction(new Computable<Integer>() {
+        public Integer compute() {
+          int index = -1;
+          VirtualFile file = VirtualFileManager.getInstance().findFileByUrl(url);
+          Document document = file == null ? null : FileDocumentManager.getInstance().getDocument(file);
+          if (document != null) {
+            // line is one-based
+            int docLine = line == 0 ? 0 : line-1;
+            int startOffset = document.getLineStartOffset(docLine);
+            int endOffset = document.getLineEndOffset(docLine);
+            String lineText = document.getText().substring(startOffset, endOffset);
+            index = lineText.indexOf(offendingCode);
+            if (index == -1) {
+              for (index = 0; index < lineText.length(); index++) {
+                if (!Character.isWhitespace(lineText.charAt(index))) break;
+              }
+              if (index == lineText.length()) index = -1;
+            }
+            // to one-based
+            if (index != -1) {
+              index++;
+            }
+          }
+          return index;
+        }
+      }).intValue();
+      if (colFromFile != -1) {
+        col = colFromFile;
+      }
+      callback.message(messageCategory, message, url, line, col);
+    }
+    else {
+      callback.message(CompilerMessageCategory.WARNING, problem, null, -1, -1);
+    }
+  }
+
+  public boolean isTrimLines() {
+    return false;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerOutputParser.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerOutputParser.java
new file mode 100644
index 0000000..12ceca3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseCompilerOutputParser.java
@@ -0,0 +1,90 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class EclipseCompilerOutputParser extends OutputParser {
+  private final String myOutputDir;
+
+  public EclipseCompilerOutputParser(final String outputDir) {
+    myOutputDir = outputDir;
+  }
+
+  @NonNls private static final Pattern PATH_PATTERN = Pattern.compile("\\s*(.*) - #.*");
+  @NonNls private static final Pattern COMPILED_PATTERN = Pattern.compile("\\[\\d* unit(s)? compiled\\]");
+  @NonNls private static final Pattern GENERATED_PATTERN = Pattern.compile("\\[\\d* \\.class file(s)? generated\\]");
+  public boolean processMessageLine(Callback callback) {
+    @NonNls String line = callback.getNextLine();
+    if (line == null) {
+      return false;
+    }
+    if (line.trim().length() == 0) {
+      return true;
+    }
+    if (line.startsWith("[parsing ")) {
+      Matcher matcher = PATH_PATTERN.matcher(line.substring("[parsing ".length()));
+      matcher.matches();
+      String path = matcher.group(1);
+      callback.setProgressText(CompilerBundle.message("eclipse.compiler.parsing", path));
+      callback.fileProcessed(path);
+      return true;
+    }
+    if (line.startsWith("[reading ")) {
+      //StringTokenizer tokenizer = new StringTokenizer(line.substring("[reading ".length()), " ]");
+      //String fqn = tokenizer.nextToken();
+      callback.setProgressText(CompilerBundle.message("eclipse.compiler.reading"));
+      return true;
+    }
+    if (line.startsWith("[analyzing ")) {
+      Matcher matcher = PATH_PATTERN.matcher(line.substring("[analyzing ".length()));
+      matcher.matches();
+      String path = matcher.group(1);
+      callback.setProgressText(CompilerBundle.message("eclipse.compiler.analyzing", path));
+      return true;
+    }
+    if (line.startsWith("[completed ")) {
+      //Matcher matcher = PATH_PATTERN.matcher(line.substring("[completed ".length()));
+      //matcher.matches();
+      //String path = matcher.group(1);
+      //callback.setProgressText(CompilerBundle.message("eclipse.compiler.completed", path));
+      return true;
+    }
+    if (line.startsWith("[writing ")) {
+      Matcher matcher = PATH_PATTERN.matcher(line.substring("[writing ".length()));
+      matcher.matches();
+      String path = matcher.group(1);
+      String absPath = FileUtil.toSystemDependentName(myOutputDir + '/' + path);
+      //callback.setProgressText(CompilerBundle.message("eclipse.compiler.writing", absPath));
+      callback.fileGenerated(new FileObject(new File(absPath)));
+      return true;
+    }
+    if (COMPILED_PATTERN.matcher(line).matches() || GENERATED_PATTERN.matcher(line).matches()) {
+      return true;
+    }
+    callback.message(CompilerMessageCategory.INFORMATION, line, null, -1, -1);
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java
new file mode 100644
index 0000000..77aa2a1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompiler.java
@@ -0,0 +1,160 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Set;
+
+
+public class EclipseEmbeddedCompiler implements BackendCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.eclipse.EclipseEmbeddedCompiler");
+
+  private final Project myProject;
+  private final EclipseCompiler myEclipseExternalCompiler;
+  private int myExitCode;
+  private final EclipseCompilerDriver myEclipseCompilerDriver;
+  private static final Set<FileType> COMPILABLE_TYPES = Collections.<FileType>singleton(StdFileTypes.JAVA);
+
+  public EclipseEmbeddedCompiler(Project project) {
+    myProject = project;
+    myEclipseExternalCompiler = new EclipseCompiler(project);
+    myEclipseCompilerDriver = new EclipseCompilerDriver();
+  }
+
+  public boolean checkCompiler(final CompileScope scope) {
+    return myEclipseCompilerDriver != null && myEclipseExternalCompiler.checkCompiler(scope);
+  }
+
+  @NotNull
+  @NonNls
+  public String getId() { // used for externalization
+    return JavaCompilers.ECLIPSE_EMBEDDED_ID;
+  }
+
+  @NotNull
+  public String getPresentableName() {
+    return CompilerBundle.message("compiler.eclipse.embedded.name");
+  }
+
+  @NotNull
+  public Configurable createConfigurable() {
+    return new EclipseCompilerConfigurable(EclipseEmbeddedCompilerConfiguration.getOptions(myProject, EclipseEmbeddedCompilerConfiguration.class));
+  }
+
+  @NotNull
+  public Set<FileType> getCompilableFileTypes() {
+    return COMPILABLE_TYPES;
+  }
+
+  @Nullable
+  public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
+    return new OutputParser() {
+      public boolean processMessageLine(Callback callback) {
+        return myEclipseCompilerDriver.processMessageLine(callback, outputDir, myProject);
+      }
+    };
+  }
+
+  @Nullable
+  public OutputParser createOutputParser(@NotNull final String outputDir) {
+    return null;
+  }
+
+  public void compileFinished() {
+  }
+
+
+  @NotNull
+  public Process launchProcess(@NotNull final ModuleChunk chunk, @NotNull final String outputDir, @NotNull final CompileContext compileContext) throws IOException {
+    @NonNls final ArrayList<String> commandLine = new ArrayList<String>();
+    final IOException[] ex = {null};
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          final EclipseCompilerOptions options = EclipseCompilerConfiguration.getOptions(myProject, EclipseEmbeddedCompilerConfiguration.class);
+          myEclipseExternalCompiler.addCommandLineOptions(commandLine, chunk, outputDir, options, false, false);
+        }
+        catch (IOException e) {
+          ex[0] = e;
+        }
+      }
+    });
+    if (ex[0] != null) {
+      throw ex[0];
+    }
+
+    return new Process() {
+      public OutputStream getOutputStream() {
+        throw new UnsupportedOperationException();
+      }
+
+      public InputStream getInputStream() {
+        return null;
+      }
+
+      public InputStream getErrorStream() {
+        return null;
+      }
+
+      public void destroy() {
+      }
+
+      public int waitFor() {
+        try {
+          commandLine.remove("-verbose");
+          String[] finalCmds = ArrayUtil.toStringArray(commandLine);
+          myEclipseCompilerDriver.parseCommandLineAndCompile(finalCmds,compileContext);
+          myExitCode = 0;
+          return myExitCode;
+        }
+        catch (Exception e) {
+          compileContext.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+          LOG.info(e);
+          myExitCode = -1;
+          return -1;
+        }
+      }
+
+      public int exitValue() {
+        return myExitCode;
+      }
+    };
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompilerConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompilerConfiguration.java
new file mode 100755
index 0000000..1c36e57
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseEmbeddedCompilerConfiguration.java
@@ -0,0 +1,31 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.components.StorageScheme;
+
+@State(
+  name = "EclipseEmbeddedCompilerSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class EclipseEmbeddedCompilerConfiguration extends EclipseCompilerConfiguration {
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseSettingsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseSettingsBuilder.java
new file mode 100644
index 0000000..7748223
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/eclipse/EclipseSettingsBuilder.java
@@ -0,0 +1,47 @@
+/*
+ * 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.compiler.impl.javaCompiler.eclipse;
+
+import com.intellij.compiler.impl.javaCompiler.javac.JavacSettingsBuilder;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.Chunk;
+import org.jetbrains.jps.model.java.compiler.EclipseCompilerOptions;
+
+import java.util.Collection;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 9/27/12
+ */
+public class EclipseSettingsBuilder extends JavacSettingsBuilder {
+  public EclipseSettingsBuilder(final EclipseCompilerOptions options) {
+    super(options);
+  }
+
+  @Override
+  public EclipseCompilerOptions getOptions() {
+    return (EclipseCompilerOptions)super.getOptions();
+  }
+
+  @Override
+  public Collection<String> getOptions(Chunk<Module> chunk) {
+    final Collection<String> options = super.getOptions(chunk);
+    if (getOptions().PROCEED_ON_ERROR) {
+      options.add("-proceedOnError");
+    }
+    return options;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/FilePathActionJavac.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/FilePathActionJavac.java
new file mode 100644
index 0000000..fc32b08
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/FilePathActionJavac.java
@@ -0,0 +1,65 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+
+import java.io.File;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+/**
+ * @author Eugene Zhuravlev              
+ *         Date: Sep 14, 2005
+ */
+public class FilePathActionJavac extends JavacParserAction {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.javac.FilePathActionJavac");
+  private final Matcher myJdk7FormatMatcher;
+  
+  public FilePathActionJavac(final Matcher matcher) {
+    super(matcher);
+    myJdk7FormatMatcher = Pattern.compile("^\\w+\\[(.+)\\]$", Pattern.CASE_INSENSITIVE).matcher("");
+  }
+
+  protected void doExecute(final String line, String filePath, final OutputParser.Callback callback) {
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Process parsing message: " + filePath);
+    }
+
+    // for jdk7: cut off characters wrapping the path. e.g. "RegularFileObject[C:/tmp/bugs/src/a/Demo1.java]"
+    if (myJdk7FormatMatcher.reset(filePath).matches()) {
+      filePath = myJdk7FormatMatcher.group(1);
+    }
+
+    int index = filePath.lastIndexOf('/');
+    final String name = index >= 0 ? filePath.substring(index + 1) : filePath;
+
+    final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name);
+    if (StdFileTypes.JAVA.equals(fileType)) {
+      callback.fileProcessed(filePath);
+      callback.setProgressText(CompilerBundle.message("progress.parsing.file", name));
+    }
+    else if (StdFileTypes.CLASS.equals(fileType)) {
+      callback.fileGenerated(new FileObject(new File(filePath)));
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java
new file mode 100644
index 0000000..e962a93
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacCompiler.java
@@ -0,0 +1,450 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerIOUtil;
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerPaths;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.*;
+import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
+import com.intellij.openapi.projectRoots.impl.MockJdkWrapper;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.rt.compiler.JavacRunner;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+import org.jetbrains.jps.model.java.compiler.JavaCompilers;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+
+import java.io.*;
+import java.util.*;
+
+public class JavacCompiler extends ExternalCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.javaCompiler.javac.JavacCompiler");
+  private final Project myProject;
+  private final List<File> myTempFiles = new ArrayList<File>();
+  @NonNls private static final String JAVAC_MAIN_CLASS_OLD = "sun.tools.javac.Main";
+  @NonNls public static final String JAVAC_MAIN_CLASS = "com.sun.tools.javac.Main";
+  private boolean myAnnotationProcessorMode = false;
+
+  public JavacCompiler(Project project) {
+    myProject = project;
+  }
+
+  public boolean isAnnotationProcessorMode() {
+    return myAnnotationProcessorMode;
+  }
+
+  /**
+   * @param annotationProcessorMode
+   * @return previous value
+   */
+  public boolean setAnnotationProcessorMode(boolean annotationProcessorMode) {
+    final boolean oldValue = myAnnotationProcessorMode;
+    myAnnotationProcessorMode = annotationProcessorMode;
+    return oldValue;
+  }
+
+  public boolean checkCompiler(final CompileScope scope) {
+    final Module[] modules = scope.getAffectedModules();
+    final Set<Sdk> checkedJdks = new HashSet<Sdk>();
+    for (final Module module : modules) {
+      final Sdk jdk  = ModuleRootManager.getInstance(module).getSdk();
+      if (jdk == null || checkedJdks.contains(jdk)) {
+        continue;
+      }
+      checkedJdks.add(jdk);
+      final SdkTypeId sdkType = jdk.getSdkType();
+      if (!(sdkType instanceof JavaSdkType)) {
+        continue;
+      }
+      final VirtualFile homeDirectory = jdk.getHomeDirectory();
+      if (homeDirectory == null) {
+        Messages.showMessageDialog(
+          myProject, CompilerBundle.jdkHomeNotFoundMessage(jdk), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
+        );
+        return false;
+      }
+      final String vmExecutablePath = ((JavaSdkType)sdkType).getVMExecutablePath(jdk);
+      if (vmExecutablePath == null) {
+        Messages.showMessageDialog(
+          myProject, CompilerBundle.message("javac.error.vm.executable.missing", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
+        );
+        return false;
+      }
+      final String toolsJarPath = ((JavaSdkType)sdkType).getToolsPath(jdk);
+      if (toolsJarPath == null) {
+        Messages.showMessageDialog(
+          myProject, CompilerBundle.message("javac.error.tools.jar.missing", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
+        );
+        return false;
+      }
+      final String versionString = jdk.getVersionString();
+      if (versionString == null) {
+        Messages.showMessageDialog(
+          myProject, CompilerBundle.message("javac.error.unknown.jdk.version", jdk.getName()), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
+        );
+        return false;
+      }
+
+      if (CompilerUtil.isOfVersion(versionString, "1.0")) {
+        Messages.showMessageDialog(
+          myProject, CompilerBundle.message("javac.error.1_0_compilation.not.supported"), CompilerBundle.message("compiler.javac.name"), Messages.getErrorIcon()
+        );
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  @NotNull
+  @NonNls
+  public String getId() { // used for externalization
+    return JavaCompilers.JAVAC_ID;
+  }
+
+  @NotNull
+  public String getPresentableName() {
+    return CompilerBundle.message("compiler.javac.name");
+  }
+
+  @NotNull
+  public Configurable createConfigurable() {
+    return new JavacConfigurable(JavacConfiguration.getOptions(myProject, JavacConfiguration.class));
+  }
+
+  public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
+    return new JavacOutputParser(myProject);
+  }
+
+  public OutputParser createOutputParser(@NotNull final String outputDir) {
+    return null;
+  }
+
+  private static class MyException extends RuntimeException {
+    private MyException(Throwable cause) {
+      super(cause);
+    }
+  }
+
+  @NotNull
+  public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
+    throws IOException, IllegalArgumentException {
+
+    try {
+      return ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
+        public String[] compute() {
+          try {
+            final List<String> commandLine = new ArrayList<String>();
+            createStartupCommand(chunk, commandLine, outputPath, JavacConfiguration.getOptions(myProject, JavacConfiguration.class), context.isAnnotationProcessorsEnabled());
+            return ArrayUtil.toStringArray(commandLine);
+          }
+          catch (IOException e) {
+            throw new MyException(e);
+          }
+        }
+      });
+    }
+    catch (MyException e) {
+      Throwable cause = e.getCause();
+      if (cause instanceof IOException) {
+        throw (IOException)cause;
+      }
+      throw e;
+    }
+  }
+
+  private void createStartupCommand(final ModuleChunk chunk, @NonNls final List<String> commandLine, final String outputPath,
+                                    JpsJavaCompilerOptions javacOptions, final boolean annotationProcessorsEnabled) throws IOException {
+    final Sdk jdk = getJdkForStartupCommand(chunk);
+    final String versionString = jdk.getVersionString();
+    JavaSdkVersion version = JavaSdk.getInstance().getVersion(jdk);
+    if (versionString == null || version == null || !(jdk.getSdkType() instanceof JavaSdkType)) {
+      throw new IllegalArgumentException(CompilerBundle.message("javac.error.unknown.jdk.version", jdk.getName()));
+    }
+    final boolean isVersion1_0 = version == JavaSdkVersion.JDK_1_0;
+    final boolean isVersion1_1 = version == JavaSdkVersion.JDK_1_1;
+
+    JavaSdkType sdkType = (JavaSdkType)jdk.getSdkType();
+
+    final String toolsJarPath = sdkType.getToolsPath(jdk);
+    if (toolsJarPath == null) {
+      throw new IllegalArgumentException(CompilerBundle.message("javac.error.tools.jar.missing", jdk.getName()));
+    }
+
+    final String vmExePath = sdkType.getVMExecutablePath(jdk);
+
+    commandLine.add(vmExePath);
+
+    if (version.isAtLeast(JavaSdkVersion.JDK_1_2)) {
+      commandLine.add("-Xmx" + javacOptions.MAXIMUM_HEAP_SIZE + "m");
+    }
+    else {
+      commandLine.add("-mx" + javacOptions.MAXIMUM_HEAP_SIZE + "m");
+    }
+
+    final List<String> additionalOptions =
+      addAdditionalSettings(commandLine, javacOptions, myAnnotationProcessorMode, version, chunk, annotationProcessorsEnabled);
+
+    CompilerUtil.addLocaleOptions(commandLine, false);
+
+    commandLine.add("-classpath");
+
+    if (isVersion1_0) {
+      commandLine.add(sdkType.getToolsPath(jdk)); //  do not use JavacRunner for jdk 1.0
+    }
+    else {
+      commandLine.add(sdkType.getToolsPath(jdk) + File.pathSeparator + JavaSdkUtil.getIdeaRtJarPath());
+      commandLine.add(JavacRunner.class.getName());
+      commandLine.add("\"" + versionString + "\"");
+    }
+
+    if (version.isAtLeast(JavaSdkVersion.JDK_1_3)) {
+      commandLine.add(JAVAC_MAIN_CLASS);
+    }
+    else {
+      commandLine.add(JAVAC_MAIN_CLASS_OLD);
+    }
+
+    addCommandLineOptions(chunk, commandLine, outputPath, jdk, isVersion1_0, isVersion1_1, myTempFiles, true, true, myAnnotationProcessorMode);
+
+    commandLine.addAll(additionalOptions);
+
+    final List<VirtualFile> files = chunk.getFilesToCompile();
+
+    if (isVersion1_0) {
+      for (VirtualFile file : files) {
+        String path = file.getPath();
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Adding path for compilation " + path);
+        }
+        commandLine.add(CompilerUtil.quotePath(path));
+      }
+    }
+    else {
+      File sourcesFile = FileUtil.createTempFile("javac", ".tmp");
+      sourcesFile.deleteOnExit();
+      myTempFiles.add(sourcesFile);
+      final PrintWriter writer = new PrintWriter(new BufferedWriter(new FileWriter(sourcesFile)));
+      try {
+        for (final VirtualFile file : files) {
+          // Important: should use "/" slashes!
+          // but not for JDK 1.5 - see SCR 36673
+          final String path = version.isAtLeast(JavaSdkVersion.JDK_1_5) ? file.getPath().replace('/', File.separatorChar) : file.getPath();
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Adding path for compilation " + path);
+          }
+          writer.println(isVersion1_1 ? path : CompilerUtil.quotePath(path));
+        }
+      }
+      finally {
+        writer.close();
+      }
+      commandLine.add("@" + sourcesFile.getAbsolutePath());
+    }
+  }
+
+  public static List<String> addAdditionalSettings(List<String> commandLine, JpsJavaCompilerOptions javacOptions, boolean isAnnotationProcessing,
+                                                   JavaSdkVersion version, ModuleChunk chunk, boolean annotationProcessorsEnabled) {
+    final List<String> additionalOptions = new ArrayList<String>();
+    StringTokenizer tokenizer = new StringTokenizer(new JavacSettingsBuilder(javacOptions).getOptionsString(chunk), " ");
+    if (!version.isAtLeast(JavaSdkVersion.JDK_1_6)) {
+      isAnnotationProcessing = false; // makes no sense for these versions
+      annotationProcessorsEnabled = false;
+    }
+    if (isAnnotationProcessing) {
+      final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(chunk.getProject()).getAnnotationProcessingConfiguration(chunk.getModules()[0]);
+      additionalOptions.add("-Xprefer:source");
+      additionalOptions.add("-implicit:none");
+      additionalOptions.add("-proc:only");
+      if (!config.isObtainProcessorsFromClasspath()) {
+        final String processorPath = config.getProcessorPath();
+        additionalOptions.add("-processorpath");
+        additionalOptions.add(FileUtil.toSystemDependentName(processorPath));
+      }
+      final Set<String> processors = config.getProcessors();
+      if (!processors.isEmpty()) {
+        additionalOptions.add("-processor");
+        additionalOptions.add(StringUtil.join(processors, ","));
+      }
+      for (Map.Entry<String, String> entry : config.getProcessorOptions().entrySet()) {
+        additionalOptions.add("-A" + entry.getKey() + "=" +entry.getValue());
+      }
+    }
+    else {
+      if (annotationProcessorsEnabled) {
+        // Unless explicitly specified by user, disable annotation processing by default for 'java compilation' mode
+        // This is needed to suppress unwanted side-effects from auto-discovered processors from compilation classpath
+        additionalOptions.add("-proc:none");
+      }
+    }
+
+    while (tokenizer.hasMoreTokens()) {
+      @NonNls String token = tokenizer.nextToken();
+      if (version == JavaSdkVersion.JDK_1_0 && "-deprecation".equals(token)) {
+        continue; // not supported for this version
+      }
+      if (!version.isAtLeast(JavaSdkVersion.JDK_1_5) && "-Xlint".equals(token)) {
+        continue; // not supported in these versions
+      }
+      if (isAnnotationProcessing) {
+        if (token.startsWith("-proc:")) {
+          continue;
+        }
+        if (token.startsWith("-implicit:")) {
+          continue;
+        }
+      }
+      else { // compiling java
+        if (annotationProcessorsEnabled) {
+          // in this mode we have -proc:none already added above, so user's settings should be ignored
+          if (token.startsWith("-proc:")) {
+            continue;
+          }
+        }
+      }
+      if (token.startsWith("-J-")) {
+        commandLine.add(token.substring("-J".length()));
+      }
+      else {
+        additionalOptions.add(token);
+      }
+    }
+
+    return additionalOptions;
+  }
+
+  public static void addCommandLineOptions(ModuleChunk chunk, @NonNls List<String> commandLine, String outputPath, Sdk jdk,
+                                           boolean version1_0,
+                                           boolean version1_1,
+                                           List<File> tempFiles, boolean addSourcePath, boolean useTempFile,
+                                           boolean isAnnotationProcessingMode) throws IOException {
+
+    LanguageLevel languageLevel = chunk.getLanguageLevel();
+    CompilerUtil.addSourceCommandLineSwitch(jdk, languageLevel, commandLine);
+    CompilerUtil.addTargetCommandLineSwitch(chunk, commandLine);
+
+    commandLine.add("-verbose");
+
+    final String cp = chunk.getCompilationClasspath();
+    final String bootCp = chunk.getCompilationBootClasspath();
+
+    final String classPath;
+    if (version1_0 || version1_1) {
+      classPath = bootCp + File.pathSeparator + cp;
+    }
+    else {
+      classPath = cp;
+      commandLine.add("-bootclasspath");
+      addClassPathValue(jdk, false, commandLine, bootCp, "javac_bootcp", tempFiles, useTempFile);
+    }
+
+    commandLine.add("-classpath");
+    addClassPathValue(jdk, version1_0, commandLine, classPath, "javac_cp", tempFiles, useTempFile);
+
+    if (!version1_1 && !version1_0 && addSourcePath) {
+      commandLine.add("-sourcepath");
+      // this way we tell the compiler that the sourcepath is "empty". However, javac thinks that sourcepath is 'new File("")'
+      // this may cause problems if we have java code in IDEA working directory
+      if (isAnnotationProcessingMode) {
+        final int currentSourcesMode = chunk.getSourcesFilter();
+        commandLine.add(chunk.getSourcePath(currentSourcesMode == ModuleChunk.TEST_SOURCES? ModuleChunk.ALL_SOURCES : currentSourcesMode));
+      }
+      else {
+        commandLine.add("\"\"");
+      }
+    }
+
+    if (isAnnotationProcessingMode) {
+      commandLine.add("-s");
+      commandLine.add(outputPath.replace('/', File.separatorChar));
+      final String moduleOutputPath = CompilerPaths.getModuleOutputPath(chunk.getModules()[0], false);
+      if (moduleOutputPath != null) {
+        commandLine.add("-d");
+        commandLine.add(moduleOutputPath.replace('/', File.separatorChar));
+      }
+    }
+    else {
+      commandLine.add("-d");
+      commandLine.add(outputPath.replace('/', File.separatorChar));
+    }
+  }
+
+  private static void addClassPathValue(final Sdk jdk, final boolean isVersion1_0, final List<String> commandLine, final String cpString, @NonNls final String tempFileName,
+                                        List<File> tempFiles,
+                                        boolean useTempFile) throws IOException {
+    if (!useTempFile) {
+      commandLine.add(cpString);
+      return;
+    }
+    // must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not
+    if (isVersion1_0) {
+      commandLine.add(((JavaSdkType)jdk.getSdkType()).getToolsPath(jdk) + File.pathSeparator + cpString);
+    }
+    else {
+      File cpFile = FileUtil.createTempFile(tempFileName, ".tmp");
+      cpFile.deleteOnExit();
+      tempFiles.add(cpFile);
+      final DataOutputStream out = new DataOutputStream(new BufferedOutputStream(new FileOutputStream(cpFile)));
+      try {
+        CompilerIOUtil.writeString(cpString, out);
+      }
+      finally {
+        out.close();
+      }
+      commandLine.add("@" + cpFile.getAbsolutePath());
+    }
+  }
+
+  private Sdk getJdkForStartupCommand(final ModuleChunk chunk) {
+    final Sdk jdk = chunk.getJdk();
+    if (ApplicationManager.getApplication().isUnitTestMode() && JavacConfiguration.getOptions(myProject, JavacConfiguration.class).isTestsUseExternalCompiler()) {
+      final String jdkHomePath = CompilerConfigurationImpl.getTestsExternalCompilerHome();
+      if (jdkHomePath == null) {
+        throw new IllegalArgumentException("[TEST-MODE] Cannot determine home directory for JDK to use javac from");
+      }
+      // when running under Mock JDK use VM executable from the JDK on which the tests run
+      return new MockJdkWrapper(jdkHomePath, jdk);
+    }
+    return jdk;
+  }
+
+  public void compileFinished() {
+    FileUtil.asyncDelete(myTempFiles);
+    myTempFiles.clear();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
new file mode 100644
index 0000000..c51f5f3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfigurable.java
@@ -0,0 +1,97 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.options.ComparingUtils;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.ui.RawCommandLineEditor;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+
+import javax.swing.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class JavacConfigurable implements Configurable{
+  private JPanel myPanel;
+  private JCheckBox myCbDebuggingInfo;
+  private JCheckBox myCbDeprecation;
+  private JCheckBox myCbGenerateNoWarnings;
+  private RawCommandLineEditor myAdditionalOptionsField;
+  private JTextField myJavacMaximumHeapField;
+  private final JpsJavaCompilerOptions myJavacSettings;
+
+  public JavacConfigurable(final JpsJavaCompilerOptions javacSettings) {
+    myJavacSettings = javacSettings;
+    myAdditionalOptionsField.setDialogCaption(CompilerBundle.message("java.compiler.option.additional.command.line.parameters"));
+  }
+
+  public String getDisplayName() {
+    return null;
+  }
+
+  public String getHelpTopic() {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public boolean isModified() {
+    boolean isModified = false;
+    isModified |= ComparingUtils.isModified(myJavacMaximumHeapField, myJavacSettings.MAXIMUM_HEAP_SIZE);
+
+    isModified |= ComparingUtils.isModified(myCbDeprecation, myJavacSettings.DEPRECATION);
+    isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJavacSettings.DEBUGGING_INFO);
+    isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJavacSettings.GENERATE_NO_WARNINGS);
+    isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myJavacSettings.ADDITIONAL_OPTIONS_STRING);
+    return isModified;
+  }
+
+  public void apply() throws ConfigurationException {
+
+    try {
+      myJavacSettings.MAXIMUM_HEAP_SIZE = Integer.parseInt(myJavacMaximumHeapField.getText());
+      if(myJavacSettings.MAXIMUM_HEAP_SIZE < 1) {
+        myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
+      }
+    }
+    catch(NumberFormatException exception) {
+      myJavacSettings.MAXIMUM_HEAP_SIZE = 128;
+    }
+
+    myJavacSettings.DEPRECATION =  myCbDeprecation.isSelected();
+    myJavacSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
+    myJavacSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
+    myJavacSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText();
+  }
+
+  public void reset() {
+    myJavacMaximumHeapField.setText(Integer.toString(myJavacSettings.MAXIMUM_HEAP_SIZE));
+    myCbDeprecation.setSelected(myJavacSettings.DEPRECATION);
+    myCbDebuggingInfo.setSelected(myJavacSettings.DEBUGGING_INFO);
+    myCbGenerateNoWarnings.setSelected(myJavacSettings.GENERATE_NO_WARNINGS);
+    myAdditionalOptionsField.setText(myJavacSettings.ADDITIONAL_OPTIONS_STRING);
+  }
+
+  public void disposeUIResources() {
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfiguration.java
new file mode 100755
index 0000000..6e1f497
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacConfiguration.java
@@ -0,0 +1,57 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+
+@State(
+  name = "JavacSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class JavacConfiguration implements PersistentStateComponent<JpsJavaCompilerOptions> {
+  private final JpsJavaCompilerOptions mySettings = new JpsJavaCompilerOptions();
+  private final Project myProject;
+
+  public JavacConfiguration(Project project) {
+    myProject = project;
+  }
+
+  @Override
+  @NotNull
+  public JpsJavaCompilerOptions getState() {
+    JpsJavaCompilerOptions state = new JpsJavaCompilerOptions();
+    XmlSerializerUtil.copyBean(mySettings, state);
+    state.ADDITIONAL_OPTIONS_STRING = PathMacroManager.getInstance(myProject).collapsePathsRecursively(state.ADDITIONAL_OPTIONS_STRING);
+    return state;
+  }
+
+  @Override
+  public void loadState(JpsJavaCompilerOptions state) {
+    XmlSerializerUtil.copyBean(state, mySettings);
+  }
+
+  public static JpsJavaCompilerOptions getOptions(Project project, Class<? extends JavacConfiguration> aClass) {
+    JavacConfiguration configuration = ServiceManager.getService(project, aClass);
+    return configuration.mySettings;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
new file mode 100644
index 0000000..3291deb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOptionsPanel.form
@@ -0,0 +1,109 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.javac.JavacConfigurable">
+  <grid id="280f7" binding="myPanel" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="79" y="160" width="574" height="210"/>
+    </constraints>
+    <properties/>
+    <clientProperties>
+      <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+    </clientProperties>
+    <border type="etched" title-resource-bundle="messages/CompilerBundle" title-key="javac.options.group.title"/>
+    <children>
+      <component id="8538e" class="javax.swing.JCheckBox" binding="myCbDeprecation">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="true"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.report.deprecated"/>
+        </properties>
+      </component>
+      <component id="3d38f" class="javax.swing.JCheckBox" binding="myCbDebuggingInfo">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <selected value="true"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.debugging.info"/>
+        </properties>
+      </component>
+      <component id="90803" class="javax.swing.JCheckBox" binding="myCbGenerateNoWarnings">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
+        </properties>
+      </component>
+      <grid id="d7ddf" layout-manager="GridLayoutManager" row-count="2" column-count="4" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="10" left="8" bottom="0" right="0"/>
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f8a80" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.additional.command.line.parameters"/>
+            </properties>
+          </component>
+          <component id="479c2" class="com.intellij.ui.RawCommandLineEditor" binding="myAdditionalOptionsField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="3" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+          <component id="327dc" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="4" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="javac.option.max.heap.size"/>
+            </properties>
+          </component>
+          <component id="15c16" class="javax.swing.JTextField" binding="myJavacMaximumHeapField">
+            <constraints>
+              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false">
+                <preferred-size width="60" height="-1"/>
+              </grid>
+            </constraints>
+            <properties>
+              <margin top="0" left="2" bottom="0" right="0"/>
+              <text value="128"/>
+            </properties>
+            <clientProperties>
+              <caretAspectRatio class="java.lang.Float" value="0.04"/>
+            </clientProperties>
+          </component>
+          <component id="9ae23" class="com.intellij.ui.components.JBLabel">
+            <constraints>
+              <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <enabled value="false"/>
+              <text value="(ineffective when &quot;Use external build&quot; is on)"/>
+            </properties>
+          </component>
+          <hspacer id="30d41">
+            <constraints>
+              <grid row="1" column="3" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </hspacer>
+        </children>
+      </grid>
+      <vspacer id="72a3c">
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java
new file mode 100644
index 0000000..ba12e69
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacOutputParser.java
@@ -0,0 +1,283 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.editor.ex.util.EditorUtil;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
+import com.intellij.rt.compiler.JavacResourcesReader;
+import com.intellij.util.StringBuilderSpinAllocator;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class JavacOutputParser extends OutputParser {
+  private final int myTabSize;
+  @NonNls private String WARNING_PREFIX = "warning:"; // default value
+
+  public JavacOutputParser(Project project) {
+    myTabSize = CodeStyleSettingsManager.getSettings(project).getTabSize(StdFileTypes.JAVA);
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      // emulate patterns setup if 'embedded' javac is used (javac is started not via JavacRunner)
+      addJavacPattern(JavacResourcesReader.MSG_PARSING_STARTED + JavacResourcesReader.CATEGORY_VALUE_DIVIDER + "[parsing started {0}]");
+      addJavacPattern(JavacResourcesReader.MSG_PARSING_COMPLETED + JavacResourcesReader.CATEGORY_VALUE_DIVIDER + "[parsing completed {0}ms]");
+      addJavacPattern(JavacResourcesReader.MSG_LOADING + JavacResourcesReader.CATEGORY_VALUE_DIVIDER + "[loading {0}]");
+      addJavacPattern(JavacResourcesReader.MSG_CHECKING + JavacResourcesReader.CATEGORY_VALUE_DIVIDER + "[checking {0}]");
+      addJavacPattern(JavacResourcesReader.MSG_WROTE + JavacResourcesReader.CATEGORY_VALUE_DIVIDER + "[wrote {0}]");
+    }
+  }
+
+  public boolean processMessageLine(Callback callback) {
+    if (super.processMessageLine(callback)) {
+      return true;
+    }                                              
+    final String line = callback.getCurrentLine();
+    if (line == null) {
+      return false;
+    }
+    if (JavacResourcesReader.MSG_PATTERNS_START.equals(line)) {
+      myParserActions.clear();
+      while (true) {
+        final String patternLine = callback.getNextLine();
+        if (JavacResourcesReader.MSG_PATTERNS_END.equals(patternLine)) {
+          break;
+        }
+        addJavacPattern(patternLine);
+      }
+      return true;
+    }
+
+    int colonIndex1 = line.indexOf(':');
+    if (colonIndex1 == 1){ // drive letter
+      colonIndex1 = line.indexOf(':', colonIndex1 + 1);
+    }
+
+    if (colonIndex1 >= 0){ // looks like found something like file path
+      @NonNls String part1 = line.substring(0, colonIndex1).trim();
+      if(part1.equalsIgnoreCase("error") /*jikes*/ || part1.equalsIgnoreCase("Caused by")) {
+        addMessage(callback, CompilerMessageCategory.ERROR, line.substring(colonIndex1));
+        return true;
+      }
+      if(part1.equalsIgnoreCase("warning")) {
+        addMessage(callback, CompilerMessageCategory.WARNING, line.substring(colonIndex1));
+        return true;
+      }
+      if(part1.equals("javac")) {
+        addMessage(callback, CompilerMessageCategory.ERROR, line);
+        return true;
+      }
+
+      final int colonIndex2 = line.indexOf(':', colonIndex1 + 1);
+      if (colonIndex2 >= 0){
+        final String filePath = part1.replace(File.separatorChar, '/');
+        final Boolean fileExists = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>(){
+          public Boolean compute(){
+            return LocalFileSystem.getInstance().findFileByPath(filePath) != null? Boolean.TRUE : Boolean.FALSE;
+          }
+        });
+        if (!fileExists.booleanValue()) {
+          // the part one turned out to be something else than a file path
+          return true;
+        }
+        try {
+          final int lineNum = Integer.parseInt(line.substring(colonIndex1 + 1, colonIndex2).trim());
+          String message = line.substring(colonIndex2 + 1).trim();
+          CompilerMessageCategory category = CompilerMessageCategory.ERROR;
+          if (message.startsWith(WARNING_PREFIX)){
+            message = message.substring(WARNING_PREFIX.length()).trim();
+            category = CompilerMessageCategory.WARNING;
+          }
+
+          List<String> messages = new ArrayList<String>();
+          messages.add(message);
+          int colNum;
+          String prevLine = null;
+          do{
+            final String nextLine = callback.getNextLine();
+            if (nextLine == null) {
+              return false;
+            }
+            if (nextLine.trim().equals("^")){
+              final CharSequence chars = prevLine == null ? line : prevLine;
+              final int offset = Math.max(0, Math.min(chars.length(), nextLine.indexOf('^')));
+              colNum = EditorUtil.calcColumnNumber(null, chars,0, offset, myTabSize);
+              String messageEnd = callback.getNextLine();
+              while (isMessageEnd(messageEnd)) {
+                messages.add(messageEnd.trim());
+                messageEnd = callback.getNextLine();
+              }
+              if (messageEnd != null) {
+                callback.pushBack(messageEnd);
+              }
+              break;
+            }
+            if (prevLine != null) {
+              messages.add(prevLine);
+            }
+            prevLine = nextLine;
+          }
+          while(true);
+
+          if (colNum >= 0){
+            messages = convertMessages(messages);
+            final StringBuilder buf = StringBuilderSpinAllocator.alloc();
+            try {
+              for (final String m : messages) {
+                if (buf.length() > 0) {
+                  buf.append("\n");
+                }
+                buf.append(m);
+              }
+              addMessage(callback, category, buf.toString(), VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath), lineNum, colNum + 1);
+            }
+            finally {
+              StringBuilderSpinAllocator.dispose(buf);
+            }
+            return true;
+          }
+        }
+        catch (NumberFormatException ignored) {
+        }
+      }
+    }
+
+    if(line.endsWith("java.lang.OutOfMemoryError")) {
+      addMessage(callback, CompilerMessageCategory.ERROR, CompilerBundle.message("error.javac.out.of.memory"));
+      return true;
+    }
+
+    addMessage(callback, CompilerMessageCategory.INFORMATION, line);
+    return true;
+  }
+
+  private static boolean isMessageEnd(String line) {
+    return line != null && line.length() > 0 && Character.isWhitespace(line.charAt(0));
+  }
+
+
+  private static List<String> convertMessages(List<String> messages) {
+    if(messages.size() <= 1) {
+      return messages;
+    }
+    final String line0 = messages.get(0);
+    final String line1 = messages.get(1);
+    final int colonIndex = line1.indexOf(':');
+    if (colonIndex > 0){
+      @NonNls String part1 = line1.substring(0, colonIndex).trim();
+      // jikes
+      if ("symbol".equals(part1)){
+        String symbol = line1.substring(colonIndex + 1).trim();
+        messages.remove(1);
+        if(messages.size() >= 2) {
+          messages.remove(1);
+        }
+        messages.set(0, line0 + " " + symbol);
+      }
+    }
+    return messages;
+  }
+
+  private void addJavacPattern(@NonNls final String line) {
+    final int dividerIndex = line.indexOf(JavacResourcesReader.CATEGORY_VALUE_DIVIDER);
+    if (dividerIndex < 0) {
+      // by reports it may happen for some IBM JDKs (empty string?)
+      return;
+    }
+    final String category = line.substring(0, dividerIndex);
+    final String resourceBundleValue = line.substring(dividerIndex + 1);
+    if (JavacResourcesReader.MSG_PARSING_COMPLETED.equals(category) ||
+        JavacResourcesReader.MSG_PARSING_STARTED.equals(category) ||
+        JavacResourcesReader.MSG_WROTE.equals(category)
+      ) {
+      myParserActions.add(new FilePathActionJavac(createMatcher(resourceBundleValue)));
+    }
+    else if (JavacResourcesReader.MSG_CHECKING.equals(category)) {
+      myParserActions.add(new JavacParserAction(createMatcher(resourceBundleValue)) {
+        protected void doExecute(final String line, String parsedData, final Callback callback) {
+          callback.setProgressText(CompilerBundle.message("progress.compiling.class", parsedData));
+        }
+      });
+    }
+    else if (JavacResourcesReader.MSG_LOADING.equals(category)) {
+      myParserActions.add(new JavacParserAction(createMatcher(resourceBundleValue)) {
+        protected void doExecute(final String line, @Nullable String parsedData, final Callback callback) {
+          callback.setProgressText(CompilerBundle.message("progress.loading.classes"));
+        }
+      });
+    }
+    else if (JavacResourcesReader.MSG_NOTE.equals(category)) {
+      myParserActions.add(new JavacParserAction(createMatcher(resourceBundleValue)) {
+        protected void doExecute(final String line, @Nullable final String filePath, final Callback callback) {
+          final boolean fileExists = filePath != null && ApplicationManager.getApplication().runReadAction(new Computable<Boolean>(){
+            public Boolean compute(){
+              return LocalFileSystem.getInstance().findFileByPath(filePath) != null? Boolean.TRUE : Boolean.FALSE;
+            }
+          });
+          if (fileExists) {
+            addMessage(callback, CompilerMessageCategory.WARNING, line, VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath), -1, -1);
+          }
+          else {
+            addMessage(callback, CompilerMessageCategory.INFORMATION, line);
+          }
+        }
+      });
+    }
+    else if (JavacResourcesReader.MSG_WARNING.equals(category)) {
+      WARNING_PREFIX = resourceBundleValue;
+    }
+    else if (JavacResourcesReader.MSG_STATISTICS.equals(category)) {
+      myParserActions.add(new JavacParserAction(createMatcher(resourceBundleValue)) {
+        protected void doExecute(final String line, @Nullable String parsedData, final Callback callback) {
+          // empty
+        }
+      });
+    }
+    else if (JavacResourcesReader.MSG_IGNORED.equals(category)) {
+      myParserActions.add(new JavacParserAction(createMatcher(resourceBundleValue)) {
+        protected void doExecute(final String line, @Nullable String parsedData, final Callback callback) {
+          // ignored
+        }
+      });
+    }
+  }
+
+
+  /**
+   * made public for Tests, do not use this method directly
+   */
+  public static Matcher createMatcher(@NonNls final String resourceBundleValue) {
+    @NonNls String regexp = resourceBundleValue.replaceAll("([\\[\\]\\(\\)\\.\\*])", "\\\\$1");
+    regexp = regexp.replaceAll("\\{\\d+\\}", "(.+)");
+    return Pattern.compile(regexp, Pattern.CASE_INSENSITIVE).matcher("");
+  }
+
+  public boolean isTrimLines() {
+    return false;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacParserAction.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacParserAction.java
new file mode 100644
index 0000000..a9eefaf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacParserAction.java
@@ -0,0 +1,48 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.ParserAction;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.regex.Matcher;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Sep 14, 2005
+ */
+public abstract class JavacParserAction extends ParserAction {
+  private final Matcher myMatcher;
+
+  protected JavacParserAction(final Matcher matcher) {
+    myMatcher = matcher;
+  }
+
+  public final boolean execute(String line, final OutputParser.Callback callback) {
+    myMatcher.reset(line);
+    if (!myMatcher.matches()) {
+      return false;
+    }
+    final String parsed = myMatcher.groupCount() >= 1 ? myMatcher.group(1).replace(File.separatorChar, '/') : null;
+    doExecute(line, parsed, callback);
+    return true;
+  }
+
+  protected abstract void doExecute(final String line, @Nullable String parsedData, final OutputParser.Callback callback);
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacSettingsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacSettingsBuilder.java
new file mode 100644
index 0000000..7be8e1d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/JavacSettingsBuilder.java
@@ -0,0 +1,92 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.CompilerEncodingService;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.Chunk;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+
+import java.nio.charset.Charset;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class JavacSettingsBuilder {
+  private final JpsJavaCompilerOptions myOptions;
+
+  public JavacSettingsBuilder(JpsJavaCompilerOptions options) {
+    myOptions = options;
+  }
+
+  protected JpsJavaCompilerOptions getOptions() {
+    return myOptions;
+  }
+
+  public Collection<String> getOptions(Chunk<Module> chunk) {
+    List<String> options = new ArrayList<String>();
+    if (getOptions().DEBUGGING_INFO) {
+      options.add("-g");
+    }
+    if (getOptions().DEPRECATION) {
+      options.add("-deprecation");
+    }
+    if (getOptions().GENERATE_NO_WARNINGS) {
+      options.add("-nowarn");
+    }
+    boolean isEncodingSet = false;
+    final StringTokenizer tokenizer = new StringTokenizer(getOptions().ADDITIONAL_OPTIONS_STRING, " \t\r\n");
+    while(tokenizer.hasMoreTokens()) {
+      final String token = tokenizer.nextToken();
+      if(!acceptUserOption(token)) {
+        continue;
+      }
+      options.add(token);
+      if ("-encoding".equals(token)) {
+        isEncodingSet = true;
+      }
+    }
+    if (!isEncodingSet && acceptEncoding()) {
+      final Charset charset = CompilerEncodingService.getPreferredModuleEncoding(chunk);
+      if (charset != null) {
+        options.add("-encoding");
+        options.add(charset.name());
+      }
+    }
+    return options;
+  }
+
+  protected boolean acceptUserOption(String token) {
+    return !("-g".equals(token) || "-deprecation".equals(token) || "-nowarn".equals(token));
+  }
+
+  protected boolean acceptEncoding() {
+    return true;
+  }
+
+  public String getOptionsString(final ModuleChunk chunk) {
+    final StringBuilder options = new StringBuilder();
+    for (String option : getOptions(chunk)) {
+      if (options.length() > 0) {
+        options.append(" ");
+      }
+      options.append(option);
+    }
+   return options.toString();
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/StatisticsActionJavac.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/StatisticsActionJavac.java
new file mode 100644
index 0000000..d969e40
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/javac/StatisticsActionJavac.java
@@ -0,0 +1,39 @@
+/*
+ * 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.compiler.impl.javaCompiler.javac;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.compiler.CompilerBundle;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.regex.Matcher;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Sep 24, 2005
+ */
+public class StatisticsActionJavac extends JavacParserAction {
+  private final String myProgressMessageResourceKey;
+
+  public StatisticsActionJavac(final Matcher matcher, String progressMessageResourceKey) {
+    super(matcher);
+    myProgressMessageResourceKey = progressMessageResourceKey;
+  }
+
+  protected void doExecute(final String line, @Nullable String parsedData, final OutputParser.Callback callback) {
+    callback.setProgressText(CompilerBundle.message(myProgressMessageResourceKey));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesCompiler.java
new file mode 100644
index 0000000..fb4eed3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesCompiler.java
@@ -0,0 +1,237 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.compiler.impl.javaCompiler.ExternalCompiler;
+import com.intellij.compiler.impl.javaCompiler.ModuleChunk;
+import com.intellij.compiler.options.JavaCompilersTab;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ShowSettingsUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileWriter;
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class JikesCompiler extends ExternalCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.JikesHandler");
+  private final Project myProject;
+  private File myTempFile;
+
+  public JikesCompiler(Project project) {
+    myProject = project;
+  }
+
+  public boolean checkCompiler(final CompileScope scope) {
+    String compilerPath = getCompilerPath();
+    if (StringUtil.isEmpty(compilerPath)) {
+      Messages.showMessageDialog(
+        myProject,
+        CompilerBundle.message("jikes.error.path.to.compiler.unspecified"), CompilerBundle.message("compiler.jikes.name"),
+        Messages.getErrorIcon()
+      );
+      openConfigurationDialog();
+      compilerPath = getCompilerPath(); // update path
+      if (StringUtil.isEmpty(compilerPath)) {
+        return false;
+      }
+    }
+
+    File file = new File(compilerPath);
+    if (!file.exists()) {
+      Messages.showMessageDialog(
+        myProject,
+        CompilerBundle.message("jikes.error.path.to.compiler.missing", compilerPath),
+        CompilerBundle.message("compiler.jikes.name"),
+        Messages.getErrorIcon()
+      );
+      openConfigurationDialog();
+      compilerPath = getCompilerPath(); // update path
+      if (StringUtil.isEmpty(compilerPath)) {
+        return false;
+      }
+      if (!new File(compilerPath).exists()) {
+        return false;
+      }
+    }
+
+    return true;
+  }
+
+  private void openConfigurationDialog() {
+    final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    final Collection<BackendCompiler> compilers = configuration.getRegisteredJavaCompilers();
+    final BackendCompiler defaultCompiler = configuration.getDefaultCompiler();
+    final JavaCompilersTab compilersTab = new JavaCompilersTab(myProject, compilers, defaultCompiler);
+
+    ShowSettingsUtil.getInstance().editConfigurable(myProject, compilersTab);
+  }
+
+  private String getCompilerPath() {
+    return JikesConfiguration.getOptions(myProject).JIKES_PATH.replace('/', File.separatorChar);
+  }
+
+  @NotNull
+  @NonNls
+  public String getId() // used for externalization
+  {
+    return "Jikes";
+  }
+
+  @NotNull
+  public String getPresentableName() {
+    return CompilerBundle.message("compiler.jikes.name");
+  }
+
+  @NotNull
+  public Configurable createConfigurable() {
+    return new JikesConfigurable(JikesConfiguration.getOptions(myProject));
+  }
+
+  public OutputParser createErrorParser(@NotNull final String outputDir, Process process) {
+    return new JikesOutputParser(myProject);
+  }
+
+  @Nullable
+  public OutputParser createOutputParser(@NotNull final String outputDir) {
+    return null;
+  }
+
+  @NotNull
+  public String[] createStartupCommand(final ModuleChunk chunk, final CompileContext context, final String outputPath)
+    throws IOException {
+
+    final ArrayList<String> commandLine = new ArrayList<String>();
+    final IOException[] ex = {null};
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          _createStartupCommand(chunk, commandLine, outputPath);
+        }
+        catch (IOException e) {
+          ex[0] = e;
+        }
+      }
+    });
+    if (ex[0] != null) {
+      throw ex[0];
+    }
+    return ArrayUtil.toStringArray(commandLine);
+  }
+
+  private void _createStartupCommand(final ModuleChunk chunk, final ArrayList<String> commandLine, @NotNull final String outputPath) throws IOException {
+
+    myTempFile = FileUtil.createTempFile("jikes", ".tmp");
+    myTempFile.deleteOnExit();
+
+    final List<VirtualFile> files = chunk.getFilesToCompile();
+    PrintWriter writer = new PrintWriter(new FileWriter(myTempFile));
+    try {
+      for (VirtualFile file : files) {
+        writer.println(file.getPath());
+      }
+    }
+    finally {
+      writer.close();
+    }
+
+    String compilerPath = getCompilerPath();
+    LOG.assertTrue(compilerPath != null, "No path to compiler configured");
+
+    commandLine.add(compilerPath);
+
+    //noinspection HardCodedStringLiteral
+    commandLine.add("-verbose");
+    //noinspection HardCodedStringLiteral
+    commandLine.add("-classpath");
+
+    // must include output path to classpath, otherwise javac will compile all dependent files no matter were they compiled before or not
+    commandLine.add(chunk.getCompilationBootClasspath() + File.pathSeparator + chunk.getCompilationClasspath());
+
+    setupSourceVersion(chunk, commandLine);
+    //noinspection HardCodedStringLiteral
+    commandLine.add("-sourcepath");
+    String sourcePath = chunk.getSourcePath();
+    if (sourcePath.length() > 0) {
+      commandLine.add(sourcePath);
+    }
+    else {
+      commandLine.add("\"\"");
+    }
+
+    //noinspection HardCodedStringLiteral
+    commandLine.add("-d");
+    commandLine.add(outputPath.replace('/', File.separatorChar));
+
+    JikesSettingsBuilder jikesSettings = new JikesSettingsBuilder(JikesConfiguration.getOptions(myProject));
+    StringTokenizer tokenizer = new StringTokenizer(jikesSettings.getOptionsString(chunk), " ");
+    while (tokenizer.hasMoreTokens()) {
+      commandLine.add(tokenizer.nextToken());
+    }
+    commandLine.add("@" + myTempFile.getAbsolutePath());
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  private static void setupSourceVersion(final ModuleChunk chunk, final ArrayList<String> commandLine) {
+    final Sdk jdk = chunk.getJdk();
+    final String versionString = jdk.getVersionString();
+
+    final LanguageLevel applicableLanguageLevel = CompilerUtil.getApplicableLanguageLevel(versionString, chunk.getLanguageLevel());
+    if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_5)) {
+      commandLine.add("-source");
+      commandLine.add("1.4"); // -source 1.5 not supported yet by jikes, so use the highest possible version
+    }
+    else if (applicableLanguageLevel.equals(LanguageLevel.JDK_1_4)) {
+      commandLine.add("-source");
+      commandLine.add("1.4");
+    }
+  }
+
+
+  public void compileFinished() {
+    if (myTempFile != null) {
+      FileUtil.delete(myTempFile);
+      myTempFile = null;
+    }
+  }
+
+}
+
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfigurable.java
new file mode 100644
index 0000000..1731625
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfigurable.java
@@ -0,0 +1,102 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.compiler.options.ComparingUtils;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.RawCommandLineEditor;
+import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class JikesConfigurable implements Configurable {
+  private JPanel myPanel;
+  private JCheckBox myCbDebuggingInfo;
+  private JCheckBox myCbDeprecation;
+  private JCheckBox myCbGenerateNoWarnings;
+  private RawCommandLineEditor myAdditionalOptionsField;
+  private TextFieldWithBrowseButton myPathField;
+  private final JikesCompilerOptions myJikesSettings;
+
+  public JikesConfigurable(JikesCompilerOptions jikesSettings) {
+    myJikesSettings = jikesSettings;
+    myPathField.getButton().addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor();
+        VirtualFile file = FileChooser.chooseFile(descriptor, myPathField, null, null);
+        if (file != null) {
+          myPathField.setText(file.getPath().replace('/', File.separatorChar));
+        }
+      }
+    });
+    myAdditionalOptionsField.setDialogCaption(CompilerBundle.message("java.compiler.option.additional.command.line.parameters"));
+  }
+
+  public String getDisplayName() {
+    return null;
+  }
+
+  public String getHelpTopic() {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public boolean isModified() {
+    boolean isModified = false;
+    isModified |= ComparingUtils.isModified(myPathField, myJikesSettings.JIKES_PATH.replace('/', File.separatorChar));
+    isModified |= ComparingUtils.isModified(myCbDeprecation, myJikesSettings.DEPRECATION);
+    isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myJikesSettings.DEBUGGING_INFO);
+    isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myJikesSettings.GENERATE_NO_WARNINGS);
+    isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myJikesSettings.ADDITIONAL_OPTIONS_STRING);
+    return isModified;
+  }
+
+  public void apply() throws ConfigurationException {
+    myJikesSettings.JIKES_PATH = myPathField.getText().trim().replace(File.separatorChar, '/');
+    myJikesSettings.DEPRECATION = myCbDeprecation.isSelected();
+    myJikesSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
+    myJikesSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
+    myJikesSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText();
+  }
+
+  public void reset() {
+    myPathField.setText(myJikesSettings.JIKES_PATH.replace('/', File.separatorChar));
+    myCbDeprecation.setSelected(myJikesSettings.DEPRECATION);
+    myCbDebuggingInfo.setSelected(myJikesSettings.DEBUGGING_INFO);
+    myCbGenerateNoWarnings.setSelected(myJikesSettings.GENERATE_NO_WARNINGS);
+    myAdditionalOptionsField.setText(myJikesSettings.ADDITIONAL_OPTIONS_STRING);
+  }
+
+  public void disposeUIResources() {
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfiguration.java
new file mode 100755
index 0000000..f82e26f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
+
+@State(
+  name = "JikesSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class JikesConfiguration implements PersistentStateComponent<JikesCompilerOptions> {
+  private final JikesCompilerOptions mySettings = new JikesCompilerOptions();
+
+  @NotNull
+  public JikesCompilerOptions getState() {
+    return mySettings;
+  }
+
+  public void loadState(JikesCompilerOptions state) {
+    XmlSerializerUtil.copyBean(state, mySettings);
+  }
+
+  public static JikesCompilerOptions getOptions(Project project) {
+    return ServiceManager.getService(project, JikesConfiguration.class).getState();
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form
new file mode 100644
index 0000000..23055ee
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOptionsPanel.form
@@ -0,0 +1,101 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.impl.javaCompiler.jikes.JikesConfigurable">
+  <grid id="66887" binding="myPanel" layout-manager="GridLayoutManager" row-count="6" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="103" y="66" width="439" height="254"/>
+    </constraints>
+    <properties/>
+    <clientProperties>
+      <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+    </clientProperties>
+    <border type="etched" title-resource-bundle="messages/CompilerBundle" title-key="jikes.options.group.title"/>
+    <children>
+      <component id="3d38f" class="javax.swing.JCheckBox" binding="myCbDebuggingInfo">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <margin top="5" left="2" bottom="2" right="2"/>
+          <selected value="true"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.debugging.info"/>
+        </properties>
+      </component>
+      <component id="90803" class="javax.swing.JCheckBox" binding="myCbGenerateNoWarnings">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <margin top="2" left="2" bottom="2" right="3"/>
+          <selected value="true"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
+        </properties>
+      </component>
+      <component id="8538e" class="javax.swing.JCheckBox" binding="myCbDeprecation">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <margin top="2" left="2" bottom="5" right="2"/>
+          <selected value="true"/>
+          <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.report.deprecated"/>
+        </properties>
+      </component>
+      <vspacer id="b6f66">
+        <constraints>
+          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <grid id="31c1" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="415eb" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myPathField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+          </component>
+          <component id="327dc" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="jikes.option.path.to.executable"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <grid id="918d2" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f8a80" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.additional.command.line.parameters"/>
+            </properties>
+          </component>
+          <component id="479c2" class="com.intellij.ui.RawCommandLineEditor" binding="myAdditionalOptionsField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOutputParser.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOutputParser.java
new file mode 100644
index 0000000..1d5bb00
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesOutputParser.java
@@ -0,0 +1,133 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+
+public class JikesOutputParser extends OutputParser {
+  private final JikesCompilerOptions myJikesSettings;
+  @NonNls private static final String JAVA_FILE_MSG_TAIL = ".java:";
+  @NonNls private static final String CAUTION = "Caution";
+  @NonNls private static final String WARNING = "Warning";
+  @NonNls private static final String ERROR = "Error";
+  @NonNls private static final String SEMANTIC_WARNING = "Semantic Warning";
+  @NonNls private static final String SEMANTIC_ERROR = "Semantic Error";
+  @NonNls private static final String ENTER_TO_CONTINUE_REGEXP = ".*Enter\\s+to\\s+continue.*";
+
+  public JikesOutputParser(Project project) {
+    myJikesSettings = JikesConfiguration.getOptions(project);
+    myParserActions.add(new ParserActionJikes());
+  }
+
+  public boolean processMessageLine(Callback callback) {
+    if (super.processMessageLine(callback)) {
+      return true;
+    }
+    String line = callback.getCurrentLine();
+    if (line == null) {
+      return false;
+    }
+    if (line.length() == 0) {
+      return false;
+    }
+//sae
+    if (myJikesSettings.IS_EMACS_ERRORS_MODE) {
+
+      String filePath = "";
+      final int tailIndex = line.indexOf(JAVA_FILE_MSG_TAIL);
+      if (tailIndex > 5) filePath = line.substring(0, tailIndex + 5);
+      filePath = filePath.replace(File.separatorChar, '/');
+      final String url = VirtualFileManager.constructUrl(LocalFileSystem.PROTOCOL, filePath);
+      if (tailIndex > 6) {
+        line = line.substring(tailIndex + 6);
+        int lineNum;
+
+//second token = start line
+        StringTokenizer tokenizer = new StringTokenizer(line, ":");
+//first token = filename
+        String token = tokenizer.nextToken();
+
+        try {
+          lineNum = Integer.parseInt(token);
+        }
+        catch (Exception e) {
+          addMessage(callback, CompilerMessageCategory.INFORMATION, line);
+          return true;
+        }
+//thrd token = start column
+        token = tokenizer.nextToken();
+        int colNum;
+        try {
+          colNum = Integer.parseInt(token);
+        }
+        catch (Exception e) {
+          addMessage(callback, CompilerMessageCategory.INFORMATION, line);
+          return true;
+        }
+//4,5 token = end line/column   tmp not used
+        tokenizer.nextToken();
+        tokenizer.nextToken();
+// 6 error type
+        CompilerMessageCategory category = CompilerMessageCategory.INFORMATION;
+        token = tokenizer.nextToken().trim();
+        if (CAUTION.equalsIgnoreCase(token)) {
+          category = CompilerMessageCategory.WARNING;
+        }
+        else if (WARNING.equalsIgnoreCase(token) || SEMANTIC_WARNING.equalsIgnoreCase(token)) { // Semantic errors/warnings were introduced in jikes 1.18
+          category = CompilerMessageCategory.WARNING;
+        }
+        else if (ERROR.equalsIgnoreCase(token) || SEMANTIC_ERROR.equalsIgnoreCase(token)) {
+          category = CompilerMessageCategory.ERROR;
+        }
+
+        String message = token;
+        message = message.concat("  ");
+        message = message.concat(tokenizer.nextToken(""));
+        ArrayList<String> messages = new ArrayList<String>();
+        messages.add(message);
+
+        if (colNum > 0 && messages.size() > 0) {
+          StringBuilder buf = new StringBuilder();
+          for (String m : messages) {
+            if (buf.length() > 0) {
+              buf.append("\n");
+            }
+            buf.append(m);
+          }
+          addMessage(callback, category, buf.toString(), url, lineNum, colNum);
+          return true;
+        }
+      }
+    }
+//--sae
+
+//Enter to continue
+    if (!line.matches(ENTER_TO_CONTINUE_REGEXP)) {
+      addMessage(callback, CompilerMessageCategory.INFORMATION, line);
+    }
+    return true;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesSettingsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesSettingsBuilder.java
new file mode 100644
index 0000000..636db21
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/JikesSettingsBuilder.java
@@ -0,0 +1,50 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.compiler.impl.javaCompiler.javac.JavacSettingsBuilder;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.Chunk;
+import org.jetbrains.jps.model.java.compiler.JikesCompilerOptions;
+
+import java.util.Collection;
+
+public class JikesSettingsBuilder extends JavacSettingsBuilder {
+
+  public JikesSettingsBuilder(JikesCompilerOptions options) {
+    super(options);
+  }
+
+  @Override
+  public JikesCompilerOptions getOptions() {
+    return (JikesCompilerOptions)super.getOptions();
+  }
+
+  public Collection<String> getOptions(Chunk<Module> chunk) {
+    final Collection<String> options = super.getOptions(chunk);
+    if(getOptions().IS_EMACS_ERRORS_MODE) {
+      options.add("+E");
+    }
+    return options;
+  }
+
+  protected boolean acceptUserOption(String token) {
+    if (!super.acceptUserOption(token)) {
+      return false;
+    }
+    return !("++".equals(token) || "+M".equals(token) || "+F".equals(token) || "+E".equals(token));
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/ParserActionJikes.java b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/ParserActionJikes.java
new file mode 100644
index 0000000..ba1884f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/javaCompiler/jikes/ParserActionJikes.java
@@ -0,0 +1,88 @@
+/*
+ * 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.compiler.impl.javaCompiler.jikes;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.compiler.ParserAction;
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * This class provides compatibility with older javac(english locale) and jikes versions and
+ * implements parsing method from previous IDEA versions for jikes and javac compiler output.
+ * Used in order not to miss some compiler output messages when jikes is configured as a preferred compiler
+ * Also used in test mode in which javac is not run via JavacRunner
+ *
+ * @author Eugene Zhuravlev
+ *         Date: Sep 24, 2005
+ */
+public class ParserActionJikes extends ParserAction {
+  @NonNls private static final String JAVA_EXTENSION = ".java";
+
+  public boolean execute(@NonNls String line, final OutputParser.Callback callback) {
+    if (!StringUtil.startsWithChar(line, '[') || !StringUtil.endsWithChar(line, ']')) {
+      return false;
+    }
+    if (line.startsWith("[parsing started")){ // javac
+      String filePath = line.substring("[parsing started".length(), line.length() - 1).trim();
+      processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
+    }
+    else if (line.startsWith("[parsed") && line.contains(JAVA_EXTENSION)) { // javac version 1.2.2
+      int index = line.indexOf(JAVA_EXTENSION);
+      String filePath = line.substring("[parsed".length(), index + JAVA_EXTENSION.length()).trim();
+      processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
+    }
+    else if (line.startsWith("[read") && line.endsWith(".java]")){ // jikes
+      String filePath = line.substring("[read".length(), line.length() - 1).trim();
+      processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
+    }
+    else if (line.startsWith("[parsing completed")){
+    }
+    else if (line.startsWith("[loading") || line.startsWith("[loaded") || line.startsWith("[read")){
+      callback.setProgressText(CompilerBundle.message("progress.loading.classes"));
+    }
+    else if (line.startsWith("[checking")){
+      String className = line.substring("[checking".length(), line.length() - 1).trim();
+      callback.setProgressText(CompilerBundle.message("progress.compiling.class", className));
+    }
+    else if (line.startsWith("[wrote") || line.startsWith("[write")){
+      String filePath = line.substring("[wrote".length(), line.length() - 1).trim();
+      processParsingMessage(callback, filePath.replace(File.separatorChar, '/'));
+    }
+    return true;
+  }
+
+  private static void processParsingMessage(final OutputParser.Callback callback, @NonNls final String filePath) {
+    int index = filePath.lastIndexOf('/');
+    final String name = index >= 0 ? filePath.substring(index + 1) : filePath;
+
+    final FileType fileType = FileTypeManager.getInstance().getFileTypeByFileName(name);
+    if (StdFileTypes.JAVA.equals(fileType)) {
+      callback.fileProcessed(filePath);
+      callback.setProgressText(CompilerBundle.message("progress.parsing.file", name));
+    }
+    else if (StdFileTypes.CLASS.equals(fileType)) {
+      callback.fileGenerated(new FileObject(new File(filePath)));
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildInstructionBase.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildInstructionBase.java
new file mode 100644
index 0000000..446dd2e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildInstructionBase.java
@@ -0,0 +1,72 @@
+/*
+ * 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 cdr
+ */
+package com.intellij.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.compiler.make.BuildInstruction;
+import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.util.io.FileUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Collection;
+
+public abstract class BuildInstructionBase extends UserDataHolderBase implements BuildInstruction, Cloneable {
+  private final String myOutputRelativePath;
+  private Collection<File> myFilesToDelete;
+
+  protected BuildInstructionBase(String outputRelativePath) {
+    myOutputRelativePath = outputRelativePath;
+  }
+
+  public String getOutputRelativePath() {
+    return myOutputRelativePath;
+  }
+
+  public BuildInstructionBase clone() {
+    return (BuildInstructionBase)super.clone();
+  }
+
+  public void addFileToDelete(File file) {
+    if (myFilesToDelete == null) {
+      myFilesToDelete = new THashSet<File>();
+    }
+    myFilesToDelete.add(file);
+  }
+
+  public void collectFilesToDelete(Collection<File> filesToDelete) {
+    if (myFilesToDelete != null) {
+      filesToDelete.addAll(myFilesToDelete);
+    }
+    myFilesToDelete = null;
+  }
+
+  @NonNls
+  public String toString() {
+    return super.toString();
+  }
+
+  protected File createTempFile(final String prefix, final String suffix) throws IOException {
+    final File tempFile = FileUtil.createTempFile(prefix + "___", suffix);
+    addFileToDelete(tempFile);
+    return tempFile;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildRecipeImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildRecipeImpl.java
new file mode 100644
index 0000000..03e62a0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/BuildRecipeImpl.java
@@ -0,0 +1,80 @@
+/*
+ * 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 cdr
+ */
+package com.intellij.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.compiler.make.BuildInstruction;
+import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.List;
+
+@Deprecated
+public class BuildRecipeImpl implements BuildRecipe {
+  private final List<BuildInstruction> myInstructions = new ArrayList<BuildInstruction>();
+
+  public void addInstruction(BuildInstruction instruction) {
+    if (!contains(instruction)) {
+      myInstructions.add(instruction);
+    }
+  }
+
+  public boolean contains(final BuildInstruction instruction) {
+    return myInstructions.contains(instruction);
+  }
+
+  public boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder){
+    try {
+      return visitInstructionsWithExceptions(visitor, reverseOrder);
+    }
+    catch (Exception e) {
+      if (e instanceof RuntimeException) {
+        throw (RuntimeException)e;
+      }
+      return false;
+    }
+  }
+  public boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception {
+    for (int i = reverseOrder ? myInstructions.size()-1 : 0;
+         reverseOrder ? i>=0 : i < myInstructions.size();
+         i += reverseOrder ? -1 : 1) {
+      BuildInstruction instruction = myInstructions.get(i);
+      if (!instruction.accept(visitor)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath) {
+    addInstruction(new FileCopyInstructionImpl(file, isDirectory, DeploymentUtil.trimForwardSlashes(outputRelativePath)));
+  }
+
+  public String toString() {
+    String s = "Build recipe:";
+    for (BuildInstruction buildInstruction : myInstructions) {
+      s += "\n" + buildInstruction + "; ";
+    }
+    return s;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DependentJarsEvaluator.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DependentJarsEvaluator.java
new file mode 100644
index 0000000..9fa4e2c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DependentJarsEvaluator.java
@@ -0,0 +1,44 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.util.Pair;
+
+import java.util.LinkedHashSet;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class DependentJarsEvaluator {
+  private final Set<JarInfo> myJars = new LinkedHashSet<JarInfo>();
+
+  public void addJarWithDependencies(final JarInfo jarInfo) {
+    if (myJars.add(jarInfo)) {
+      for (JarDestinationInfo destination : jarInfo.getJarDestinations()) {
+        addJarWithDependencies(destination.getJarInfo());
+      }
+      for (Pair<String, JarInfo> pair : jarInfo.getPackedJars()) {
+        addJarWithDependencies(pair.getSecond());
+      }
+    }
+  }
+
+  public Set<JarInfo> getJars() {
+    return myJars;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DestinationInfo.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DestinationInfo.java
new file mode 100644
index 0000000..abda982
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/DestinationInfo.java
@@ -0,0 +1,60 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class DestinationInfo {
+  private VirtualFile myOutputFile;
+  private final String myOutputPath;
+  private final String myOutputFilePath;
+
+  protected DestinationInfo(@NotNull final String outputPath, @Nullable final VirtualFile outputFile, @NotNull String outputFilePath) {
+    myOutputFilePath = outputFilePath;
+    myOutputFile = outputFile;
+    myOutputPath = outputPath;
+  }
+
+  @NotNull
+  public String getOutputPath() {
+    return myOutputPath;
+  }
+
+  @Nullable
+  public VirtualFile getOutputFile() {
+    return myOutputFile;
+  }
+
+  @NotNull
+  public String getOutputFilePath() {
+    return myOutputFilePath;
+  }
+
+  public void update() {
+    if (myOutputFile != null && !myOutputFile.isValid()) {
+      myOutputFile = null;
+    }
+    if (myOutputFile == null) {
+      myOutputFile = LocalFileSystem.getInstance().findFileByPath(myOutputFilePath);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/ExplodedDestinationInfo.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/ExplodedDestinationInfo.java
new file mode 100644
index 0000000..33a3a8e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/ExplodedDestinationInfo.java
@@ -0,0 +1,33 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class ExplodedDestinationInfo extends DestinationInfo {
+  public ExplodedDestinationInfo(final String outputPath, @Nullable final VirtualFile outputFile) {
+    super(outputPath, outputFile, outputPath);
+  }
+
+  public String toString() {
+    return getOutputPath();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/FileCopyInstructionImpl.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/FileCopyInstructionImpl.java
new file mode 100644
index 0000000..64b5855
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/FileCopyInstructionImpl.java
@@ -0,0 +1,76 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.compiler.make.BuildInstructionVisitor;
+import com.intellij.openapi.compiler.make.FileCopyInstruction;
+import com.intellij.openapi.util.io.FileUtil;
+
+import java.io.File;
+
+public class FileCopyInstructionImpl extends BuildInstructionBase implements FileCopyInstruction {
+  private File myFile;
+  private boolean myIsDirectory;
+
+  public FileCopyInstructionImpl(File source, boolean isDirectory, String outputRelativePath) {
+    super(outputRelativePath);
+    setFile(source, isDirectory);
+  }
+
+  public boolean accept(BuildInstructionVisitor visitor) throws Exception {
+    return visitor.visitFileCopyInstruction(this);
+  }
+
+  public String toString() {
+    return "Copy " + getFile() + "->" + getOutputRelativePath();
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof FileCopyInstruction)) return false;
+
+    final FileCopyInstruction item = (FileCopyInstruction) o;
+
+    if (getFile() != null ? !FileUtil.filesEqual(getFile(), item.getFile()) : item.getFile() != null) return false;
+
+    if (getOutputRelativePath() != null) {
+      if (!getOutputRelativePath().equals( item.getOutputRelativePath() )) return false;
+    } else if ( item.getOutputRelativePath() != null ) {
+      return false;
+    }
+
+    return true;
+  }
+
+  public int hashCode() {
+    return (getFile() != null ? getFile().hashCode() : 0) +
+           (getOutputRelativePath() != null ? getOutputRelativePath().hashCode():0);
+  }
+
+  public File getFile() {
+    return myFile;
+  }
+
+  public boolean isDirectory() {
+    return myIsDirectory;
+  }
+
+  private void setFile(File file, boolean isDirectory) {
+    myFile = file;
+    myIsDirectory = isDirectory;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/IgnoredFileFilter.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/IgnoredFileFilter.java
new file mode 100644
index 0000000..5ad3f5a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/IgnoredFileFilter.java
@@ -0,0 +1,38 @@
+/*
+ * 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 cdr
+ */
+package com.intellij.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+
+import java.io.File;
+import java.io.FileFilter;
+
+public class IgnoredFileFilter implements FileFilter {
+    public boolean accept(File file) {
+      final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+      final String name = file.getName();
+      return !fileTypeManager.isFileIgnored(name)
+        && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_PROJECT
+        && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_MODULE
+        && fileTypeManager.getFileTypeByFileName(name) != StdFileTypes.IDEA_WORKSPACE
+        ;
+    }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarDestinationInfo.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarDestinationInfo.java
new file mode 100644
index 0000000..5cc45c1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarDestinationInfo.java
@@ -0,0 +1,55 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+
+/**
+ * @author nik
+ */
+public class JarDestinationInfo extends DestinationInfo {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.packagingCompiler.JarDestinationInfo");
+  private final String myPathInJar;
+  private final JarInfo myJarInfo;
+
+  public JarDestinationInfo(final String pathInJar, final JarInfo jarInfo, DestinationInfo jarDestination) {
+    super(appendPathInJar(jarDestination.getOutputPath(), pathInJar), jarDestination.getOutputFile(), jarDestination.getOutputFilePath());
+    LOG.assertTrue(!pathInJar.startsWith(".."), pathInJar);
+    myPathInJar = StringUtil.startsWithChar(pathInJar, '/') ? pathInJar : "/" + pathInJar;
+    myJarInfo = jarInfo;
+  }
+
+  private static String appendPathInJar(String outputPath, String pathInJar) {
+    LOG.assertTrue(outputPath.length() > 0 && outputPath.charAt(outputPath.length() - 1) != '/');
+    LOG.assertTrue(pathInJar.length() > 0 && pathInJar.charAt(0) != '/');
+    return outputPath + JarFileSystem.JAR_SEPARATOR + pathInJar;
+  }
+
+  public String getPathInJar() {
+    return myPathInJar;
+  }
+
+  public JarInfo getJarInfo() {
+    return myJarInfo;
+  }
+
+  public String toString() {
+    return myPathInJar + "(" + getOutputPath() + ")";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarInfo.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarInfo.java
new file mode 100644
index 0000000..7626ca1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarInfo.java
@@ -0,0 +1,77 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.util.ArrayList;
+import java.util.LinkedHashSet;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class JarInfo {
+  private final List<Pair<String, VirtualFile>> myPackedFiles;
+  private final LinkedHashSet<Pair<String, JarInfo>> myPackedJars;
+  private final List<DestinationInfo> myDestinations;
+
+  public JarInfo() {
+    myDestinations = new ArrayList<DestinationInfo>();
+    myPackedFiles = new ArrayList<Pair<String, VirtualFile>>();
+    myPackedJars = new LinkedHashSet<Pair<String, JarInfo>>();
+  }
+
+  public void addDestination(DestinationInfo info) {
+    myDestinations.add(info);
+    if (info instanceof JarDestinationInfo) {
+      JarDestinationInfo destinationInfo = (JarDestinationInfo)info;
+      destinationInfo.getJarInfo().myPackedJars.add(Pair.create(destinationInfo.getPathInJar(), this));
+    }
+  }
+
+  public void addContent(String pathInJar, VirtualFile sourceFile) {
+    myPackedFiles.add(Pair.create(pathInJar, sourceFile));
+  }
+
+  public List<Pair<String, VirtualFile>> getPackedFiles() {
+    return myPackedFiles;
+  }
+
+  public LinkedHashSet<Pair<String, JarInfo>> getPackedJars() {
+    return myPackedJars;
+  }
+
+  public List<JarDestinationInfo> getJarDestinations() {
+    final ArrayList<JarDestinationInfo> list = new ArrayList<JarDestinationInfo>();
+    for (DestinationInfo destination : myDestinations) {
+      if (destination instanceof JarDestinationInfo) {
+        list.add((JarDestinationInfo)destination);
+      }
+    }
+    return list;
+  }
+
+  public List<DestinationInfo> getAllDestinations() {
+    return myDestinations;
+  }
+
+  public String getPresentableDestination() {
+    return !myDestinations.isEmpty() ? myDestinations.get(0).getOutputPath() : "";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java
new file mode 100644
index 0000000..a546480
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/packagingCompiler/JarsBuilder.java
@@ -0,0 +1,282 @@
+/*
+ * 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.compiler.impl.packagingCompiler;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.impl.compiler.ArtifactCompilerUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.graph.CachingSemiGraph;
+import com.intellij.util.graph.DFSTBuilder;
+import com.intellij.util.graph.GraphGenerator;
+import com.intellij.util.io.ZipUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.JarFile;
+import java.util.jar.JarOutputStream;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipOutputStream;
+
+/**
+ * @author nik
+ */
+public class JarsBuilder {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.packagingCompiler.JarsBuilder");
+  private final Set<JarInfo> myJarsToBuild;
+  private final FileFilter myFileFilter;
+  private final CompileContext myContext;
+  private Map<JarInfo, File> myBuiltJars;
+
+  public JarsBuilder(Set<JarInfo> jarsToBuild, FileFilter fileFilter, CompileContext context) {
+    DependentJarsEvaluator evaluator = new DependentJarsEvaluator();
+    for (JarInfo jarInfo : jarsToBuild) {
+      evaluator.addJarWithDependencies(jarInfo);
+    }
+    myJarsToBuild = evaluator.getJars();
+    myFileFilter = fileFilter;
+    myContext = context;
+  }
+
+  public boolean buildJars(Set<String> writtenPaths) throws IOException {
+    myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.building.archives"));
+
+    final JarInfo[] sortedJars = sortJars();
+    if (sortedJars == null) {
+      return false;
+    }
+
+    myBuiltJars = new HashMap<JarInfo, File>();
+    try {
+      for (JarInfo jar : sortedJars) {
+        myContext.getProgressIndicator().checkCanceled();
+        buildJar(jar);
+      }
+
+      myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.copying.archives"));
+      copyJars(writtenPaths);
+    }
+    finally {
+      deleteTemporaryJars();
+    }
+
+
+    return true;
+  }
+
+  private void deleteTemporaryJars() {
+    for (File file : myBuiltJars.values()) {
+      FileUtil.delete(file);
+    }
+  }
+
+  private void copyJars(final Set<String> writtenPaths) throws IOException {
+    for (Map.Entry<JarInfo, File> entry : myBuiltJars.entrySet()) {
+      File fromFile = entry.getValue();
+      boolean first = true;
+      for (DestinationInfo destination : entry.getKey().getAllDestinations()) {
+        if (destination instanceof ExplodedDestinationInfo) {
+          File toFile = new File(FileUtil.toSystemDependentName(destination.getOutputPath()));
+
+          if (first) {
+            first = false;
+            renameFile(fromFile, toFile, writtenPaths);
+            fromFile = toFile;
+          }
+          else {
+            DeploymentUtil.getInstance().copyFile(fromFile, toFile, myContext, writtenPaths, myFileFilter);
+          }
+
+        }
+      }
+    }
+  }
+
+  private static void renameFile(final File fromFile, final File toFile, final Set<String> writtenPaths) throws IOException {
+    FileUtil.rename(fromFile, toFile);
+    writtenPaths.add(toFile.getPath());
+  }
+
+  @Nullable
+  private JarInfo[] sortJars() {
+    final DFSTBuilder<JarInfo> builder = new DFSTBuilder<JarInfo>(GraphGenerator.create(CachingSemiGraph.create(new JarsGraph())));
+    if (!builder.isAcyclic()) {
+      final Pair<JarInfo, JarInfo> dependency = builder.getCircularDependency();
+      String message = CompilerBundle.message("packaging.compiler.error.cannot.build.circular.dependency.found.between.0.and.1",
+                                              dependency.getFirst().getPresentableDestination(),
+                                              dependency.getSecond().getPresentableDestination());
+      myContext.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
+      return null;
+    }
+
+    JarInfo[] jars = myJarsToBuild.toArray(new JarInfo[myJarsToBuild.size()]);
+    Arrays.sort(jars, builder.comparator());
+    jars = ArrayUtil.reverseArray(jars);
+    return jars;
+  }
+
+  public Set<JarInfo> getJarsToBuild() {
+    return myJarsToBuild;
+  }
+
+  private void buildJar(final JarInfo jar) throws IOException {
+    if (jar.getPackedFiles().isEmpty() && jar.getPackedJars().isEmpty()) {
+      myContext.addMessage(CompilerMessageCategory.WARNING, "Archive '" + jar.getPresentableDestination() + "' has no files so it won't be created", null, -1, -1);
+      return;
+    }
+
+    myContext.getProgressIndicator()
+      .setText(CompilerBundle.message("packaging.compiler.message.building.0", jar.getPresentableDestination()));
+    File jarFile = FileUtil.createTempFile("artifactCompiler", "tmp");
+    myBuiltJars.put(jar, jarFile);
+
+    FileUtil.createParentDirs(jarFile);
+
+    VirtualFile manifestFile = null;
+    for (Pair<String, VirtualFile> pair : jar.getPackedFiles()) {
+      if (pair.getFirst().equals(JarFile.MANIFEST_NAME)) {
+        manifestFile = pair.getSecond();
+      }
+    }
+    final JarOutputStream jarOutputStream = createJarOutputStream(jarFile, manifestFile);
+
+    try {
+      final THashSet<String> writtenPaths = new THashSet<String>();
+      for (Pair<String, VirtualFile> pair : jar.getPackedFiles()) {
+        if (pair.getFirst().equals(JarFile.MANIFEST_NAME)) continue;
+        final VirtualFile sourceFile = pair.getSecond();
+        if (sourceFile.isInLocalFileSystem()) {
+          File file = VfsUtil.virtualToIoFile(sourceFile);
+          addFileToJar(jarOutputStream, file, pair.getFirst(), writtenPaths);
+        }
+        else {
+          extractFileAndAddToJar(jarOutputStream, sourceFile, pair.getFirst(), writtenPaths);
+        }
+      }
+
+      for (Pair<String, JarInfo> nestedJar : jar.getPackedJars()) {
+        File nestedJarFile = myBuiltJars.get(nestedJar.getSecond());
+        if (nestedJarFile != null) {
+          addFileToJar(jarOutputStream, nestedJarFile, nestedJar.getFirst(), writtenPaths);
+        }
+        else {
+          LOG.debug("nested jar file " + nestedJar.getFirst() + " for " + jar.getPresentableDestination() + " not found");
+        }
+      }
+    }
+    finally {
+      jarOutputStream.close();
+    }
+  }
+
+  private static JarOutputStream createJarOutputStream(File jarFile, VirtualFile manifestFile) throws IOException {
+    final BufferedOutputStream outputStream = new BufferedOutputStream(new FileOutputStream(jarFile));
+    final JarOutputStream jarOutputStream;
+    if (manifestFile != null) {
+      final InputStream manifestStream = manifestFile.getInputStream();
+      try {
+        jarOutputStream = new JarOutputStream(outputStream, new Manifest(manifestStream));
+      }
+      finally {
+        manifestStream.close();
+      }
+    }
+    else {
+      jarOutputStream = new JarOutputStream(outputStream);
+    }
+    return jarOutputStream;
+  }
+
+  private void extractFileAndAddToJar(JarOutputStream jarOutputStream, VirtualFile sourceFile, String relativePath, THashSet<String> writtenPaths)
+    throws IOException {
+    relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath);
+    myContext.getProgressIndicator().setText2(relativePath);
+    if (!writtenPaths.add(relativePath)) return;
+
+    final BufferedInputStream input = ArtifactCompilerUtil.getJarEntryInputStream(sourceFile, myContext);
+    if (input == null) return;
+
+    ZipEntry entry = new ZipEntry(relativePath);
+    entry.setTime(ArtifactCompilerUtil.getJarFile(sourceFile).lastModified());
+    jarOutputStream.putNextEntry(entry);
+    FileUtil.copy(input, jarOutputStream);
+    jarOutputStream.closeEntry();
+  }
+
+  private void addFileToJar(final @NotNull JarOutputStream jarOutputStream, final @NotNull File file, @NotNull String relativePath,
+                            final @NotNull THashSet<String> writtenPaths) throws IOException {
+    if (!file.exists()) {
+      return;
+    }
+
+    relativePath = addParentDirectories(jarOutputStream, writtenPaths, relativePath);
+    myContext.getProgressIndicator().setText2(relativePath);
+    ZipUtil.addFileToZip(jarOutputStream, file, relativePath, writtenPaths, myFileFilter);
+  }
+
+  private static String addParentDirectories(JarOutputStream jarOutputStream, THashSet<String> writtenPaths, String relativePath) throws IOException {
+    while (StringUtil.startsWithChar(relativePath, '/')) {
+      relativePath = relativePath.substring(1);
+    }
+    int i = relativePath.indexOf('/');
+    while (i != -1) {
+      String prefix = relativePath.substring(0, i+1);
+      if (!writtenPaths.contains(prefix) && prefix.length() > 1) {
+        addEntry(jarOutputStream, prefix);
+        writtenPaths.add(prefix);
+      }
+      i = relativePath.indexOf('/', i + 1);
+    }
+    return relativePath;
+  }
+
+  private static void addEntry(final ZipOutputStream output, @NonNls final String relativePath) throws IOException {
+    ZipEntry e = new ZipEntry(relativePath);
+    e.setMethod(ZipEntry.STORED);
+    e.setSize(0);
+    e.setCrc(0);
+    output.putNextEntry(e);
+    output.closeEntry();
+  }
+
+  private class JarsGraph implements GraphGenerator.SemiGraph<JarInfo> {
+    public Collection<JarInfo> getNodes() {
+      return myJarsToBuild;
+    }
+
+    public Iterator<JarInfo> getIn(final JarInfo n) {
+      Set<JarInfo> ins = new HashSet<JarInfo>();
+      for (JarDestinationInfo destination : n.getJarDestinations()) {
+        ins.add(destination.getJarInfo());
+      }
+      return ins.iterator();
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java
new file mode 100644
index 0000000..3efbec2
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompiler.java
@@ -0,0 +1,236 @@
+/*
+ * 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: Jan 17, 2003
+ * Time: 3:48:26 PM
+ */
+package com.intellij.compiler.impl.resourceCompiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.make.MakeUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.Chunk;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+public class ResourceCompiler implements TranslatingCompiler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.resourceCompiler.ResourceCompiler");
+  private final Project myProject;
+  private final CompilerConfiguration myConfiguration;
+  private final ResourceCompilerExtension[] myResourceCompilerExtensions = ResourceCompilerExtension.EP_NAME.getExtensions();
+
+  public ResourceCompiler(Project project, CompilerConfiguration compilerConfiguration) {
+    myProject = project;
+    myConfiguration = compilerConfiguration;
+  }
+
+  @NotNull
+  public String getDescription() {
+    return CompilerBundle.message("resource.compiler.description");
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    ((CompilerConfigurationImpl) CompilerConfiguration.getInstance(myProject)).convertPatterns();
+    return true;
+  }
+
+  public boolean isCompilableFile(VirtualFile file, CompileContext context) {
+    final Module module = context.getModuleByFile(file);
+    if (module != null && skipStandardResourceCompiler(module)) {
+      return false;
+    }
+    return myConfiguration.isResourceFile(file);
+  }
+
+  public void compile(final CompileContext context, Chunk<Module> moduleChunk, final VirtualFile[] files, OutputSink sink) {
+    context.getProgressIndicator().pushState();
+    context.getProgressIndicator().setText(CompilerBundle.message("progress.copying.resources"));
+
+    final Map<String, Collection<OutputItem>> processed = new HashMap<String, Collection<OutputItem>>();
+    final LinkedList<CopyCommand> copyCommands = new LinkedList<CopyCommand>();
+    final Module singleChunkModule = moduleChunk.getNodes().size() == 1? moduleChunk.getNodes().iterator().next() : null;
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+        for (final VirtualFile file : files) {
+          if (context.getProgressIndicator().isCanceled()) {
+            break;
+          }
+          final Module module = singleChunkModule != null? singleChunkModule : context.getModuleByFile(file);
+          if (module == null) {
+            continue; // looks like file invalidated
+          }
+          final VirtualFile fileRoot = MakeUtil.getSourceRoot(context, module, file);
+          if (fileRoot == null) {
+            continue;
+          }
+          final String sourcePath = file.getPath();
+          final String relativePath = VfsUtilCore.getRelativePath(file, fileRoot, '/');
+          final boolean inTests = ((CompileContextEx)context).isInTestSourceContent(file);
+          final VirtualFile outputDir = inTests? context.getModuleOutputDirectoryForTests(module) : context.getModuleOutputDirectory(module);
+          if (outputDir == null) {
+            continue;
+          }
+          final String outputPath = outputDir.getPath();
+          
+          final String packagePrefix = fileIndex.getPackageNameByDirectory(fileRoot);
+          final String targetPath;
+          if (packagePrefix != null && packagePrefix.length() > 0) {
+            targetPath = outputPath + "/" + packagePrefix.replace('.', '/') + "/" + relativePath;
+          }
+          else {
+            targetPath = outputPath + "/" + relativePath;
+          }
+          if (sourcePath.equals(targetPath)) {
+            addToMap(processed, outputPath, new MyOutputItem(targetPath, file));
+          }
+          else {
+            copyCommands.add(new CopyCommand(outputPath, sourcePath, targetPath, file));
+          }
+        }
+      }
+    });
+
+    final List<File> filesToRefresh = new ArrayList<File>();
+    // do actual copy outside of read action to reduce the time the application is locked on it
+    while (!copyCommands.isEmpty()) {
+      final CopyCommand command = copyCommands.removeFirst();
+      if (context.getProgressIndicator().isCanceled()) {
+        break;
+      }
+      //context.getProgressIndicator().setFraction((idx++) * 1.0 / total);
+      context.getProgressIndicator().setText2("Copying " + command.getFromPath() + "...");
+      try {
+        final MyOutputItem outputItem = command.copy(filesToRefresh);
+        addToMap(processed, command.getOutputPath(), outputItem);
+      }
+      catch (IOException e) {
+        context.addMessage(
+          CompilerMessageCategory.ERROR,
+          CompilerBundle.message("error.copying", command.getFromPath(), command.getToPath(), e.getMessage()),
+          command.getSourceFileUrl(), -1, -1
+        );
+      }
+    }
+
+    if (!filesToRefresh.isEmpty()) {
+      CompilerUtil.refreshIOFiles(filesToRefresh);
+      filesToRefresh.clear();
+    }
+
+    for (Iterator<Map.Entry<String, Collection<OutputItem>>> it = processed.entrySet().iterator(); it.hasNext();) {
+      Map.Entry<String, Collection<OutputItem>> entry = it.next();
+      sink.add(entry.getKey(), entry.getValue(), VirtualFile.EMPTY_ARRAY);
+      it.remove(); // to free memory
+    }
+    context.getProgressIndicator().popState();
+  }
+
+  private boolean skipStandardResourceCompiler(final Module module) {
+    for (ResourceCompilerExtension extension : myResourceCompilerExtensions) {
+      if (extension.skipStandardResourceCompiler(module)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private static void addToMap(Map<String, Collection<OutputItem>> map, String outputDir, OutputItem item) {
+    Collection<OutputItem> list = map.get(outputDir);
+    if (list == null) {
+      list = new ArrayList<OutputItem>();
+      map.put(outputDir, list);
+    }
+    list.add(item);
+  }
+
+  private static class CopyCommand {
+    private final String myOutputPath;
+    private final String myFromPath;
+    private final String myToPath;
+    private final VirtualFile mySourceFile;
+
+    private CopyCommand(String outputPath, String fromPath, String toPath, VirtualFile sourceFile) {
+      myOutputPath = outputPath;
+      myFromPath = fromPath;
+      myToPath = toPath;
+      mySourceFile = sourceFile;
+    }
+
+    public MyOutputItem copy(List<File> filesToRefresh) throws IOException {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Copying " + myFromPath + " to " + myToPath);
+      }
+      final File targetFile = new File(myToPath);
+      FileUtil.copyContent(new File(myFromPath), targetFile);
+      filesToRefresh.add(targetFile);
+      return new MyOutputItem(myToPath, mySourceFile);
+    }
+
+    public String getOutputPath() {
+      return myOutputPath;
+    }
+
+    public String getFromPath() {
+      return myFromPath;
+    }
+
+    public String getToPath() {
+      return myToPath;
+    }
+
+    public String getSourceFileUrl() {
+      // do not use mySourseFile.getUrl() directly as it requires read action
+      return VirtualFileManager.constructUrl(mySourceFile.getFileSystem().getProtocol(), myFromPath);
+    }
+  }
+
+  private static class MyOutputItem implements OutputItem {
+    private final String myTargetPath;
+    private final VirtualFile myFile;
+
+    private MyOutputItem(String targetPath, VirtualFile sourceFile) {
+      myTargetPath = targetPath;
+      myFile = sourceFile;
+    }
+
+    public String getOutputPath() {
+      return myTargetPath;
+    }
+
+    public VirtualFile getSourceFile() {
+      return myFile;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompilerExtension.java b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompilerExtension.java
new file mode 100644
index 0000000..47d901c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/resourceCompiler/ResourceCompilerExtension.java
@@ -0,0 +1,14 @@
+package com.intellij.compiler.impl.resourceCompiler;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class ResourceCompilerExtension {
+  public static final ExtensionPointName<ResourceCompilerExtension> EP_NAME =
+    ExtensionPointName.create("com.intellij.compiler.resourceCompilerExtension");
+
+  public boolean skipStandardResourceCompiler(final @NotNull Module module) {
+    return false;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/JavacOutputParserPool.java b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/JavacOutputParserPool.java
new file mode 100644
index 0000000..cc99f2d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/JavacOutputParserPool.java
@@ -0,0 +1,117 @@
+/*
+ * 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.compiler.impl.rmiCompiler;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.javaCompiler.CompilerParsingThread;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacOutputParser;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.ex.JavaSdkUtil;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.rt.compiler.JavacResourcesReader;
+import com.intellij.util.ArrayUtil;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 10, 2005
+ */
+public class JavacOutputParserPool {
+  protected final Project myProject;
+  private final CompileContext myContext;
+  private final Map<Sdk, OutputParser> myProjectToParserMap = new HashMap<Sdk, OutputParser>();
+
+  protected JavacOutputParserPool(Project project, final CompileContext context) {
+    myProject = project;
+    myContext = context;
+  }
+
+  public OutputParser getJavacOutputParser(Sdk jdk) throws IOException {
+    OutputParser outputParser = myProjectToParserMap.get(jdk);
+    if (outputParser == null) {
+      outputParser = createJavacOutputParser(jdk);
+      myProjectToParserMap.put(jdk, outputParser);
+    }
+    return outputParser;
+  }
+
+  private OutputParser createJavacOutputParser(final Sdk jdk) throws IOException {
+    final JavacOutputParser outputParser = new JavacOutputParser(myProject);
+    // first, need to setup the output parser
+    final String[] setupCmdLine = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
+      public String[] compute() {
+        return createParserSetupCommand(jdk);
+      }
+    });
+    final Process setupProcess = Runtime.getRuntime().exec(setupCmdLine);
+
+    final CompilerParsingThread setupProcessParsingThread = new CompilerParsingThread(setupProcess, outputParser, true, true,myContext);
+    final Future<?> parsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(setupProcessParsingThread);
+    try {
+      setupProcess.waitFor();
+    }
+    catch (InterruptedException ignored) {
+    }
+    finally {
+      setupProcessParsingThread.setProcessTerminated(true);
+    }
+    try {
+      parsingThreadFuture.get();
+    }
+    catch (InterruptedException e) {
+    }
+    catch (ExecutionException e) {
+    }
+    return outputParser;
+  }
+
+  private static String[] createParserSetupCommand(final Sdk jdk) {
+
+    final VirtualFile homeDirectory = jdk.getHomeDirectory();
+    if (homeDirectory == null) {
+      throw new IllegalArgumentException(CompilerBundle.jdkHomeNotFoundMessage(jdk));
+    }
+
+    final List<String> commandLine = new ArrayList<String>();
+    commandLine.add(((JavaSdkType)jdk.getSdkType()).getVMExecutablePath(jdk));
+
+    CompilerUtil.addLocaleOptions(commandLine, false);
+
+    //noinspection HardCodedStringLiteral
+    commandLine.add("-classpath");
+    commandLine.add(((JavaSdkType)jdk.getSdkType()).getToolsPath(jdk) + File.pathSeparator + JavaSdkUtil.getIdeaRtJarPath());
+
+    commandLine.add(JavacResourcesReader.class.getName());
+
+    return ArrayUtil.toStringArray(commandLine);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java
new file mode 100644
index 0000000..ae0f0b7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicCompiler.java
@@ -0,0 +1,522 @@
+/*
+ * 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.compiler.impl.rmiCompiler;
+
+import com.intellij.compiler.OutputParser;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.javaCompiler.CompilerParsingThread;
+import com.intellij.compiler.impl.javaCompiler.FileObject;
+import com.intellij.compiler.make.Cache;
+import com.intellij.compiler.make.CacheCorruptedException;
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.compiler.make.MakeUtil;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Chunk;
+import com.intellij.util.PathsList;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.concurrent.ExecutionException;
+import java.util.concurrent.Future;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 29, 2004
+ */
+
+public class RmicCompiler implements ClassPostProcessingCompiler{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.impl.rmiCompiler.RmicCompiler");
+  //private static final FileFilter CLASSES_AND_DIRECTORIES_FILTER = new FileFilter() {
+  //  public boolean accept(File pathname) {
+  //    return pathname.isDirectory() || pathname.getName().endsWith(".class");
+  //  }
+  //};
+  //private static final String REMOTE_INTERFACE_NAME = Remote.class.getName();
+
+  @NotNull
+  public ProcessingItem[] getProcessingItems(final CompileContext context) {
+    if (!RmicConfiguration.getOptions(context.getProject()).IS_EANABLED) {
+      return ProcessingItem.EMPTY_ARRAY;
+    }
+    final Project project = context.getProject();
+    final List<ProcessingItem> items = new ArrayList<ProcessingItem>();
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        DependencyCache dependencyCache = ((CompileContextEx)context).getDependencyCache();
+        try {
+          final Cache cache = dependencyCache.getCache();
+          final int[] allClassNames = cache.getAllClassNames();
+          final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+          final LocalFileSystem lfs = LocalFileSystem.getInstance();
+          for (final int className : allClassNames) {
+            final boolean isRemoteObject = cache.isRemote(className) && !MakeUtil.isInterface(cache.getFlags(className));
+            if (!isRemoteObject && !dependencyCache.wasRemote(className)) {
+              continue;
+            }
+            final String outputPath = cache.getPath(className);
+            if (outputPath == null) {
+              continue;
+            }
+            final VirtualFile outputClassFile = lfs.findFileByPath(outputPath.replace(File.separatorChar, '/'));
+            if (outputClassFile == null) {
+              continue;
+            }
+            final VirtualFile sourceFile = ((CompileContextEx)context).getSourceFileByOutputFile(outputClassFile);
+            if (sourceFile == null) {
+              continue;
+            }
+            final Module module = context.getModuleByFile(sourceFile);
+            if (module == null) {
+              continue;
+            }
+            final VirtualFile outputDir = fileIndex.isInTestSourceContent(sourceFile)
+                                          ? context.getModuleOutputDirectoryForTests(module)
+                                          : context.getModuleOutputDirectory(module);
+            if (outputDir == null) {
+              continue;
+            }
+
+            if (!VfsUtil.isAncestor(outputDir, outputClassFile, true)) {
+              LOG.error(outputClassFile.getPath() + " should be located under the output root " + outputDir.getPath());
+            }
+
+            final ProcessingItem item = createProcessingItem(module, outputClassFile, outputDir,
+                                                             isRemoteObject, dependencyCache.resolve(className));
+            items.add(item);
+          }
+        }
+        catch (CacheCorruptedException e) {
+          context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+          LOG.info(e);
+        }
+      }
+    });
+
+    return items.toArray(new ProcessingItem[items.size()]);
+  }
+
+  public static ProcessingItem createProcessingItem(final Module module,
+                                             final VirtualFile outputClassFile,
+                                             final VirtualFile outputDir,
+                                             final boolean remoteObject, String qName) {
+    final RmicProcessingItem item = new RmicProcessingItem(
+      module, outputClassFile, new File(outputDir.getPath()), qName
+    );
+    item.setIsRemoteObject(remoteObject);
+    return item;
+  }
+
+  public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) {
+    final Project project = context.getProject();
+    if (!RmicConfiguration.getOptions(project).IS_EANABLED) {
+      return ProcessingItem.EMPTY_ARRAY;
+    }
+    final ProgressIndicator progressIndicator = context.getProgressIndicator();
+    progressIndicator.pushState();
+    try {
+      progressIndicator.setText(CompilerBundle.message("progress.generating.rmi.stubs"));
+      final Map<Pair<Module, File>, List<RmicProcessingItem>> sortedByModuleAndOutputPath = new HashMap<Pair<Module,File>, List<RmicProcessingItem>>();
+      for (ProcessingItem item1 : items) {
+        final RmicProcessingItem item = (RmicProcessingItem)item1;
+        final Pair<Module, File> moduleOutputPair = new Pair<Module, File>(item.getModule(), item.getOutputDir());
+        List<RmicProcessingItem> dirItems = sortedByModuleAndOutputPath.get(moduleOutputPair);
+        if (dirItems == null) {
+          dirItems = new ArrayList<RmicProcessingItem>();
+          sortedByModuleAndOutputPath.put(moduleOutputPair, dirItems);
+        }
+        dirItems.add(item);
+      }
+      final List<ProcessingItem> processed = new ArrayList<ProcessingItem>();
+
+      final JavacOutputParserPool parserPool = new JavacOutputParserPool(project, context);
+
+      for (final Pair<Module, File> pair : sortedByModuleAndOutputPath.keySet()) {
+        if (progressIndicator.isCanceled()) {
+          break;
+        }
+        final List<RmicProcessingItem> dirItems = sortedByModuleAndOutputPath.get(pair);
+        try {
+          // should delete all previously generated files for the remote class if there are any
+          for (Iterator itemIterator = dirItems.iterator(); itemIterator.hasNext();) {
+            final RmicProcessingItem item = (RmicProcessingItem)itemIterator.next();
+            item.deleteGeneratedFiles();
+            if (!item.isRemoteObject()) {
+              itemIterator
+                .remove(); // the object was remote and currently is not, so remove it from the list and do not generate stubs for it
+            }
+          }
+          if (!dirItems.isEmpty()) {
+            final RmicProcessingItem[] successfullyProcessed = invokeRmic(context, parserPool, pair.getFirst(), dirItems, pair.getSecond());
+            ContainerUtil.addAll(processed, successfullyProcessed);
+          }
+          progressIndicator.setFraction(((double)processed.size()) / ((double)items.length));
+        }
+        catch (IOException e) {
+          context.addMessage(CompilerMessageCategory.ERROR, e.getMessage(), null, -1, -1);
+          LOG.info(e);
+        }
+      }
+      // update state so that the latest timestamps are recorded by make
+      final ProcessingItem[] processedItems = processed.toArray(new ProcessingItem[processed.size()]);
+      final List<File> filesToRefresh = new ArrayList<File>(processedItems.length * 3);
+      for (ProcessingItem processedItem : processedItems) {
+        RmicProcessingItem item = (RmicProcessingItem)processedItem;
+        item.updateState();
+        filesToRefresh.add(item.myStub);
+        filesToRefresh.add(item.mySkel);
+        filesToRefresh.add(item.myTie);
+      }
+      CompilerUtil.refreshIOFiles(filesToRefresh);
+      return processedItems;
+    }
+    finally {
+      progressIndicator.popState();
+    }
+  }
+
+  private static RmicProcessingItem[] invokeRmic(final CompileContext context,
+                                          final JavacOutputParserPool parserPool, final Module module,
+                                          final List<RmicProcessingItem> dirItems,
+                                          final File outputDir
+  ) throws IOException{
+
+    final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+
+    final Map<String, RmicProcessingItem> pathToItemMap = new HashMap<String, RmicProcessingItem>();
+    final String[] cmdLine = ApplicationManager.getApplication().runReadAction(new Computable<String[]>() {
+      public String[] compute() {
+        for (final RmicProcessingItem item : dirItems) {
+          pathToItemMap.put(item.myStub.getPath().replace(File.separatorChar, '/'), item);
+          pathToItemMap.put(item.mySkel.getPath().replace(File.separatorChar, '/'), item);
+          pathToItemMap.put(item.myTie.getPath().replace(File.separatorChar, '/'), item);
+        }
+        return createStartupCommand(module, outputDir.getPath(), dirItems.toArray(new RmicProcessingItem[dirItems.size()]));
+      }
+    });
+
+    if (LOG.isDebugEnabled()) {
+      StringBuilder buf = new StringBuilder();
+      for (int idx = 0; idx < cmdLine.length; idx++) {
+        if (idx > 0) {
+          buf.append(" ");
+        }
+        buf.append(cmdLine[idx]);
+      }
+      LOG.debug(buf.toString());
+    }
+
+    // obtain parser before running the process because configuring parser may involve starting another process
+    final OutputParser outputParser = parserPool.getJavacOutputParser(jdk);
+
+    final Process process = Runtime.getRuntime().exec(cmdLine);
+    final Set<RmicProcessingItem> successfullyCompiledItems = new HashSet<RmicProcessingItem>();
+    final CompilerParsingThread parsingThread = new CompilerParsingThread(process, outputParser, false, true,context) {
+      protected void processCompiledClass(FileObject classFileToProcess) {
+        String key = classFileToProcess.getFile().getPath().replace(File.separatorChar, '/');
+        final RmicProcessingItem item = pathToItemMap.get(key);
+        if (item != null) {
+          successfullyCompiledItems.add(item);
+        }
+      }
+    };
+
+    final Future<?> parsingThreadFuture = ApplicationManager.getApplication().executeOnPooledThread(parsingThread);
+    try {
+      process.waitFor();
+    }
+    catch (InterruptedException ignored) {
+    }
+    finally {
+      parsingThread.setProcessTerminated(true);
+    }
+
+    try {
+      parsingThreadFuture.get();
+    }
+    catch (InterruptedException ignored) {
+    }
+    catch (ExecutionException ignored) {
+    }
+    return successfullyCompiledItems.toArray(new RmicProcessingItem[successfullyCompiledItems.size()]);
+  }
+
+  private static String[] createStartupCommand(final Module module, final String outputPath, final RmicProcessingItem[] items) {
+    final Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+
+    final VirtualFile homeDirectory = jdk.getHomeDirectory();
+    if (homeDirectory == null) {
+      throw new IllegalArgumentException(CompilerBundle.jdkHomeNotFoundMessage(jdk));
+    }
+    final String jdkPath = homeDirectory.getPath().replace('/', File.separatorChar);
+
+    @NonNls final String compilerPath = jdkPath + File.separator + "bin" + File.separator + "rmic";
+
+    @NonNls final List<String> commandLine = new ArrayList<String>();
+    commandLine.add(compilerPath);
+
+    CompilerUtil.addLocaleOptions(commandLine, true);
+
+    commandLine.add("-verbose");
+
+    final Project project = module.getProject();
+    ContainerUtil.addAll(commandLine, new RmicSettingsBuilder(RmicConfiguration.getOptions(project)).getOptions(new Chunk<Module>(module)));
+
+    commandLine.add("-classpath");
+
+    commandLine.add(getCompilationClasspath(module));
+
+    commandLine.add("-d");
+
+    commandLine.add(outputPath);
+
+    for (RmicProcessingItem item : items) {
+      commandLine.add(item.getClassQName());
+    }
+    return ArrayUtil.toStringArray(commandLine);
+  }
+
+  @NotNull
+  public String getDescription() {
+    return CompilerBundle.message("rmi.compiler.description");
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    return true;
+  }
+
+  /*
+  private void addAllRemoteFilesFromModuleOutput(final CompileContext context, final Module module, final List<ProcessingItem> items, final File outputDir, File fromDir, final JavaClass remoteInterface) {
+    final File[] children = fromDir.listFiles(CLASSES_AND_DIRECTORIES_FILTER);
+    for (int idx = 0; idx < children.length; idx++) {
+      final File child = children[idx];
+      if (child.isDirectory()) {
+        addAllRemoteFilesFromModuleOutput(context, module, items, outputDir, child, remoteInterface);
+      }
+      else {
+        final String path = child.getPath();
+        try {
+          final ClassParser classParser = new ClassParser(path);
+          final JavaClass javaClass = classParser.parse();
+          // important! Need this in order to resolve other classes in the project (e.g. superclasses)
+          javaClass.setRepository(BcelUtils.getActiveRepository());
+          if (isRmicCompilable(javaClass, remoteInterface)) {
+            ApplicationManager.getApplication().runReadAction(new Runnable() {
+              public void run() {
+                final VirtualFile outputClassFile = LocalFileSystem.getInstance().findFileByIoFile(child);
+                if (outputClassFile != null) {
+                  items.add(new RmicProcessingItem(module, outputClassFile, outputDir, javaClass.getClassName()));
+                }
+              }
+            });
+          }
+        }
+        catch (IOException e) {
+          context.addMessage(CompilerMessageCategory.ERROR, "Cannot parse class file " + path + ": " + e.toString(), null, -1, -1);
+        }
+        catch (ClassFormatException e) {
+          context.addMessage(CompilerMessageCategory.ERROR, "Class format exception: " + e.getMessage() + " File: " + path, null, -1, -1);
+        }
+      }
+    }
+  }
+  */
+
+  /*
+  private boolean isRmicCompilable(final JavaClass javaClass, final JavaClass remoteInterface) {
+    // stubs are needed for classes that _directly_ implement remote interfaces
+    if (javaClass.isInterface() || isGenerated(javaClass)) {
+      return false;
+    }
+    final JavaClass[] directlyImplementedInterfaces = javaClass.getInterfaces();
+    if (directlyImplementedInterfaces != null) {
+      for (int i = 0; i < directlyImplementedInterfaces.length; i++) {
+        if (directlyImplementedInterfaces[i].instanceOf(remoteInterface)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+  */
+
+  /*
+  private boolean isGenerated(JavaClass javaClass) {
+    final String sourceFileName = javaClass.getSourceFileName();
+    return sourceFileName == null || !sourceFileName.endsWith(".java");
+  }
+  */
+
+
+  public ValidityState createValidityState(DataInput in) throws IOException {
+    return new RemoteClassValidityState(in.readLong(), in.readLong(), in.readLong(), in.readLong());
+  }
+
+  private static String getCompilationClasspath(Module module) {
+    final OrderEnumerator enumerator = ModuleRootManager.getInstance(module).orderEntries().withoutSdk().compileOnly().recursively().exportedOnly();
+    final PathsList pathsList = enumerator.getPathsList();
+    return pathsList.getPathsString();
+  }
+
+  private static final class RemoteClassValidityState implements ValidityState {
+    private final long myRemoteClassTimestamp;
+    private final long myStubTimestamp;
+    private final long mySkelTimestamp;
+    private final long myTieTimestamp;
+
+    private RemoteClassValidityState(long remoteClassTimestamp, long stubTimestamp, long skelTimestamp, long tieTimestamp) {
+      myRemoteClassTimestamp = remoteClassTimestamp;
+      myStubTimestamp = stubTimestamp;
+      mySkelTimestamp = skelTimestamp;
+      myTieTimestamp = tieTimestamp;
+    }
+
+    public boolean equalsTo(ValidityState otherState) {
+      if (otherState instanceof RemoteClassValidityState) {
+        final RemoteClassValidityState state = (RemoteClassValidityState)otherState;
+        return myRemoteClassTimestamp == state.myRemoteClassTimestamp &&
+               myStubTimestamp == state.myStubTimestamp &&
+               mySkelTimestamp == state.mySkelTimestamp &&
+               myTieTimestamp == state.myTieTimestamp;
+      }
+      return false;
+    }
+
+    public void save(DataOutput out) throws IOException {
+      out.writeLong(myRemoteClassTimestamp);
+      out.writeLong(myStubTimestamp);
+      out.writeLong(mySkelTimestamp);
+      out.writeLong(myTieTimestamp);
+    }
+  }
+  private static final class RmicProcessingItem implements ProcessingItem {
+    private final Module myModule;
+    private final VirtualFile myOutputClassFile;
+    private final File myOutputDir;
+    private final String myQName;
+    private RemoteClassValidityState myState;
+    private final File myStub;
+    private final File mySkel;
+    private final File myTie;
+    private boolean myIsRemoteObject = false;
+
+    private RmicProcessingItem(Module module, final VirtualFile outputClassFile, File outputDir, String qName) {
+      myModule = module;
+      myOutputClassFile = outputClassFile;
+      myOutputDir = outputDir;
+      myQName = qName;
+      final String relativePath;
+      final String baseName;
+
+      final int index = qName.lastIndexOf('.');
+      if (index >= 0) {
+        relativePath = qName.substring(0, index + 1).replace('.', '/');
+        baseName = qName.substring(index + 1);
+      }
+      else {
+        relativePath = "";
+        baseName = qName;
+      }
+      final String path = outputDir.getPath().replace(File.separatorChar, '/') + "/" + relativePath;
+      //noinspection HardCodedStringLiteral
+      myStub = new File(path + "/" + baseName + "_Stub.class");
+      //noinspection HardCodedStringLiteral
+      mySkel = new File(path + "/" + baseName + "_Skel.class");
+      //noinspection HardCodedStringLiteral
+      myTie = new File(path + "/_" + baseName + "_Tie.class");
+      updateState();
+    }
+
+    public boolean isRemoteObject() {
+      return myIsRemoteObject;
+    }
+
+    public void setIsRemoteObject(boolean isRemote) {
+      myIsRemoteObject = isRemote;
+    }
+
+    @NotNull
+    public VirtualFile getFile() {
+      return myOutputClassFile;
+    }
+
+    public ValidityState getValidityState() {
+      return myState;
+    }
+
+    public void updateState() {
+      myState = new RemoteClassValidityState(
+        myOutputClassFile.getTimeStamp(),
+        getTimestamp(myStub),
+        getTimestamp(mySkel),
+        getTimestamp(myTie)
+      );
+
+    }
+
+    private static long getTimestamp(File file) {
+      long l = file.lastModified();
+      return l == 0 ? -1L : l;
+    }
+
+    public void deleteGeneratedFiles() {
+      if (FileUtil.delete(myStub)) {
+        CompilerUtil.refreshIOFile(myStub);
+      }
+      if (FileUtil.delete(mySkel)) {
+        CompilerUtil.refreshIOFile(mySkel);
+      }
+      if (FileUtil.delete(myTie)) {
+        CompilerUtil.refreshIOFile(myTie);
+      }
+    }
+
+    public String getClassQName() {
+      return myQName;
+    }
+
+    public File getOutputDir() {
+      return myOutputDir;
+    }
+
+    public Module getModule() {
+      return myModule;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicConfiguration.java
new file mode 100755
index 0000000..70b8b42
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicConfiguration.java
@@ -0,0 +1,46 @@
+/*
+ * 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.compiler.impl.rmiCompiler;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.RmicCompilerOptions;
+
+@State(
+  name = "RmicSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.PROJECT_FILE)
+   ,@Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/compiler.xml", scheme = StorageScheme.DIRECTORY_BASED)
+    }
+)
+public class RmicConfiguration implements PersistentStateComponent<RmicCompilerOptions> {
+  private final RmicCompilerOptions mySettings = new RmicCompilerOptions();
+
+  @NotNull
+  public RmicCompilerOptions getState() {
+    return mySettings;
+  }
+
+  public void loadState(RmicCompilerOptions state) {
+    XmlSerializerUtil.copyBean(state, mySettings);
+  }
+
+  public static RmicCompilerOptions getOptions(Project project) {
+    return ServiceManager.getService(project, RmicConfiguration.class).getState();
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicSettingsBuilder.java b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicSettingsBuilder.java
new file mode 100644
index 0000000..e4b0aee
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/rmiCompiler/RmicSettingsBuilder.java
@@ -0,0 +1,55 @@
+/*
+ * 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.compiler.impl.rmiCompiler;
+
+import com.intellij.compiler.impl.javaCompiler.javac.JavacSettingsBuilder;
+import com.intellij.openapi.module.Module;
+import com.intellij.util.Chunk;
+import org.jetbrains.jps.model.java.compiler.RmicCompilerOptions;
+
+import java.util.Collection;
+
+public class RmicSettingsBuilder extends JavacSettingsBuilder {
+
+  public RmicSettingsBuilder(final RmicCompilerOptions options) {
+    super(options);
+    getOptions().DEPRECATION = false; // in this configuration deprecation is false by default
+  }
+
+  @Override
+  public RmicCompilerOptions getOptions() {
+    return (RmicCompilerOptions)super.getOptions();
+  }
+
+  public Collection<String> getOptions(Chunk<Module> chunk) {
+    final Collection<String> options = super.getOptions(chunk);
+    if(getOptions().GENERATE_IIOP_STUBS) {
+      options.add("-iiop");
+    }
+    return options;
+  }
+
+  protected boolean acceptUserOption(String token) {
+    if (!super.acceptUserOption(token)) {
+      return false;
+    }
+    return !("-iiop".equals(token));
+  }
+
+  protected boolean acceptEncoding() {
+    return false;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/AnnotationTargets.java b/java/compiler/impl/src/com/intellij/compiler/make/AnnotationTargets.java
new file mode 100644
index 0000000..100fd4a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/AnnotationTargets.java
@@ -0,0 +1,66 @@
+/*
+ * 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.compiler.make;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 7, 2004
+ */
+public interface AnnotationTargets {
+  /** Class, interface or enum declaration */
+  int TYPE = 0x1;
+
+  @NonNls String TYPE_STR = "TYPE";
+
+  /** Field declaration (includes enum constants) */
+  int FIELD = 0x2;
+
+  @NonNls String FIELD_STR = "FIELD";
+
+  /** Method declaration */
+  int METHOD = 0x4;
+
+  @NonNls String METHOD_STR = "METHOD";
+
+  /** Parameter declaration */
+  int PARAMETER = 0x8;
+
+  @NonNls String PARAMETER_STR = "PARAMETER";
+
+  /** Constructor declaration */
+  int CONSTRUCTOR = 0x10;
+
+  @NonNls String CONSTRUCTOR_STR = "CONSTRUCTOR";
+
+  /** Local variable declaration */
+  int LOCAL_VARIABLE = 0x20;
+
+  @NonNls String LOCAL_VARIABLE_STR = "LOCAL_VARIABLE";
+
+  /** Annotation type declaration */
+  int ANNOTATION_TYPE = 0x40;
+
+  @NonNls String ANNOTATION_TYPE_STR = "ANNOTATION_TYPE";
+
+  /** Package declaration */
+  int PACKAGE = 0x80;
+
+  @NonNls String PACKAGE_STR = "PACKAGE";
+
+  int ALL = TYPE | FIELD | METHOD | PARAMETER | CONSTRUCTOR | LOCAL_VARIABLE | ANNOTATION_TYPE | PACKAGE;
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java
new file mode 100644
index 0000000..fb7a5c6
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/BackwardDependenciesStorage.java
@@ -0,0 +1,511 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.containers.SLRUCache;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.EnumeratorIntegerDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import gnu.trove.*;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 1, 2008
+ */
+public class BackwardDependenciesStorage implements Flushable, Disposable {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CompilerDependencyStorage");
+  protected final PersistentHashMap<Integer, DependenciesSet> myMap;
+  protected final SLRUCache<Integer, ReferencerSetHolder> myCache;
+  private Integer myKeyToRemove;
+  private static final int FIELD = 1;
+  private static final int METHOD = 2;
+  private static final int CLASS = 3;
+
+  public BackwardDependenciesStorage(File file, final int cacheSize) throws IOException {
+    myMap = new PersistentHashMap<Integer, DependenciesSet>(file, EnumeratorIntegerDescriptor.INSTANCE, new MyDataExternalizer());
+
+    myCache = new SLRUCache<Integer, ReferencerSetHolder>(cacheSize * 2, cacheSize) {
+      @NotNull
+      public ReferencerSetHolder createValue(Integer key) {
+        return new ReferencerSetHolder(key);
+      }
+
+      protected void onDropFromCache(Integer key, final ReferencerSetHolder holder) {
+        if (key.equals(myKeyToRemove) || !holder.isDirty()) {
+          return;
+        }
+        try {
+          if (holder.isDataLoaded() || !myMap.containsMapping(key)) {
+            myMap.put(key, new DependenciesSet(holder.getData()));
+          }
+          else {
+            myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
+              public void append(final DataOutput out) throws IOException {
+                final Ref<IOException> exception = new Ref<IOException>(null);
+                // process removed
+                holder.myRemoveRequested.forEach(new TIntProcedure() {
+                  public boolean execute(int qName) {
+                    try {
+                      out.writeInt(-qName);
+                      return true;
+                    }
+                    catch (IOException e) {
+                      exception.set(e);
+                    }
+                    return false;
+                  }
+                });
+                final IOException _ex = exception.get();
+                if (_ex != null) {
+                  throw _ex;
+                }
+                // process added members
+                for (ReferencerItem item : holder.myAdded) {
+                  item.save(out);
+                }
+              }
+            });
+          }
+        }
+        catch (IOException e) {
+          LOG.error(e);
+        }
+      }
+    };
+  }
+
+  public synchronized void remove(Integer qName) throws IOException {
+    myKeyToRemove = qName;
+    try {
+      myCache.remove(qName);
+    }
+    finally {
+      myKeyToRemove = null;
+    }
+    myMap.remove(qName);
+  }
+
+  public synchronized void removeReferencer(Integer qName, int referencerQName) throws IOException {
+    if (myMap.containsMapping(qName)) {
+      final ReferencerSetHolder set = myCache.get(qName);
+      set.removeReferencer(referencerQName);
+    }
+  }
+
+  public synchronized void addClassReferencer(Integer qName, int referencerQName) {
+    myCache.get(qName).addReferencer(new ReferencerItem(referencerQName));
+  }
+
+  public synchronized void addFieldReferencer(Integer qName, int referencerQName, int fieldName) {
+    myCache.get(qName).addReferencer(new FieldReferencerItem(referencerQName, fieldName));
+  }
+
+  public synchronized void addMethodReferencer(Integer qName, int referencerQName, int methodName, int descriptor) {
+    myCache.get(qName).addReferencer(new MethodReferencerItem(referencerQName, methodName, descriptor));
+  }
+
+  public synchronized Dependency[] getDependencies(Integer classQName) throws CacheCorruptedException {
+    try {
+      if (!myMap.containsMapping(classQName)) {
+        return Dependency.EMPTY_ARRAY;
+      }
+
+      return convertToDependencies(classQName.intValue(), myCache.get(classQName).getData());
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  private static Dependency[] convertToDependencies(int classToSkip, Set<ReferencerItem> data) {
+    final TIntObjectHashMap<Dependency> dependencies = new TIntObjectHashMap<Dependency>();
+    for (ReferencerItem item : data) {
+      if (item.qName == classToSkip) {
+        continue; // skip self-dependencies
+      }
+      final Dependency dependency = addDependency(dependencies, item.qName);
+      if (item instanceof FieldReferencerItem) {
+        dependency.addField(((FieldReferencerItem)item).name);
+      }
+      else if (item instanceof MethodReferencerItem) {
+        final MethodReferencerItem methodItem = (MethodReferencerItem)item;
+        dependency.addMethod(methodItem.name, methodItem.descriptor);
+      }
+    }
+
+    final Dependency[] dependencyArray = new Dependency[dependencies.size()];
+    dependencies.forEachValue(new TObjectProcedure<Dependency>() {
+      private int index = 0;
+      public boolean execute(Dependency object) {
+        dependencyArray[index++] = object;
+        return true;
+      }
+    });
+    return dependencyArray;
+  }
+
+  private static Dependency addDependency(TIntObjectHashMap<Dependency> container, int classQName) {
+    Dependency dependency = container.get(classQName);
+    if (dependency == null) {
+      dependency = new Dependency(classQName);
+      container.put(classQName, dependency);
+    }
+    return dependency;
+  }
+
+  public synchronized void flush() throws IOException {
+    myCache.clear();
+    myMap.force();
+  }
+
+  private void flush(Integer key) {
+    myCache.remove(key); // makes changes into PersistentHashMap
+    myMap.force(); // flushes internal caches (which consume memory) and writes unsaved data to disk
+  }
+
+  public synchronized void dispose() {
+    try {
+      flush();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    try {
+      myMap.close();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+  }
+
+  private static class ReferencerItem {
+    public final int qName;
+
+    private ReferencerItem(int qName) {
+      this.qName = qName;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      ReferencerItem that = (ReferencerItem)o;
+
+      if (qName != that.qName) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      return qName;
+    }
+
+    public void save(DataOutput out) throws IOException {
+      out.writeInt(qName);
+      out.writeByte(CLASS);
+    }
+  }
+
+  private static final class MethodReferencerItem extends ReferencerItem {
+    public final int name;
+    public final int descriptor;
+
+    MethodReferencerItem(int qName, int name, int descriptor) {
+      super(qName);
+      this.name = name;
+      this.descriptor = descriptor;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+      if (!super.equals(o)) return false;
+
+      MethodReferencerItem that = (MethodReferencerItem)o;
+
+      if (descriptor != that.descriptor) return false;
+      if (name != that.name) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      int result = super.hashCode();
+      result = 31 * result + name;
+      result = 31 * result + descriptor;
+      return result;
+    }
+
+    public void save(DataOutput out) throws IOException {
+      out.writeInt(qName);
+      out.writeByte(METHOD);
+      out.writeInt(name);
+      out.writeInt(descriptor);
+    }
+  }
+
+  private static final class FieldReferencerItem extends ReferencerItem {
+    public final int name;
+
+    FieldReferencerItem(int qName, int name) {
+      super(qName);
+      this.name = name;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+      if (!super.equals(o)) return false;
+
+      FieldReferencerItem that = (FieldReferencerItem)o;
+
+      if (name != that.name) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      int result = super.hashCode();
+      result = 31 * result + name;
+      return result;
+    }
+
+    public void save(DataOutput out) throws IOException {
+      out.writeInt(qName);
+      out.writeByte(FIELD);
+      out.writeInt(name);
+    }
+  }
+
+  private class ReferencerSetHolder {
+    private final Integer myKey;
+    private TIntHashSet myRemoveRequested = new TIntHashSet();
+    private Set<ReferencerItem> myAdded = new THashSet<ReferencerItem>();
+    
+    private Set<ReferencerItem> myData = null;
+    private boolean myIsDirty = false;
+
+    public ReferencerSetHolder(Integer key) {
+      myKey = key;
+    }
+
+    public void addReferencer(ReferencerItem referencer) {
+      if (myData != null) {
+        myIsDirty |= myData.add(referencer);
+        return;
+      }
+      myAdded.add(referencer);
+    }
+
+    public void removeReferencer(int qName) {
+      if (myData != null) {
+        myIsDirty |= removeAllReferencerItems(myData, qName);
+        return;
+      }
+      myRemoveRequested.add(qName);
+      removeAllReferencerItems(myAdded, qName);
+    }
+
+    public boolean isDirty() {
+      return myData != null? myIsDirty : myRemoveRequested.size() > 0 || myAdded.size() > 0;
+    }
+
+    public boolean isDataLoaded() {
+      return myData != null;
+    }
+
+    public Set<ReferencerItem> getData() throws IOException {
+      if (myData == null) {
+        final DependenciesSet ds = myMap.get(myKey);
+        Set<ReferencerItem> set = null;
+        if (ds != null) {
+          set = ds.set;
+          myIsDirty |= ds.needsCompacting;
+        }
+        if (set == null) {
+          set = new THashSet<ReferencerItem>();
+        }
+        myIsDirty |= removeAllReferencerItems(set, myRemoveRequested);
+        myIsDirty |= set.addAll(myAdded);
+        myData = set;
+        myAdded = null;
+        myRemoveRequested = null;
+      }
+      return Collections.unmodifiableSet(myData);
+    }
+
+  }
+
+  private static class MyDataExternalizer implements DataExternalizer<DependenciesSet> {
+    public void save(DataOutput out, DependenciesSet ds) throws IOException {
+      final TIntHashSet classes = new TIntHashSet();
+      final Map<Dependency.FieldRef, TIntHashSet> fieldsMap = new HashMap<Dependency.FieldRef, TIntHashSet>();
+      final Map<Dependency.MethodRef, TIntHashSet> methodsMap = new HashMap<Dependency.MethodRef, TIntHashSet>();
+      for (ReferencerItem item : ds.set) {
+        if (item instanceof FieldReferencerItem) {
+          final Dependency.FieldRef ref = new Dependency.FieldRef(((FieldReferencerItem)item).name);
+          TIntHashSet referencers = fieldsMap.get(ref);
+          if (referencers == null) {
+            referencers = new TIntHashSet();
+            fieldsMap.put(ref, referencers);
+          }
+          referencers.add(item.qName);
+        }
+        else if (item instanceof MethodReferencerItem) {
+          final MethodReferencerItem _item = (MethodReferencerItem)item;
+          final Dependency.MethodRef ref = new Dependency.MethodRef(_item.name, _item.descriptor);
+          TIntHashSet referencers = methodsMap.get(ref);
+          if (referencers == null) {
+            referencers = new TIntHashSet();
+            methodsMap.put(ref, referencers);
+          }
+          referencers.add(item.qName);
+        }
+        else {
+          classes.add(item.qName);
+        }
+      }
+
+      out.writeInt(classes.size());
+      for (TIntIterator it = classes.iterator(); it.hasNext();) {
+        out.writeInt(it.next());
+      }
+
+      out.writeInt(fieldsMap.size());
+      for (Map.Entry<Dependency.FieldRef, TIntHashSet> entry : fieldsMap.entrySet()) {
+        out.writeInt(entry.getKey().name);
+        final TIntHashSet referencers = entry.getValue();
+        out.writeInt(referencers.size());
+        for (TIntIterator rit = referencers.iterator(); rit.hasNext();) {
+          out.writeInt(rit.next());
+        }
+      }
+
+      out.writeInt(methodsMap.size());
+      for (Map.Entry<Dependency.MethodRef, TIntHashSet> entry : methodsMap.entrySet()) {
+        final Dependency.MethodRef ref = entry.getKey();
+        out.writeInt(ref.name);
+        out.writeInt(ref.descriptor);
+        final TIntHashSet referencers = entry.getValue();
+        out.writeInt(referencers.size());
+        for (TIntIterator rit = referencers.iterator(); rit.hasNext();) {
+          out.writeInt(rit.next());
+        }
+      }
+    }
+
+    public DependenciesSet read(DataInput in) throws IOException {
+      final Set<ReferencerItem> set = new THashSet<ReferencerItem>();
+
+      int classesCount = in.readInt();
+      while (classesCount-- > 0) {
+        set.add(new ReferencerItem(in.readInt()));
+      }
+
+      int fieldsCount = in.readInt();
+      while (fieldsCount-- > 0) {
+        final int fieldName = in.readInt();
+        int referencersCount = in.readInt();
+        while (referencersCount-- > 0) {
+          set.add(new FieldReferencerItem(in.readInt(), fieldName));
+        }
+      }
+
+      int methodsCount = in.readInt();
+      while (methodsCount-- > 0) {
+        final int methodName = in.readInt();
+        final int methodDescriptor = in.readInt();
+        int referensersCount = in.readInt();
+        while (referensersCount-- > 0) {
+          set.add(new MethodReferencerItem(in.readInt(), methodName, methodDescriptor));
+        }
+      }
+      boolean needsCompacting = false;
+      // manage appends if exist qName, kind, {field | method}
+      final DataInputStream _in = (DataInputStream)in;
+      while (_in.available() > 0) {
+        needsCompacting = true;
+        final int qName = _in.readInt();
+        if (qName < 0) {
+          removeAllReferencerItems(set, -qName);
+        }
+        else {
+          final byte kind = _in.readByte();
+          if (kind == FIELD) {
+            set.add(new FieldReferencerItem(qName, _in.readInt()));
+          }
+          else if (kind == METHOD) {
+            final int name = _in.readInt();
+            final int descriptor = _in.readInt();
+            set.add(new MethodReferencerItem(qName, name, descriptor));
+          }
+          else if (kind == CLASS){
+            set.add(new ReferencerItem(qName));
+          }
+        }
+      }
+
+      return new DependenciesSet(set, needsCompacting);
+    }
+  }
+
+  private static final class DependenciesSet {
+    public final Set<ReferencerItem> set;
+    public final boolean needsCompacting;
+
+    public DependenciesSet(Set<ReferencerItem> set, boolean needsCompacting) {
+      this.set = set;
+      this.needsCompacting = needsCompacting;
+    }
+
+    public DependenciesSet(Set<ReferencerItem> set) {
+      this(set, false);
+    }
+  }
+
+
+  private static boolean removeAllReferencerItems(final Set<ReferencerItem> from, final TIntHashSet qNames) {
+    boolean removed = false;
+    for (Iterator<ReferencerItem> it = from.iterator(); it.hasNext();) {
+      final ReferencerItem item = it.next();
+      if (qNames.contains(item.qName)) {
+        it.remove();
+        removed = true;
+      }
+    }
+    return removed;
+  }
+
+  private static boolean removeAllReferencerItems(final Set<ReferencerItem> from, final int qNames) {
+    boolean removed = false;
+    for (Iterator<ReferencerItem> it = from.iterator(); it.hasNext();) {
+      final ReferencerItem item = it.next();
+      if (qNames == item.qName) {
+        it.remove();
+        removed = true;
+      }
+    }
+    return removed;
+  }
+
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/BoundsParser.java b/java/compiler/impl/src/com/intellij/compiler/make/BoundsParser.java
new file mode 100644
index 0000000..0ab9489
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/BoundsParser.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.compiler.make;
+
+import com.intellij.compiler.classParsing.SignatureParser;
+import com.intellij.compiler.classParsing.SignatureParsingException;
+import com.intellij.util.ArrayUtil;
+
+import java.text.CharacterIterator;
+import java.text.StringCharacterIterator;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 10, 2004
+ */
+public class BoundsParser extends SignatureParser{
+  final List<String> myInterfaceBounds = new ArrayList<String>();
+  private int myParsingBound;
+
+  public void parseClassBound(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
+    myParsingBound += 1;
+    try {
+      super.parseClassBound(it, buf);
+    }
+    finally {
+      myParsingBound -= 1;
+    }
+  }
+
+  public void parseInterfaceBound(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
+    myParsingBound += 1;
+    try {
+      super.parseInterfaceBound(it, buf);
+    }
+    finally {
+      myParsingBound -= 1;
+    }
+  }
+
+  public void parseClassTypeSignature(CharacterIterator it, StringBuilder buf) throws SignatureParsingException {
+    if (myParsingBound > 0) {
+      final int start = buf.length();
+
+      super.parseClassTypeSignature(it, buf);
+
+      final String qName = convertToQalifiedName(buf.substring(start + 1, buf.length() - 1));
+      myInterfaceBounds.add(qName);
+    }
+    else {
+      super.parseClassTypeSignature(it, buf);
+    }
+  }
+
+  private static String convertToQalifiedName(String ifaceSignature) {
+    ifaceSignature = ifaceSignature.replaceAll("<.*>", "");
+    return ifaceSignature.replace('/', '.');
+  }
+
+  public String[] getBounds() {
+    return ArrayUtil.toStringArray(myInterfaceBounds);
+  }
+
+  public static String[] getBounds(String classSignature) throws SignatureParsingException {
+    final BoundsParser parser = new BoundsParser();
+    parser.parseClassSignature(new StringCharacterIterator(classSignature), new StringBuilder());
+    return parser.getBounds();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/Cache.java b/java/compiler/impl/src/com/intellij/compiler/make/Cache.java
new file mode 100644
index 0000000..2e3d554
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/Cache.java
@@ -0,0 +1,520 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.EnumeratorIntegerDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Aug 8, 2003
+ * Time: 7:03:56 PM
+ */
+public class Cache {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.Cache");
+  public static final int UNKNOWN = -1;
+
+  private final PersistentHashMap<Integer, ClassInfo> myQNameToClassInfoMap;
+
+  private final BackwardDependenciesStorage myDependencies;
+  private final CompilerDependencyStorage<Integer> myQNameToReferencedClassesMap;
+  private final CompilerDependencyStorage<Integer> myQNameToSubclassesMap;
+  private final PersistentHashMap<Integer, Boolean> myRemoteQNames;
+  private final String myStorePath;
+
+  public Cache(@NonNls final String storePath, final int cacheSize) throws IOException {
+    myStorePath = storePath;
+    new File(storePath).mkdirs();
+    myQNameToClassInfoMap = new CachedPersistentHashMap<Integer, ClassInfo>(getOrCreateFile("classes"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<ClassInfo>() {
+      public void save(DataOutput out, ClassInfo value) throws IOException {
+        value.save(out);
+      }
+      public ClassInfo read(DataInput in) throws IOException {
+        return new ClassInfo(in);
+      }
+    }, cacheSize * 2) {
+      protected boolean isValueDirty(ClassInfo classInfo) {
+        return classInfo.isDirty();
+      }
+    };
+
+    myDependencies = new BackwardDependenciesStorage(getOrCreateFile("bdeps"), cacheSize);
+    myQNameToReferencedClassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("fdeps"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize);
+    myQNameToSubclassesMap = new CompilerDependencyStorage<Integer>(getOrCreateFile("subclasses"), EnumeratorIntegerDescriptor.INSTANCE, cacheSize);
+
+    myRemoteQNames = new PersistentHashMap<Integer, Boolean>(getOrCreateFile("remote"), EnumeratorIntegerDescriptor.INSTANCE, new DataExternalizer<Boolean>() {
+      public void save(DataOutput out, Boolean value) throws IOException {
+        out.writeBoolean(value.booleanValue());
+      }
+
+      public Boolean read(DataInput in) throws IOException {
+        return in.readBoolean();
+      }
+    }, cacheSize);
+  }
+
+  private File getOrCreateFile(final String fileName) throws IOException {
+    final File file = new File(myStorePath, fileName);
+    FileUtil.createIfDoesntExist(file);
+    return file;
+  }
+
+  public void dispose() throws CacheCorruptedException {
+    CacheCorruptedException ex = null;
+    try {
+      myQNameToClassInfoMap.close();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      ex = new CacheCorruptedException(e);
+    }
+    try {
+      myRemoteQNames.close();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+      if (ex != null) {
+        ex = new CacheCorruptedException(e);
+      }
+    }
+
+    myQNameToReferencedClassesMap.dispose();
+    myDependencies.dispose();
+    myQNameToSubclassesMap.dispose();
+
+    if (ex != null) {
+      throw ex;
+    }
+
+  }
+
+  public int[] getAllClassNames() throws CacheCorruptedException {
+    try {
+      final Collection<Integer> allKeys = myQNameToClassInfoMap.getAllKeysWithExistingMapping();
+      final int[] array = ArrayUtil.newIntArray(allKeys.size());
+      int idx = 0;
+      for (Integer id : allKeys) {
+        array[idx++] = id.intValue();
+      }
+      return array;
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int importClassInfo(ClassFileReader reader, SymbolTable symbolTable) throws ClsFormatException, CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = new ClassInfo(reader, symbolTable);
+      myQNameToClassInfoMap.put(classInfo.getQualifiedName(), classInfo);
+      return classInfo.getQualifiedName();
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void importClassInfo(Cache fromCache, final int qName) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = fromCache.myQNameToClassInfoMap.get(qName);
+      if (classInfo != null) {
+        final ClassInfo clone = classInfo.clone();
+        clone.clearReferences();
+        myQNameToClassInfoMap.put(qName, clone);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public AnnotationConstantValue[] getRuntimeVisibleAnnotations(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getRuntimeVisibleAnnotations() : AnnotationConstantValue.EMPTY_ARRAY;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public AnnotationConstantValue[] getRuntimeInvisibleAnnotations(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getRuntimeInvisibleAnnotations() : AnnotationConstantValue.EMPTY_ARRAY;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int[] getSubclasses(int classId) throws CacheCorruptedException {
+    try {
+      return myQNameToSubclassesMap.getValues(classId);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void addSubclass(int classId, int subclassQName) throws CacheCorruptedException {
+    try {
+      myQNameToSubclassesMap.addValue(classId, subclassQName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void removeSubclass(int classId, int subclassQName) throws CacheCorruptedException {
+    try {
+      myQNameToSubclassesMap.removeValue(classId, subclassQName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int[] getReferencedClasses(int qName) throws CacheCorruptedException {
+    try {
+      return myQNameToReferencedClassesMap.getValues(qName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void clearReferencedClasses(int qName) throws CacheCorruptedException {
+    try {
+      myQNameToReferencedClassesMap.remove(qName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public Collection<ReferenceInfo> getReferences(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? Arrays.asList(classInfo.getReferences()) : Collections.<ReferenceInfo>emptyList();
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public String getSourceFileName(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getSourceFileName() : "";
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public boolean isRemote(int classId) throws CacheCorruptedException {
+    try {
+      return myRemoteQNames.containsMapping(classId);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void setRemote(int classId, boolean remote) throws CacheCorruptedException {
+    try {
+      if (remote) {
+        myRemoteQNames.put(classId, Boolean.TRUE);
+      }
+      else {
+        myRemoteQNames.remove(classId);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int getSuperQualifiedName(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getSuperQualifiedName() : UNKNOWN;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public String getPath(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getPath() : "";
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void setPath(int classId, String path) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      if (classInfo != null) {
+        classInfo.setPath(path);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+  
+  public int getGenericSignature(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getGenericSignature() : UNKNOWN;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public boolean containsClass(int qName) throws CacheCorruptedException {
+    try {
+      return myQNameToClassInfoMap.containsMapping(qName);
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int[] getSuperInterfaces(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getSuperInterfaces() : ArrayUtil.EMPTY_INT_ARRAY;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public int getFlags(int classId) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classId);
+      return classInfo != null? classInfo.getFlags() : UNKNOWN;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public FieldInfo[] getFields(int qName) throws CacheCorruptedException{
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(qName);
+      return classInfo != null? classInfo.getFields() : FieldInfo.EMPTY_ARRAY;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  @Nullable
+  public FieldInfo findField(final int classDeclarationId, final int name, final int descriptor) throws CacheCorruptedException{
+    try {
+      for (FieldInfo fieldInfo : getFields(classDeclarationId)) {
+        if (fieldInfo.getName() == name && fieldInfo.getDescriptor() == descriptor) {
+          return fieldInfo;
+        }
+      }
+      return null;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  @Nullable
+  public FieldInfo findFieldByName(final int classDeclarationId, final int name) throws CacheCorruptedException{
+    try {
+      for (FieldInfo fieldInfo : getFields(classDeclarationId)) {
+        if (fieldInfo.getName() == name) {
+          return fieldInfo;
+        }
+      }
+      return null;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public MethodInfo[] getMethods(int classQName) throws CacheCorruptedException{
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(classQName);
+      return classInfo != null? classInfo.getMethods() : MethodInfo.EMPTY_ARRAY;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  @Nullable
+  public MethodInfo findMethod(final int classQName, final int name, final int descriptor) throws CacheCorruptedException{
+    try {
+      for (MethodInfo methodInfo : getMethods(classQName)) {
+        if (methodInfo.getName() == name && methodInfo.getDescriptor() == descriptor) {
+          return methodInfo;
+        }
+      }
+      return null;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public List<MethodInfo> findMethodsByName(final int classDeclarationId, final int name) throws CacheCorruptedException{
+    try {
+      final List<MethodInfo> methods = new ArrayList<MethodInfo>();
+      for (MethodInfo methodInfo : getMethods(classDeclarationId)) {
+        if (methodInfo.getName() == name) {
+          methods.add(methodInfo);
+        }
+      }
+      return methods;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  @Nullable
+  public MethodInfo findMethodsBySignature(final int classDeclarationId, final String signature, SymbolTable symbolTable) throws CacheCorruptedException{
+    try {
+      for (MethodInfo methodInfo : getMethods(classDeclarationId)) {
+        if (signature.equals(CacheUtils.getMethodSignature(symbolTable.getSymbol(methodInfo.getName()), symbolTable.getSymbol(methodInfo.getDescriptor())))) {
+          return methodInfo;
+        }
+      }
+      return null;
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void addClassReferencer(int qName, int referencerQName) throws CacheCorruptedException {
+    try {
+      if (qName == referencerQName) {
+        return; // do not log self-dependencies
+      }
+      if (myQNameToClassInfoMap.containsMapping(qName)) {
+        myDependencies.addClassReferencer(qName, referencerQName);
+        myQNameToReferencedClassesMap.addValue(referencerQName, qName);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void removeClassReferencer(int qName, int referencerQName) throws CacheCorruptedException {
+    try {
+      myDependencies.removeReferencer(qName, referencerQName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void addFieldReferencer(int qName, int fieldName, int referencerQName) throws CacheCorruptedException {
+    try {
+      if (qName != referencerQName && myQNameToClassInfoMap.containsMapping(qName)) {
+        myDependencies.addFieldReferencer(qName, referencerQName, fieldName);
+        myQNameToReferencedClassesMap.addValue(referencerQName, qName);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void addMethodReferencer(int qName, int methodName, int methodDescriptor, int referencerQName) throws CacheCorruptedException {
+    try {
+      if (qName != referencerQName && myQNameToClassInfoMap.containsMapping(qName)) {
+        myDependencies.addMethodReferencer(qName, referencerQName, methodName, methodDescriptor);
+        myQNameToReferencedClassesMap.addValue(referencerQName, qName);
+      }
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  /** @NotNull */
+  public Dependency[] getBackDependencies(final int classQName) throws CacheCorruptedException{
+    return myDependencies.getDependencies(classQName);
+  }
+
+  public void wipe() {
+    try {
+      dispose();
+    }
+    catch (CacheCorruptedException ignored) {
+    }
+    finally {
+      final File[] files = new File(myStorePath).listFiles();
+      if (files != null) {
+        for (File file : files) {
+          if (!file.isDirectory()) {
+            FileUtil.delete(file);
+          }
+        }
+      }
+    }
+  }
+
+  public void removeClass(final int qName) throws CacheCorruptedException {
+    try {
+      final ClassInfo classInfo = myQNameToClassInfoMap.get(qName);
+      if (classInfo == null) {
+        return;
+      }
+      myDependencies.remove(qName);
+      myQNameToClassInfoMap.remove(qName);
+      myQNameToReferencedClassesMap.remove(qName);
+      myQNameToSubclassesMap.remove(qName);
+      myRemoteQNames.remove(qName);
+    }
+    catch (Throwable e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheCorruptedException.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheCorruptedException.java
new file mode 100644
index 0000000..916a370
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheCorruptedException.java
@@ -0,0 +1,43 @@
+/*
+ * 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: Jul 10, 2003
+ * Time: 4:51:25 PM
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+
+public class CacheCorruptedException extends Exception{
+  private static final String DEFAULT_MESSAGE = CompilerBundle.message("error.dependency.info.on.disk.corrupted");
+  public CacheCorruptedException(String message) {
+    super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message);
+  }
+
+  public CacheCorruptedException(Throwable cause) {
+    super(DEFAULT_MESSAGE, cause);
+  }
+
+  public CacheCorruptedException(String message, Throwable cause) {
+    super((message == null || message.length() == 0)? DEFAULT_MESSAGE : message, cause);
+  }
+
+  public String getMessage() {
+    return super.getMessage();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java
new file mode 100644
index 0000000..bf2a58e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CacheUtils.java
@@ -0,0 +1,211 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerManagerImpl;
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.MethodInfo;
+import com.intellij.compiler.impl.ExitException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessage;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.StringBuilderSpinAllocator;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ * Date: Aug 18, 2003
+ * Time: 6:32:32 PM
+ */
+public class CacheUtils {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CacheUtils");
+
+  public static String[] getParameterSignatures(MethodInfo methodDeclarationId, SymbolTable symbolTable) throws CacheCorruptedException {
+    String descriptor = symbolTable.getSymbol(methodDeclarationId.getDescriptor());
+    int endIndex = descriptor.indexOf(')');
+    if (endIndex <= 0) {
+      LOG.error("Corrupted method descriptor: " + descriptor);
+    }
+    return parseSignature(descriptor.substring(1, endIndex));
+  }
+
+  private static String[] parseSignature(String signature) {
+    final ArrayList<String> list = new ArrayList<String>();
+    String paramSignature = parseParameterSignature(signature);
+    while (paramSignature != null && !"".equals(paramSignature)) {
+      list.add(paramSignature);
+      signature = signature.substring(paramSignature.length());
+      paramSignature = parseParameterSignature(signature);
+    }
+    return ArrayUtil.toStringArray(list);
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  private static @Nullable String parseParameterSignature(String signature) {
+    if (StringUtil.startsWithChar(signature, 'B')) {
+      return "B";
+    }
+    if (StringUtil.startsWithChar(signature, 'C')) {
+      return "C";
+    }
+    if (StringUtil.startsWithChar(signature, 'D')) {
+      return "D";
+    }
+    if (StringUtil.startsWithChar(signature, 'F')) {
+      return "F";
+    }
+    if (StringUtil.startsWithChar(signature, 'I')) {
+      return "I";
+    }
+    if (StringUtil.startsWithChar(signature, 'J')) {
+      return "J";
+    }
+    if (StringUtil.startsWithChar(signature, 'S')) {
+      return "S";
+    }
+    if (StringUtil.startsWithChar(signature, 'Z')) {
+      return "Z";
+    }
+    if (StringUtil.startsWithChar(signature, 'L')) {
+      return signature.substring(0, signature.indexOf(";") + 1);
+    }
+    if (StringUtil.startsWithChar(signature, '[')) {
+      String s = parseParameterSignature(signature.substring(1));
+      return (s != null) ? ("[" + s) : null;
+    }
+    return null;
+  }
+
+  public static String getMethodSignature(String name, String descriptor) {
+    final StringBuilder builder = StringBuilderSpinAllocator.alloc();
+    try {
+      builder.append(name);
+      builder.append(descriptor.substring(0, descriptor.indexOf(')') + 1));
+      return builder.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(builder);
+    }
+  }
+
+  public static boolean areArraysContentsEqual(int[] exceptions1, int[] exceptions2) {
+    if (exceptions1.length != exceptions2.length) {
+      return false;
+    }
+    if (exceptions1.length != 0) { // optimization
+      TIntHashSet exceptionsSet = new TIntHashSet(exceptions1);
+      for (int exception : exceptions2) {
+        if (!exceptionsSet.contains(exception)) {
+          return false;
+        }
+      }
+    }
+    return true;
+  }
+
+  public static Collection<VirtualFile> findDependentFiles(
+    final CompileContextEx context, 
+    final Set<VirtualFile> compiledWithErrors, 
+    final @Nullable Function<Pair<int[], Set<VirtualFile>>, Pair<int[], Set<VirtualFile>>> filter)
+    throws CacheCorruptedException, ExitException {
+    
+    if (!CompilerConfiguration.MAKE_ENABLED) {
+      return Collections.emptyList();
+    }
+    context.getProgressIndicator().setText(CompilerBundle.message("progress.checking.dependencies"));
+
+    final DependencyCache dependencyCache = context.getDependencyCache();
+
+    final Pair<int[], Set<VirtualFile>> deps = dependencyCache.findDependentClasses(context, context.getProject(), compiledWithErrors);
+    final Pair<int[], Set<VirtualFile>> filteredDeps = filter != null? filter.fun(deps) : deps;
+
+    final Set<VirtualFile> dependentFiles = new HashSet<VirtualFile>();
+    final CacheCorruptedException[] _ex = {null};
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(context.getProject());
+          SourceFileFinder sourceFileFinder = new SourceFileFinder(context.getProject(), context);
+          final Cache cache = dependencyCache.getCache();
+          for (final int infoQName : filteredDeps.getFirst()) {
+            final String qualifiedName = dependencyCache.resolve(infoQName);
+            final String sourceFileName = cache.getSourceFileName(infoQName);
+            final VirtualFile file = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName, true);
+            if (file != null) {
+              dependentFiles.add(file);
+              if (ApplicationManager.getApplication().isUnitTestMode()) {
+                LOG.assertTrue(file.isValid());
+                CompilerManagerImpl.addRecompiledPath(file.getPath());
+              }
+            }
+            else {
+              LOG.info("No source file for " + dependencyCache.resolve(infoQName) + " found; source file name=" + sourceFileName);
+            }
+          }
+          for (final VirtualFile file : filteredDeps.getSecond()) {
+            if (!compilerConfiguration.isExcludedFromCompilation(file)) {
+              dependentFiles.add(file);
+              if (ApplicationManager.getApplication().isUnitTestMode()) {
+                LOG.assertTrue(file.isValid());
+                CompilerManagerImpl.addRecompiledPath(file.getPath());
+              }
+            }
+          }
+        }
+        catch (CacheCorruptedException e) {
+          _ex[0] = e;
+        }
+      }
+    });
+    if (_ex[0] != null) {
+      throw _ex[0];
+    }
+    context.getProgressIndicator().setText(
+      dependentFiles.size() > 0? CompilerBundle.message("progress.found.dependent.files", dependentFiles.size()) : ""
+    );
+
+    return dependentFiles;
+  }
+
+  @NotNull
+  public static Set<VirtualFile> getFilesCompiledWithErrors(final CompileContextEx context) {
+    CompilerMessage[] messages = context.getMessages(CompilerMessageCategory.ERROR);
+    Set<VirtualFile> compiledWithErrors = Collections.emptySet();
+    if (messages.length > 0) {
+      compiledWithErrors = new HashSet<VirtualFile>(messages.length);
+      for (CompilerMessage message : messages) {
+        final VirtualFile file = message.getVirtualFile();
+        if (file != null) {
+          compiledWithErrors.add(file);
+        }
+      }
+    }
+    return compiledWithErrors;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CachedPersistentHashMap.java b/java/compiler/impl/src/com/intellij/compiler/make/CachedPersistentHashMap.java
new file mode 100644
index 0000000..b8b45cb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CachedPersistentHashMap.java
@@ -0,0 +1,115 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.containers.SLRUMap;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 1, 2008
+ */
+public class CachedPersistentHashMap<Key, Value> extends PersistentHashMap<Key, Value> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CachedPersistentHashMap");
+  protected final SLRUMap<Key, Value> myCache;
+
+  public CachedPersistentHashMap(File file, KeyDescriptor<Key> keyDescriptor, DataExternalizer<Value> valDescriptor, final int cacheSize) throws IOException {
+    super(file, keyDescriptor, valDescriptor);
+    myCache = new SLRUMap<Key,Value>(cacheSize * 2, cacheSize) {
+      protected void onDropFromCache(Key key, Value value) {
+        if (isValueDirty(value)) {
+          try {
+            CachedPersistentHashMap.super.put(key, value);
+          }
+          catch (IOException e) {
+            LOG.info(e);
+          }
+        }
+      }
+    };
+  }
+
+  protected boolean isValueDirty(Value value) {
+    return false;
+  }
+
+  @Override
+  protected void doPut(Key key, Value value) throws IOException {
+    myCache.remove(key);
+    super.doPut(key, value);
+  }
+
+  @Override
+  protected void doAppendData(Key key, ValueDataAppender appender) throws IOException {
+    myCache.remove(key);
+    super.doAppendData(key, appender);
+  }
+
+  @Nullable
+  protected Value doGet(Key key) throws IOException {
+    Value value = myCache.get(key);
+    if (value == null) {
+      value = super.doGet(key);
+      if (value != null) {
+        myCache.put(key, value);
+      }
+    }
+    return value;
+  }
+
+  @Override
+  protected boolean doContainsMapping(Key key) throws IOException {
+    final Value value = myCache.get(key);
+    return value != null || super.doContainsMapping(key);
+  }
+
+  @Override
+  protected void doRemove(Key key) throws IOException {
+    myCache.remove(key);
+    super.doRemove(key);
+  }
+
+  @Override
+  protected void doForce() {
+    try {
+      clearCache();
+    }
+    finally {
+      super.doForce();
+    }
+  }
+
+  @Override
+  protected void doClose() throws IOException {
+    try {
+      clearCache();
+    }
+    finally {
+      super.doClose();
+    }
+  }
+
+  private void clearCache() {
+    myCache.clear();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CachingSearcher.java b/java/compiler/impl/src/com/intellij/compiler/make/CachingSearcher.java
new file mode 100644
index 0000000..8ac89b3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CachingSearcher.java
@@ -0,0 +1,57 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.util.Query;
+import com.intellij.util.containers.SoftHashMap;
+
+import java.util.Collection;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 15
+ * @author 2003
+ */
+public class CachingSearcher {
+  private final Project myProject;
+  private final Map<Pair<PsiElement, Boolean>, Collection<PsiReference>> myElementToReferencersMap = new SoftHashMap<Pair<PsiElement, Boolean>, Collection<PsiReference>>();
+
+  public CachingSearcher(Project project) {
+    myProject = project;
+  }
+
+  public Collection<PsiReference> findReferences(PsiElement element, final boolean ignoreAccessScope) {
+    final Pair<PsiElement, Boolean> key = new Pair<PsiElement, Boolean>(element, ignoreAccessScope? Boolean.TRUE : Boolean.FALSE);
+    Collection<PsiReference> psiReferences = myElementToReferencersMap.get(key);
+    if (psiReferences == null) {
+      GlobalSearchScope searchScope = GlobalSearchScope.projectScope(myProject);
+      searchScope = GlobalSearchScope.getScopeRestrictedByFileTypes(searchScope, StdFileTypes.JAVA);
+      final Query<PsiReference> query = ReferencesSearch.search(element, searchScope, ignoreAccessScope);
+      psiReferences = query.findAll();
+      myElementToReferencersMap.put(key, psiReferences);
+    }
+    return psiReferences;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ChangeDescription.java b/java/compiler/impl/src/com/intellij/compiler/make/ChangeDescription.java
new file mode 100644
index 0000000..1f5f8a3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ChangeDescription.java
@@ -0,0 +1,24 @@
+/*
+ * 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.compiler.make;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 7, 2004
+ */
+abstract class ChangeDescription {
+  public abstract boolean isChanged();
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
new file mode 100644
index 0000000..bd919a6
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
@@ -0,0 +1,373 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Feb 24, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.compiler.classParsing.FieldInfo;
+import com.intellij.compiler.impl.ExitException;
+import com.intellij.compiler.impl.ExitStatus;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.*;
+import com.intellij.psi.util.PsiUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+public class ChangedConstantsDependencyProcessor {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor");
+  private final Project myProject;
+  private final CachingSearcher mySearcher;
+  private final DependencyCache myDependencyCache;
+  private final int myQName;
+  private final CompileContext myContext;
+  private final FieldChangeInfo[] myChangedFields;
+  private final FieldChangeInfo[] myRemovedFields;
+  private final int MAX_CONSTANT_SEARCHES = Registry.intValue("compiler.max.static.constants.searches");
+
+
+  public ChangedConstantsDependencyProcessor(Project project,
+                                             CachingSearcher searcher,
+                                             DependencyCache dependencyCache,
+                                             int qName, CompileContext context, FieldChangeInfo[] changedFields,
+                                             FieldChangeInfo[] removedFields) {
+    myProject = project;
+    mySearcher = searcher;
+    myDependencyCache = dependencyCache;
+    myQName = qName;
+    myContext = context;
+    myChangedFields = changedFields;
+    myRemovedFields = removedFields;
+  }
+
+  public void run() throws CacheCorruptedException, ExitException {
+    final Ref<CacheCorruptedException> _ex = new Ref<CacheCorruptedException>();
+    final Ref<ExitException> exitException = new Ref<ExitException>(null);
+    DumbService.getInstance(myProject).waitForSmartMode(); // ensure running in smart mode
+
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          final String qName = myDependencyCache.resolve(myQName);
+          PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject));
+          for (PsiClass aClass : classes) {
+            PsiField[] psiFields = aClass.getFields();
+            for (PsiField psiField : psiFields) {
+              final FieldChangeInfo changeInfo = findChangeInfo(psiField);
+              if (changeInfo != null) { // this field has been changed
+                processFieldChanged(psiField, aClass, changeInfo.isAccessibilityChange);
+              }
+            }
+            for (FieldChangeInfo removedField : myRemovedFields) {
+              processFieldRemoved(removedField.fieldInfo, aClass);
+            }
+          }
+        }
+        catch (CacheCorruptedException e) {
+          _ex.set(e);
+        }
+        catch (ExitException e) {
+          exitException.set(e);
+        }
+        catch (ProcessCanceledException e) {
+          // supressed deliberately
+        }
+      }
+    });
+    if (_ex.get() != null) {
+      throw _ex.get();
+    }
+    if (exitException.get() != null) {
+      throw exitException.get();
+    }
+  }
+
+  private void processFieldRemoved(FieldInfo info, final PsiClass aClass) throws CacheCorruptedException {
+    if (info.isPrivate()) {
+      return; // optimization: don't need to search, cause may be used only in this class
+    }
+    SearchScope searchScope = GlobalSearchScope.projectScope(myProject);
+    if (info.isPackageLocal()) {
+      final PsiFile containingFile = aClass.getContainingFile();
+      if (containingFile instanceof PsiJavaFile) {
+        final String packageName = ((PsiJavaFile)containingFile).getPackageName();
+        final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(packageName);
+        if (aPackage != null) {
+          searchScope = PackageScope.packageScope(aPackage, false);
+          searchScope = searchScope.intersectWith(aClass.getUseScope());
+        }
+      }
+    }
+    final PsiSearchHelper psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(myProject);
+
+    final Ref<CacheCorruptedException> exRef = new Ref<CacheCorruptedException>(null);
+    processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() {
+      @Override
+      public synchronized boolean execute(@NotNull PsiIdentifier identifier) {
+        try {
+          final PsiElement parent = identifier.getParent();
+          if (parent instanceof PsiReferenceExpression) {
+            final PsiClass ownerClass = getOwnerClass(parent);
+            if (ownerClass != null && !ownerClass.equals(aClass)) {
+              final String _qName = ownerClass.getQualifiedName();
+              if (_qName != null) {
+                int qualifiedName = myDependencyCache.getSymbolTable().getId(_qName);
+                // should force marking of the class no matter was it compiled or not
+                // This will ensure the class was recompiled _after_ all the constants get their new values
+                if (myDependencyCache.markClass(qualifiedName, true)) {
+                  if (LOG.isDebugEnabled()) {
+                    LOG.debug("Mark dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: some constants were removed from " + myDependencyCache.resolve(myQName));
+                  }
+                }
+              }
+              else {
+                LOG.warn("Class with null qualified name was not expected here: " + ownerClass);
+              }
+            }
+          }
+          return true;
+        }
+        catch (CacheCorruptedException e) {
+          exRef.set(e);
+          return false;
+        }
+      }
+    }, myDependencyCache.resolve(info.getName()), searchScope, UsageSearchContext.IN_CODE);
+    
+    final CacheCorruptedException cacheCorruptedException = exRef.get();
+    if (cacheCorruptedException != null) {
+      throw cacheCorruptedException;
+    }
+  }
+
+  private static boolean processIdentifiers(PsiSearchHelper helper,
+                                            @NotNull final PsiElementProcessor<PsiIdentifier> processor,
+                                            @NotNull final String identifier,
+                                            @NotNull SearchScope searchScope,
+                                            short searchContext) {
+    TextOccurenceProcessor processor1 = new TextOccurenceProcessor() {
+      public boolean execute(PsiElement element, int offsetInElement) {
+        return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element);
+      }
+    };
+    return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true);
+  }
+
+  private void processFieldChanged(PsiField field, PsiClass aClass, final boolean isAccessibilityChange)
+    throws CacheCorruptedException, ExitException {
+    if (!isAccessibilityChange && field.hasModifierProperty(PsiModifier.PRIVATE)) {
+      return; // optimization: don't need to search, cause may be used only in this class
+    }
+    Set<PsiElement> usages = new HashSet<PsiElement>();
+    addUsages(field, usages, isAccessibilityChange);
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("++++++++++++++++++++++++++++++++++++++++++++++++");
+      LOG.debug("Processing changed field: " + aClass.getQualifiedName() + "." + field.getName());
+    }
+    for (final PsiElement usage : usages) {
+      PsiClass ownerClass = getOwnerClass(usage);
+      if (LOG.isDebugEnabled()) {
+        if (ownerClass != null) {
+          LOG.debug("Usage " + usage + " found in class: " + ownerClass.getQualifiedName());
+        }
+        else {
+          LOG.debug("Usage " + usage + " found in class: null");
+        }
+      }
+      if (ownerClass != null && !ownerClass.equals(aClass)) {
+        int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName());
+        // should force marking of the class no matter was it compiled or not
+        // This will ensure the class was recompiled _after_ all the constants get their new values
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Marking class id = [" + qualifiedName + "], name=[" + myDependencyCache.resolve(qualifiedName) + "]");
+        }
+        if (myDependencyCache.markClass(qualifiedName, true)) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Marked dependent class " + myDependencyCache.resolve(qualifiedName) + "; reason: constants changed in " +
+                        myDependencyCache.resolve(myQName));
+          }
+        }
+      }
+      else if (ownerClass == null) {
+        final PsiFile containingFile = usage.getContainingFile();
+        if (containingFile != null) {
+          final VirtualFile file = containingFile.getVirtualFile();
+          if (file != null) {
+            myDependencyCache.markFile(file);
+          }
+        }
+      }
+    }
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("+++++++++++++++++++++++++++++++++++++++++++++++");
+    }
+  }
+
+  private void addUsages(PsiField psiField, Collection<PsiElement> usages, final boolean ignoreAccessScope) throws ExitException {
+    final int count = getConstantSearchesCount();
+    if (count > MAX_CONSTANT_SEARCHES) {
+      myContext.requestRebuildNextTime("Too many changed compile-time constants, project rebuild scheduled");
+      throw new ExitException(ExitStatus.CANCELLED);
+    }
+    Collection<PsiReference> references = mySearcher.findReferences(psiField, ignoreAccessScope)/*doFindReferences(searchHelper, psiField)*/;
+
+    incConstantSearchesCount();
+
+    for (final PsiReference ref : references) {
+      if (!(ref instanceof PsiReferenceExpression)) {
+        continue;
+      }
+      PsiElement e = ref.getElement();
+      usages.add(e);
+      PsiField ownerField = getOwnerField(e);
+      if (ownerField != null) {
+        if (ownerField.hasModifierProperty(PsiModifier.FINAL)) {
+          PsiExpression initializer = ownerField.getInitializer();
+          if (initializer != null && PsiUtil.isConstantExpression(initializer)) {
+            // if the field depends on the compile-time-constant expression and is itself final
+            addUsages(ownerField, usages, ignoreAccessScope);
+          }
+        }
+      }
+    }
+  }
+
+  /*
+  private PsiReference[] doFindReferences(final PsiSearchHelper searchHelper, final PsiField psiField) {
+    final ProgressManager progressManager = ProgressManager.getInstance();
+    final ProgressIndicator currentProgress = progressManager.getProgressIndicator();
+    final PsiReference[][] references = new PsiReference[][] {null};
+    progressManager.runProcess(new Runnable() {
+      public void run() {
+        references[0] = searchHelper.findReferences(psiField, GlobalSearchScope.projectScope(myProject), false);
+        if (ENABLE_TRACING) {
+          System.out.println("Finding referencers for " + psiField);
+        }
+      }
+    }, new NonCancellableProgressAdapter(currentProgress));
+    return references[0];
+  }
+  */
+
+  @Nullable
+  private static PsiField getOwnerField(PsiElement element) {
+    while (!(element instanceof PsiFile)) {
+      if (element instanceof PsiClass) {
+        break;
+      }
+      if (element instanceof PsiField) { // top-level class
+        return (PsiField)element;
+      }
+      element = element.getParent();
+    }
+    return null;
+  }
+
+  @Nullable
+  private FieldChangeInfo findChangeInfo(PsiField field) throws CacheCorruptedException {
+    String name = field.getName();
+    for (final FieldChangeInfo changeInfo : myChangedFields) {
+      if (name.equals(myDependencyCache.resolve(changeInfo.fieldInfo.getName()))) {
+        return changeInfo;
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  private static PsiClass getOwnerClass(PsiElement element) {
+    while (!(element instanceof PsiFile)) {
+      if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class
+        final PsiClass psiClass = (PsiClass)element;
+        if (JspPsiUtil.isInJspFile(psiClass)) {
+          return null;
+        }
+        final PsiFile containingFile = psiClass.getContainingFile();
+        if (containingFile == null) {
+          return null;
+        }
+        return StdLanguages.JAVA.equals(containingFile.getLanguage())? psiClass : null;
+      }
+      element = element.getParent();
+    }
+    return null;
+  }
+
+  public static class FieldChangeInfo {
+    final FieldInfo fieldInfo;
+    final boolean isAccessibilityChange;
+
+    public FieldChangeInfo(final FieldInfo fieldId) {
+      this(fieldId, false);
+    }
+
+    public FieldChangeInfo(final FieldInfo fieldInfo, final boolean accessibilityChange) {
+      this.fieldInfo = fieldInfo;
+      isAccessibilityChange = accessibilityChange;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      final FieldChangeInfo fieldChangeInfo = (FieldChangeInfo)o;
+
+      if (isAccessibilityChange != fieldChangeInfo.isAccessibilityChange) return false;
+      if (!fieldInfo.equals(fieldChangeInfo.fieldInfo)) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      int result;
+      result = fieldInfo.hashCode();
+      result = 29 * result + (isAccessibilityChange ? 1 : 0);
+      return result;
+    }
+  }
+
+  private static final Key<Integer> CONSTANTS_COUNTER = Key.create("_constant_searches_counter_");
+
+  private int getConstantSearchesCount() {
+    return getConstantSearchesCount(myContext);
+  }
+
+  public static int getConstantSearchesCount(CompileContext context) {
+    final Integer value = CONSTANTS_COUNTER.get(context);
+    return value != null? value.intValue() : 0;
+  }
+
+  private void incConstantSearchesCount() {
+    CONSTANTS_COUNTER.set(myContext, getConstantSearchesCount() + 1);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java
new file mode 100644
index 0000000..314fce9
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ChangedRetentionPolicyDependencyProcessor.java
@@ -0,0 +1,107 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.cls.ClsUtil;
+
+import java.util.Collection;
+
+public class ChangedRetentionPolicyDependencyProcessor {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.ChangedConstantsDependencyProcessor");
+  private final Project myProject;
+  private final CachingSearcher mySearcher;
+  private final DependencyCache myDependencyCache;
+
+  public ChangedRetentionPolicyDependencyProcessor(Project project, CachingSearcher searcher, DependencyCache dependencyCache) {
+    myProject = project;
+    mySearcher = searcher;
+    myDependencyCache = dependencyCache;
+  }
+
+  public void checkAnnotationRetentionPolicyChanges(final int annotationQName) throws CacheCorruptedException {
+    final Cache oldCache = myDependencyCache.getCache();
+    if (!ClsUtil.isAnnotation(oldCache.getFlags(annotationQName))) {
+      return;
+    }
+    if (!hasRetentionPolicyChanged(annotationQName, oldCache, myDependencyCache.getNewClassesCache(), myDependencyCache.getSymbolTable())) {
+      return;
+    }
+    final CacheCorruptedException[] _ex = new CacheCorruptedException[] {null};
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        try {
+          final String qName = myDependencyCache.resolve(annotationQName);
+          PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qName.replace('$', '.'), GlobalSearchScope.allScope(myProject));
+          for (final PsiClass aClass : classes) {
+            if (!aClass.isAnnotationType()) {
+              continue;
+            }
+            final Collection<PsiReference> references = mySearcher.findReferences(aClass, true);
+            for (PsiReference reference : references) {
+              final PsiClass ownerClass = getOwnerClass(reference.getElement());
+              if (ownerClass != null && !ownerClass.equals(aClass)) {
+                int qualifiedName = myDependencyCache.getSymbolTable().getId(ownerClass.getQualifiedName());
+                if (myDependencyCache.markClass(qualifiedName, false)) {
+                  if (LOG.isDebugEnabled()) {
+                    LOG.debug("Marked dependent class " + myDependencyCache.resolve(qualifiedName) +
+                              "; reason: annotation's retention policy changed from SOURCE to CLASS or RUNTIME " +
+                              myDependencyCache.resolve(annotationQName));
+                  }
+                }
+              }
+            }
+          }
+        }
+        catch (CacheCorruptedException e) {
+         _ex[0] = e;
+        }
+        catch (ProcessCanceledException e) {
+          // supressed deliberately
+        }
+      }
+    });
+    if (_ex[0] != null) {
+      throw _ex[0];
+    }
+  }
+
+  private boolean hasRetentionPolicyChanged(int annotationQName, final Cache oldCache, final Cache newCache, SymbolTable symbolTable) throws CacheCorruptedException {
+    // if retention policy changed from SOURCE to CLASS or RUNTIME, all sources should be recompiled to propagate changes
+    final int oldPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, oldCache, symbolTable);
+    final int newPolicy = MakeUtil.getAnnotationRetentionPolicy(annotationQName, newCache, symbolTable);
+    if ((oldPolicy == RetentionPolicies.SOURCE) && (newPolicy == RetentionPolicies.CLASS || newPolicy == RetentionPolicies.RUNTIME)) {
+      return true;
+    }
+    return false;
+  }
+
+  private static PsiClass getOwnerClass(PsiElement element) {
+    while (!(element instanceof PsiFile)) {
+      if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class
+        return (PsiClass)element;
+      }
+      element = element.getParent();
+    }
+    return null;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ClassInfoProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/ClassInfoProcessor.java
new file mode 100644
index 0000000..5298a8c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ClassInfoProcessor.java
@@ -0,0 +1,32 @@
+/*
+ * 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: May 14, 2003
+ * Time: 10:42:29 AM
+ */
+package com.intellij.compiler.make;
+
+
+
+public interface ClassInfoProcessor {
+  /**
+   * @param classQName of a class info to be processed
+   * @return true if superclasses of info should be processed and false otherwise
+   */
+  boolean process(int classQName) throws CacheCorruptedException;
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java
new file mode 100644
index 0000000..ea93f21
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/CompilerDependencyStorage.java
@@ -0,0 +1,257 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Ref;
+import com.intellij.util.containers.SLRUCache;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import com.intellij.util.io.PersistentHashMap;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TIntProcedure;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Dec 1, 2008
+ */
+public class CompilerDependencyStorage<Key> implements Flushable, Disposable {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.CompilerDependencyStorage");
+  protected final PersistentHashMap<Key, int[]> myMap;
+  protected final SLRUCache<Key, IntSet> myCache;
+  private Key myKeyToRemove;
+
+  public CompilerDependencyStorage(File file, KeyDescriptor<Key> keyDescriptor, final int cacheSize) throws IOException {
+    myMap = new PersistentHashMap<Key, int[]>(file, keyDescriptor, new DataExternalizer<int[]>() {
+      public void save(DataOutput out, int[] array) throws IOException {
+        out.writeInt(array.length);
+        for (int value : array) {
+          out.writeInt(value);
+        }
+      }
+
+      public int[] read(DataInput in) throws IOException {
+        final TIntHashSet set = new TIntHashSet();
+        DataInputStream stream = (DataInputStream)in;
+        while(stream.available() > 0) {
+          final int size = stream.readInt();
+          final int _size = Math.abs(size);
+          for (int idx = 0; idx < _size; idx++) {
+            if (size > 0) {
+              set.add(stream.readInt());
+            }
+            else {
+              set.remove(stream.readInt());
+            }
+          }
+        }
+        return set.toArray();
+      }
+    });
+
+    myCache = new SLRUCache<Key, IntSet>(cacheSize * 2, cacheSize) {
+      @NotNull
+      public IntSet createValue(Key key) {
+        return new IntSet(key);
+      }
+
+      protected void onDropFromCache(Key key, final IntSet set) {
+        if (key == myKeyToRemove || !set.isDirty()) {
+          return;
+        }
+        try {
+          if (set.needsCompacting()) {
+            myMap.put(key, set.getValues());
+          }
+          else {
+            myMap.appendData(key, new PersistentHashMap.ValueDataAppender() {
+              public void append(final DataOutput out) throws IOException {
+                final Ref<IOException> exception = new Ref<IOException>(null);
+                final TIntProcedure saveProc = new TIntProcedure() {
+                  public boolean execute(int value) {
+                    try {
+                      out.writeInt(value);
+                      return true;
+                    }
+                    catch (IOException e) {
+                      exception.set(e);
+                      return false;
+                    }
+                  }
+                };
+
+                out.writeInt(-set.getRemovedCount());
+                set.processRemovedValues(saveProc);
+                if (exception.get() != null) {
+                  throw exception.get();
+                }
+
+                out.writeInt(set.getAddedCount());
+                set.processAddedValues(saveProc);
+                if (exception.get() != null) {
+                  throw exception.get();
+                }
+              }
+            });
+          }
+        }
+        catch (IOException e) {
+          LOG.error(e);
+        }
+      }
+    };
+  }
+
+  public synchronized void remove(Key key) throws IOException {
+    myKeyToRemove = key;
+    try {
+      myCache.remove(key);
+    }
+    finally {
+      myKeyToRemove = null;
+    }
+    myMap.remove(key);
+  }
+
+  public synchronized void removeValue(Key key, int value) throws IOException {
+    final IntSet set = myCache.get(key);
+    set.remove(value);
+    if (set.needsFlushing()) {
+      flush(key);
+    }
+  }
+
+
+  public synchronized void addValue(Key key, int value) throws IOException {
+    final IntSet set = myCache.get(key);
+    set.add(value);
+    if (set.needsFlushing()) {
+      flush(key);
+    }
+  }
+
+  public synchronized int[] getValues(Key key) throws IOException {
+    return myCache.get(key).getValues();
+  }
+
+
+  public synchronized void flush() throws IOException {
+    myCache.clear();
+    myMap.force();
+  }
+
+  private void flush(Key key) {
+    myCache.remove(key); // makes changes into PersistentHashMap
+    myMap.force(); // flushes internal caches (which consume memory) and writes unsaved data to disk
+  }
+
+  public synchronized void dispose() {
+    try {
+      flush();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    try {
+      myMap.close();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+  }
+
+  private class IntSet {
+    private final TIntHashSet myAdded = new TIntHashSet();
+    private final TIntHashSet myRemoved = new TIntHashSet();
+    private TIntHashSet myMerged = null;
+    private final Key myKey;
+
+    public IntSet(Key key) {
+      myKey = key;
+    }
+
+    public void add(int value) {
+      if (myMerged != null) {
+        myMerged.add(value);
+      }
+      if (!myRemoved.remove(value)) {
+        myAdded.add(value);
+      }
+    }
+
+    public void remove(int value) {
+      if (myMerged != null) {
+        myMerged.remove(value);
+      }
+      if (!myAdded.remove(value)) {
+        myRemoved.add(value);
+      }
+    }
+
+    public boolean isDirty() {
+      return myAdded.size() > 0 || myRemoved.size() > 0;
+    }
+
+    public boolean needsCompacting() {
+      return myMerged != null;
+    }
+
+    public boolean needsFlushing() {
+      return myAdded.size() > 3000 || myRemoved.size() > 3000;
+    }
+
+    public int getAddedCount() {
+      return myAdded.size();
+    }
+
+    public void processAddedValues(final TIntProcedure procedure) {
+      myAdded.forEach(procedure);
+    }
+
+    public int getRemovedCount() {
+      return myRemoved.size();
+    }
+
+    public void processRemovedValues(final TIntProcedure procedure) {
+      myRemoved.forEach(procedure);
+    }
+
+    public int[] getValues() throws IOException {
+      return getMerged().toArray();
+    }
+
+    private TIntHashSet getMerged() throws IOException {
+      if (myMerged == null) {
+        myMerged = new TIntHashSet();
+        final int[] fromDisk = myMap.get(myKey);
+        if (fromDisk != null) {
+          myMerged.addAll(fromDisk);
+        }
+        if (myRemoved.size() > 0) {
+          myMerged.removeAll(myRemoved.toArray());
+        }
+        if (myAdded.size() > 0) {
+          myMerged.addAll(myAdded.toArray());
+        }
+      }
+      return myMerged;
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java b/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java
new file mode 100644
index 0000000..bd2c5cf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/Dependency.java
@@ -0,0 +1,188 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 4, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.*;
+
+public class Dependency {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.Dependency");
+  public static final Dependency[] EMPTY_ARRAY = new Dependency[0];
+  private final int myClassQualifiedName;
+  private Set<FieldRef> myUsedFields;
+  private Set<MethodRef> myUsedMethods;
+
+  public static class FieldRef {
+    public final int name;
+
+    public FieldRef(int name) {
+      this.name = name;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      FieldRef fieldRef = (FieldRef)o;
+
+      if (name != fieldRef.name) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      return name;
+    }
+  }
+
+  public static class MethodRef {
+    public final int name;
+    public final int descriptor;
+    private String[] myParameterDescriptors;
+
+    public MethodRef(int name, int descriptor) {
+      this.name = name;
+      this.descriptor = descriptor;
+    }
+
+    public boolean equals(Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      MethodRef methodRef = (MethodRef)o;
+
+      if (descriptor != methodRef.descriptor) return false;
+      if (name != methodRef.name) return false;
+
+      return true;
+    }
+
+    public int hashCode() {
+      int result = name;
+      result = 31 * result + descriptor;
+      return result;
+    }
+
+    public String getDescriptor(SymbolTable symbolTable) throws CacheCorruptedException {
+      final String descriptorStr = symbolTable.getSymbol(descriptor);
+      final String nameStr = symbolTable.getSymbol(name);
+      return CacheUtils.getMethodSignature(nameStr, descriptorStr);
+    }
+
+
+    public String[] getParameterDescriptors(SymbolTable symbolTable) throws CacheCorruptedException {
+      if (myParameterDescriptors == null) {
+        String descriptorStr = symbolTable.getSymbol(descriptor);
+        int endIndex = descriptorStr.indexOf(')');
+        if (endIndex <= 0) {
+          LOG.error("Corrupted method descriptor: " + descriptorStr);
+        }
+        myParameterDescriptors = parseParameterDescriptors(descriptorStr.substring(1, endIndex));
+      }
+      return myParameterDescriptors;
+    }
+  }
+
+  public Dependency(int classQualifiedName) {
+    myClassQualifiedName = classQualifiedName;
+  }
+
+  public int getClassQualifiedName() {
+    return myClassQualifiedName;
+  }
+
+  public void addMethod(int name, int descriptor) {
+    if (myUsedMethods == null) {
+      myUsedMethods = new HashSet<MethodRef>();
+    }
+    myUsedMethods.add(new MethodRef(name, descriptor));
+  }
+
+  public void addField(int name) {
+    if (myUsedFields == null) {
+      myUsedFields = new HashSet<FieldRef>();
+    }
+    myUsedFields.add(new FieldRef(name));
+  }
+
+  public Collection<FieldRef> getFieldRefs() {
+    return myUsedFields != null? Collections.unmodifiableSet(myUsedFields) : Collections.<FieldRef>emptySet();
+  }
+
+  public Collection<MethodRef> getMethodRefs() {
+    return myUsedMethods != null? Collections.unmodifiableSet(myUsedMethods) : Collections.<MethodRef>emptySet();
+  }
+
+  private static String[] parseParameterDescriptors(String signature) {
+    ArrayList<String> list = new ArrayList<String>();
+    String paramSignature = parseFieldType(signature);
+    while (paramSignature != null && !paramSignature.isEmpty()) {
+      list.add(paramSignature);
+      signature = signature.substring(paramSignature.length());
+      paramSignature = parseFieldType(signature);
+    }
+    return ArrayUtil.toStringArray(list);
+  }
+
+  private static String parseFieldType(@NonNls String signature) {
+    if (signature.isEmpty()) {
+      return null;
+    }
+    char first = signature.charAt(0);
+    if (first == 'I') {
+      return "I";
+    }
+    if (first == 'L') {
+      return signature.substring(0, signature.indexOf(';') + 1);
+    }
+    if (first == 'B') {
+      return "B";
+    }
+    if (first == 'C') {
+      return "C";
+    }
+    if (first == 'D') {
+      return "D";
+    }
+    if (first == 'F') {
+      return "F";
+    }
+    if (first == 'J') {
+      return "J";
+    }
+    if (first == 'S') {
+      return "S";
+    }
+    if (first == 'Z') {
+      return "Z";
+    }
+    if (first == '[') {
+      String s = parseFieldType(signature.substring(1));
+      return s == null ? null : "[" + s;
+    }
+    return null;
+  }
+
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java
new file mode 100644
index 0000000..92f3285
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCache.java
@@ -0,0 +1,659 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 7, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.compiler.DependencyProcessor;
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.*;
+import com.intellij.compiler.impl.ExitException;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.cls.ClsUtil;
+import gnu.trove.TIntHashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.rmi.Remote;
+import java.util.*;
+
+public class DependencyCache {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.DependencyCache");
+
+  private volatile Cache myCache;
+  private volatile Cache myNewClassesCache;
+
+  private static final String REMOTE_INTERFACE_NAME = Remote.class.getName();
+  private final TIntHashSet myToUpdate = new TIntHashSet(); // qName strings to be updated.
+  private final TIntHashSet myTraverseRoots = new TIntHashSet(); // Dependencies are calculated from these clasess
+  private final TIntHashSet myClassesWithSourceRemoved = new TIntHashSet();
+  private final TIntHashSet myPreviouslyRemoteClasses = new TIntHashSet(); // classes that were Remote, but became non-Remote for some reason
+  private final TIntHashSet myMarkedInfos = new TIntHashSet(); // classes to be recompiled
+  private final Set<VirtualFile> myMarkedFiles = new HashSet<VirtualFile>();
+  
+  private volatile DependencyCacheNavigator myCacheNavigator;
+  private volatile SymbolTable mySymbolTable;
+  private final String mySymbolTableFilePath;
+  private final String myStoreDirectoryPath;
+  @NonNls 
+  private static final String SYMBOLTABLE_FILE_NAME = "symboltable.dat";
+
+  public DependencyCache(@NonNls String storeDirectoryPath) {
+    myStoreDirectoryPath = storeDirectoryPath;
+    LOG.assertTrue(myStoreDirectoryPath != null);
+
+    mySymbolTableFilePath = myStoreDirectoryPath + "/" + SYMBOLTABLE_FILE_NAME;
+  }
+
+  public DependencyCacheNavigator getCacheNavigator() throws CacheCorruptedException {
+    if (myCacheNavigator == null) {
+      myCacheNavigator = new DependencyCacheNavigator(getCache());
+    }
+    return myCacheNavigator;
+  }
+
+  public void wipe() throws CacheCorruptedException {
+    getCache().wipe();
+    getNewClassesCache().wipe();
+  }
+
+  public Cache getCache() throws CacheCorruptedException {
+    try {
+      if (myCache == null) {
+        // base number of cached record views of each type
+        myCache = new Cache(myStoreDirectoryPath, 512);
+      }
+
+      return myCache;
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public Cache getNewClassesCache() throws CacheCorruptedException {
+    try {
+      if (myNewClassesCache == null) {
+        myNewClassesCache = new Cache(myStoreDirectoryPath + "/tmp", 16);
+      }
+      return myNewClassesCache;
+    }
+    catch (IOException e) {
+      throw new CacheCorruptedException(e);
+    }
+  }
+
+  public void addTraverseRoot(int qName) {
+    myTraverseRoots.add(qName);
+  }
+
+  public void clearTraverseRoots() {
+    myTraverseRoots.clear();
+  }
+
+  public boolean hasUnprocessedTraverseRoots() {
+    return !myTraverseRoots.isEmpty();
+  }
+
+  public void markSourceRemoved(int qName) {
+    myClassesWithSourceRemoved.add(qName);
+  }
+
+  public void addClassToUpdate(int qName) {
+    myToUpdate.add(qName);
+  }
+
+  public int reparseClassFile(@NotNull File file, final byte[] fileContent) throws ClsFormatException, CacheCorruptedException {
+    SymbolTable symbolTable = getSymbolTable();
+
+    final int qName = getNewClassesCache().importClassInfo(new ClassFileReader(file, symbolTable, fileContent), symbolTable);
+    addClassToUpdate(qName);
+    addTraverseRoot(qName);
+    return qName;
+  }
+
+  // for profiling purposes
+  /*
+  private static void pause() {
+    System.out.println("PAUSED. ENTER A CHAR.");
+    byte[] buf = new byte[1];
+    try {
+      System.in.read(buf);
+    }
+    catch (IOException e) {
+      e.printStackTrace();
+    }
+  }
+  */
+
+  public void update() throws CacheCorruptedException {
+    if (myToUpdate.isEmpty()) {
+      return; // optimization
+    }
+
+    //pause();
+
+    final int[] namesToUpdate = myToUpdate.toArray();
+    final Cache cache = getCache();
+    final Cache newCache = getNewClassesCache();
+    final DependencyCacheNavigator navigator = getCacheNavigator();
+
+    // remove unnecesary dependencies
+    for (final int qName : namesToUpdate) {
+      // process use-dependencies
+      for (int referencedClassQName : cache.getReferencedClasses(qName)) {
+        if (!cache.containsClass(referencedClassQName)) {
+          continue;
+        }
+        cache.removeClassReferencer(referencedClassQName, qName);
+      }
+      cache.clearReferencedClasses(qName);
+      // process inheritance dependencies
+      navigator.walkSuperClasses(qName, new ClassInfoProcessor() {
+        public boolean process(int classQName) throws CacheCorruptedException {
+          cache.removeSubclass(classQName, qName);
+          return true;
+        }
+      });
+    }
+
+    // do update of classInfos
+    for (final int qName : namesToUpdate) {
+      cache.importClassInfo(newCache, qName);
+    }
+
+    // build forward-dependencies for the new infos, all new class infos must be already in the main cache!
+
+    final SymbolTable symbolTable = getSymbolTable();
+
+    for (final int qName : namesToUpdate) {
+      if (!newCache.containsClass(qName)) {
+        continue;
+      }
+      buildForwardDependencies(qName, newCache.getReferences(qName));
+      boolean isRemote = false;
+      // "remote objects" are classes that _directly_ implement remote interfaces
+      final int[] superInterfaces = cache.getSuperInterfaces(qName);
+      if (superInterfaces.length > 0) {
+        final int remoteInterfaceName = symbolTable.getId(REMOTE_INTERFACE_NAME);
+        for (int superInterface : superInterfaces) {
+          if (isRemoteInterface(cache, superInterface, remoteInterfaceName)) {
+            isRemote = true;
+            break;
+          }
+        }
+      }
+      final boolean wasRemote = cache.isRemote(qName);
+      if (wasRemote && !isRemote) {
+        synchronized (myPreviouslyRemoteClasses) {
+          myPreviouslyRemoteClasses.add(qName);
+        }
+      }
+      cache.setRemote(qName, isRemote);
+    }
+
+    // building subclass dependencies
+    for (final int qName : namesToUpdate) {
+      buildSubclassDependencies(getCache(), qName, qName);
+    }
+
+    for (final int qName : myClassesWithSourceRemoved.toArray()) {
+      cache.removeClass(qName);
+    }
+    myToUpdate.clear();
+
+    //pause();
+  }
+
+  private void buildForwardDependencies(final int classQName, final Collection<ReferenceInfo> references) throws CacheCorruptedException {
+    final Cache cache = getCache();
+
+    final int genericSignature = cache.getGenericSignature(classQName);
+    if (genericSignature != -1) {
+      final String genericClassSignature = resolve(genericSignature);
+      final int[] bounds = findBounds(genericClassSignature);
+      for (int boundClassQName : bounds) {
+        cache.addClassReferencer(boundClassQName, classQName);
+      }
+    }
+
+    buildAnnotationDependencies(classQName, cache.getRuntimeVisibleAnnotations(classQName));
+    buildAnnotationDependencies(classQName, cache.getRuntimeInvisibleAnnotations(classQName));
+
+    for (final ReferenceInfo refInfo : references) {
+      final int declaringClassName = getActualDeclaringClassForReference(refInfo);
+      if (declaringClassName == Cache.UNKNOWN) {
+        continue;
+      }
+      if (refInfo instanceof MemberReferenceInfo) {
+        final MemberInfo memberInfo = ((MemberReferenceInfo)refInfo).getMemberInfo();
+        if (memberInfo instanceof FieldInfo) {
+          cache.addFieldReferencer(declaringClassName, memberInfo.getName(), classQName);
+        }
+        else if (memberInfo instanceof MethodInfo) {
+          cache.addMethodReferencer(declaringClassName, memberInfo.getName(), memberInfo.getDescriptor(), classQName);
+        }
+        else {
+          LOG.error("Unknown member info class: " + memberInfo.getClass().getName());
+        }
+      }
+      else { // reference to class
+        cache.addClassReferencer(declaringClassName, classQName);
+      }
+    }
+    final SymbolTable symbolTable = getSymbolTable();
+
+    for (final FieldInfo fieldInfo : cache.getFields(classQName)) {
+      buildAnnotationDependencies(classQName, fieldInfo.getRuntimeVisibleAnnotations());
+      buildAnnotationDependencies(classQName, fieldInfo.getRuntimeInvisibleAnnotations());
+
+      String className = MakeUtil.parseObjectType(symbolTable.getSymbol(fieldInfo.getDescriptor()), 0);
+      if (className == null) {
+        continue;
+      }
+      final int cls = symbolTable.getId(className);
+      cache.addClassReferencer(cls, classQName);
+    }
+
+    for (final MethodInfo methodInfo : cache.getMethods(classQName)) {
+      buildAnnotationDependencies(classQName, methodInfo.getRuntimeVisibleAnnotations());
+      buildAnnotationDependencies(classQName, methodInfo.getRuntimeInvisibleAnnotations());
+      buildAnnotationDependencies(classQName, methodInfo.getRuntimeVisibleParameterAnnotations());
+      buildAnnotationDependencies(classQName, methodInfo.getRuntimeInvisibleParameterAnnotations());
+
+      if (methodInfo.isConstructor()) {
+        continue;
+      }
+
+      final String returnTypeClassName = MakeUtil.parseObjectType(methodInfo.getReturnTypeDescriptor(symbolTable), 0);
+      if (returnTypeClassName != null) {
+        final int returnTypeClassQName = symbolTable.getId(returnTypeClassName);
+        cache.addClassReferencer(returnTypeClassQName, classQName);
+      }
+
+      String[] parameterSignatures = CacheUtils.getParameterSignatures(methodInfo, symbolTable);
+      for (String parameterSignature : parameterSignatures) {
+        String paramClassName = MakeUtil.parseObjectType(parameterSignature, 0);
+        if (paramClassName != null) {
+          final int paramClassId = symbolTable.getId(paramClassName);
+          cache.addClassReferencer(paramClassId, classQName);
+        }
+      }
+    }
+  }
+
+  private static boolean isRemoteInterface(Cache cache, int ifaceName, final int remoteInterfaceName) throws CacheCorruptedException {
+    if (ifaceName == remoteInterfaceName) {
+      return true;
+    }
+    for (int superInterfaceName : cache.getSuperInterfaces(ifaceName)) {
+      if (isRemoteInterface(cache, superInterfaceName, remoteInterfaceName)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  private void buildAnnotationDependencies(int classQName, AnnotationConstantValue[][] annotations) throws CacheCorruptedException {
+    if (annotations == null || annotations.length == 0) {
+      return;
+    }
+    for (AnnotationConstantValue[] annotation : annotations) {
+      buildAnnotationDependencies(classQName, annotation);
+    }
+  }
+
+  private void buildAnnotationDependencies(int classQName, AnnotationConstantValue[] annotations) throws CacheCorruptedException {
+    if (annotations == null || annotations.length == 0) {
+      return;
+    }
+    final Cache cache = getCache();
+    for (AnnotationConstantValue annotation : annotations) {
+      final int annotationQName = annotation.getAnnotationQName();
+
+      cache.addClassReferencer(annotationQName, classQName);
+
+      final AnnotationNameValuePair[] memberValues = annotation.getMemberValues();
+      for (final AnnotationNameValuePair nameValuePair : memberValues) {
+        for (MethodInfo annotationMember : cache.findMethodsByName(annotationQName, nameValuePair.getName())) {
+          cache.addMethodReferencer(annotationQName, annotationMember.getName(), annotationMember.getDescriptor(), classQName);
+        }
+      }
+    }
+  }
+
+  private int[] findBounds(final String genericClassSignature) throws CacheCorruptedException{
+    try {
+      final String[] boundInterfaces = BoundsParser.getBounds(genericClassSignature);
+      int[] ids = ArrayUtil.newIntArray(boundInterfaces.length);
+      for (int i = 0; i < boundInterfaces.length; i++) {
+        ids[i] = getSymbolTable().getId(boundInterfaces[i]);
+      }
+      return ids;
+    }
+    catch (SignatureParsingException e) {
+      return ArrayUtil.EMPTY_INT_ARRAY;
+    }
+  }
+
+  // fixes JDK 1.4 javac bug that generates references in the constant pool
+  // to the subclass even if the field was declared in a superclass
+  private int getActualDeclaringClassForReference(final ReferenceInfo refInfo) throws CacheCorruptedException {
+    if (!(refInfo instanceof MemberReferenceInfo)) {
+      return refInfo.getClassName();
+    }
+    final int declaringClassName = refInfo.getClassName();
+    final Cache cache = getCache();
+    final MemberInfo memberInfo = ((MemberReferenceInfo)refInfo).getMemberInfo();
+    if (memberInfo instanceof FieldInfo) {
+      if (cache.findFieldByName(declaringClassName, memberInfo.getName()) != null) {
+        return declaringClassName;
+      }
+    }
+    else if (memberInfo instanceof MethodInfo) {
+      if (cache.findMethod(declaringClassName, memberInfo.getName(), memberInfo.getDescriptor()) != null) {
+        return declaringClassName;
+      }
+    }
+    final DeclaringClassFinder finder = new DeclaringClassFinder(memberInfo);
+    getCacheNavigator().walkSuperClasses(declaringClassName, finder);
+    return finder.getDeclaringClassName();
+  }
+
+  /**
+   * @return qualified names of the classes that should be additionally recompiled
+   */
+  public Pair<int[], Set<VirtualFile>> findDependentClasses(CompileContext context, Project project, Set<VirtualFile> compiledWithErrors)
+    throws CacheCorruptedException, ExitException {
+
+    markDependencies(context, project, compiledWithErrors);
+    return new Pair<int[], Set<VirtualFile>>(myMarkedInfos.toArray(), Collections.unmodifiableSet(myMarkedFiles));
+  }
+
+  private void markDependencies(CompileContext context, Project project, final Set<VirtualFile> compiledWithErrors)
+    throws CacheCorruptedException, ExitException {
+    try {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("====================Marking dependent files=====================");
+      }
+      // myToUpdate can be modified during the mark procedure, so use toArray() to iterate it
+      final int[] traverseRoots = myTraverseRoots.toArray();
+      final SourceFileFinder sourceFileFinder = new SourceFileFinder(project, context);
+      final CachingSearcher searcher = new CachingSearcher(project);
+      final ChangedRetentionPolicyDependencyProcessor changedRetentionPolicyDependencyProcessor = new ChangedRetentionPolicyDependencyProcessor(project, searcher, this);
+      for (final int qName : traverseRoots) {
+        if (!getCache().containsClass(qName)) {
+          continue;
+        }
+        if (getNewClassesCache().containsClass(qName)) { // there is a new class file created
+          new JavaDependencyProcessor(project, this, qName).run();
+          ArrayList<ChangedConstantsDependencyProcessor.FieldChangeInfo> changed =
+            new ArrayList<ChangedConstantsDependencyProcessor.FieldChangeInfo>();
+          ArrayList<ChangedConstantsDependencyProcessor.FieldChangeInfo> removed =
+            new ArrayList<ChangedConstantsDependencyProcessor.FieldChangeInfo>();
+          findModifiedConstants(qName, changed, removed);
+          if (!changed.isEmpty() || !removed.isEmpty()) {
+            new ChangedConstantsDependencyProcessor(
+              project, searcher, this, qName, context,
+              changed.toArray(new ChangedConstantsDependencyProcessor.FieldChangeInfo[changed.size()]),
+              removed.toArray(new ChangedConstantsDependencyProcessor.FieldChangeInfo[removed.size()])
+            ).run();
+          }
+          changedRetentionPolicyDependencyProcessor.checkAnnotationRetentionPolicyChanges(qName);
+          for (DependencyProcessor additionalProcessor : DependencyProcessor.EXTENSION_POINT_NAME.getExtensions()) {
+            additionalProcessor.processDependencies(context, qName, searcher);
+          }
+        }
+        else {
+          boolean isSourceDeleted = false;
+          if (myClassesWithSourceRemoved.contains(qName)) { // no recompiled class file, check whether the classfile exists
+            isSourceDeleted = true;
+          }
+          else if (!new File(getCache().getPath(qName)).exists()) {
+            final String qualifiedName = resolve(qName);
+            final String sourceFileName = getCache().getSourceFileName(qName);
+            final boolean markAsRemovedSource = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+              public Boolean compute() {
+                VirtualFile sourceFile = sourceFileFinder.findSourceFile(qualifiedName, sourceFileName, false);
+                return sourceFile == null || !compiledWithErrors.contains(sourceFile) ? Boolean.TRUE : Boolean.FALSE;
+              }
+            }).booleanValue();
+            if (markAsRemovedSource) {
+              // for Inner classes: sourceFile may exist, but the inner class declaration inside it may not,
+              // thus the source for the class info should be considered removed
+              isSourceDeleted = true;
+              markSourceRemoved(qName);
+              myMarkedInfos.remove(qName); // if the info has been marked already, the mark should be removed
+            }
+          }
+          if (isSourceDeleted) {
+            Dependency[] backDependencies = getCache().getBackDependencies(qName);
+            for (Dependency backDependency : backDependencies) {
+              if (markTargetClassInfo(backDependency)) {
+                if (LOG.isDebugEnabled()) {
+                  LOG.debug(
+                    "Mark dependent class " + backDependency.getClassQualifiedName() + "; reason: no class file found for " + qName);
+                }
+              }
+            }
+          }
+        }
+      }
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("================================================================");
+      }
+    }
+    catch (ProcessCanceledException ignored) {
+      // deliberately suppressed
+    }
+  }
+
+  private void findModifiedConstants(
+    final int qName,
+    Collection<ChangedConstantsDependencyProcessor.FieldChangeInfo> changedConstants,
+    Collection<ChangedConstantsDependencyProcessor.FieldChangeInfo> removedConstants) throws CacheCorruptedException {
+
+    final Cache cache = getCache();
+    for (final FieldInfo field : cache.getFields(qName)) {
+      final int oldFlags = field.getFlags();
+      if (ClsUtil.isStatic(oldFlags) && ClsUtil.isFinal(oldFlags)) {
+        final Cache newClassesCache = getNewClassesCache();
+        FieldInfo newField = newClassesCache.findFieldByName(qName, field.getName());
+        if (newField == null) {
+          if (!ConstantValue.EMPTY_CONSTANT_VALUE.equals(field.getConstantValue())) {
+            // if the field was really compile time constant
+            removedConstants.add(new ChangedConstantsDependencyProcessor.FieldChangeInfo(field));
+          }
+        }
+        else {
+          final boolean visibilityRestricted = MakeUtil.isMoreAccessible(oldFlags, newField.getFlags());
+          if (!field.getConstantValue().equals(newField.getConstantValue()) || visibilityRestricted) {
+            changedConstants.add(new ChangedConstantsDependencyProcessor.FieldChangeInfo(field, visibilityRestricted));
+          }
+        }
+      }
+    }
+  }
+
+  private static void buildSubclassDependencies(Cache cache, final int qName, int targetClassId) throws CacheCorruptedException {
+    final int superQName = cache.getSuperQualifiedName(targetClassId);
+    if (superQName != Cache.UNKNOWN) {
+      cache.addSubclass(superQName, qName);
+      buildSubclassDependencies(cache, qName, superQName);
+    }
+
+    int[] interfaces = cache.getSuperInterfaces(targetClassId);
+    for (final int interfaceName : interfaces) {
+      cache.addSubclass(interfaceName, qName);
+      buildSubclassDependencies(cache, qName, interfaceName);
+    }
+  }
+
+
+  /**
+   * Marks ClassInfo targeted by the dependency
+   * @return true if really added, false otherwise
+   */
+  public boolean markTargetClassInfo(Dependency dependency) throws CacheCorruptedException {
+    return markClassInfo(dependency.getClassQualifiedName(), false);
+  }
+
+  /**
+   * Marks ClassInfo that corresponds to the specified qualified name
+   * If class info is already recompiled, it is not marked
+   * @return true if really added, false otherwise
+   */
+  public boolean markClass(int qualifiedName) throws CacheCorruptedException {
+    return markClass(qualifiedName, false);
+  }
+
+  /**
+   * Marks ClassInfo that corresponds to the specified qualified name
+   * If class info is already recompiled, it is not marked unless force parameter is true
+   * @return true if really added, false otherwise
+   */
+  public boolean markClass(int qualifiedName, boolean force) throws CacheCorruptedException {
+    return markClassInfo(qualifiedName, force);
+  }
+
+  public boolean isTargetClassInfoMarked(Dependency dependency) {
+    return isClassInfoMarked(dependency.getClassQualifiedName());
+  }
+
+  public boolean isClassInfoMarked(int qName) {
+    return myMarkedInfos.contains(qName);
+  }
+  
+  public void markFile(VirtualFile file) {
+    myMarkedFiles.add(file);
+  }
+
+  /**
+   * @return true if really marked, false otherwise
+   */
+  private boolean markClassInfo(int qName, boolean force) throws CacheCorruptedException {
+    if (!getCache().containsClass(qName)) {
+      return false;
+    }
+    if (myClassesWithSourceRemoved.contains(qName)) {
+      return false; // no need to recompile since source has been removed
+    }
+    if (!force) {
+      if (getNewClassesCache().containsClass(qName)) { // already recompiled
+        return false;
+      }
+    }
+    return myMarkedInfos.add(qName);
+  }
+
+  public void resetState() {
+    myClassesWithSourceRemoved.clear();
+    myMarkedFiles.clear();
+    myMarkedInfos.clear();
+    myToUpdate.clear();
+    myTraverseRoots.clear();
+    if (myNewClassesCache != null) {
+      myNewClassesCache.wipe();
+      myNewClassesCache = null;
+    }
+    myCacheNavigator = null;
+    try {
+      if (myCache != null) {
+        myCache.dispose();
+        myCache = null;
+      }
+    }
+    catch (CacheCorruptedException e) {
+      LOG.info(e);
+    }
+    try {
+      if (mySymbolTable != null) {
+        mySymbolTable.dispose();
+        mySymbolTable = null;
+      }
+    }
+    catch (CacheCorruptedException e) {
+      LOG.info(e);
+    }
+  }
+
+
+  public SymbolTable getSymbolTable() throws CacheCorruptedException {
+    if (mySymbolTable == null) {
+      mySymbolTable = new SymbolTable(new File(mySymbolTableFilePath));
+    }
+    return mySymbolTable;
+  }
+
+  public String resolve(int id) throws CacheCorruptedException {
+    return getSymbolTable().getSymbol(id);
+  }
+
+  public boolean wasRemote(int qName) {
+    return myPreviouslyRemoteClasses.contains(qName);
+  }
+
+  private class DeclaringClassFinder implements ClassInfoProcessor {
+    private final int myMemberName;
+    private final int myMemberDescriptor;
+    private int myDeclaringClass = Cache.UNKNOWN;
+    private final boolean myIsField;
+
+    private DeclaringClassFinder(MemberInfo memberInfo) {
+      myMemberName = memberInfo.getName();
+      myMemberDescriptor = memberInfo.getDescriptor();
+      myIsField = memberInfo instanceof FieldInfo;
+    }
+
+    public int getDeclaringClassName() {
+      return myDeclaringClass;
+    }
+
+    public boolean process(int classQName) throws CacheCorruptedException {
+      final Cache cache = getCache();
+      if (myIsField) {
+        final FieldInfo fieldId = cache.findField(classQName, myMemberName, myMemberDescriptor);
+        if (fieldId != null) {
+          myDeclaringClass = classQName;
+          return false;
+        }
+      }
+      else {
+        final MethodInfo methodId = cache.findMethod(classQName, myMemberName, myMemberDescriptor);
+        if (methodId != null) {
+          myDeclaringClass = classQName;
+          return false;
+        }
+      }
+      return true;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/DependencyCacheNavigator.java b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCacheNavigator.java
new file mode 100644
index 0000000..a93caa2
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/DependencyCacheNavigator.java
@@ -0,0 +1,84 @@
+/*
+ * 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: May 26, 2003
+ * Time: 8:13:56 PM
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.openapi.diagnostic.Logger;
+
+public class DependencyCacheNavigator {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.DependencyCacheNavigator");
+
+  private final Cache myCache;
+
+  public DependencyCacheNavigator(Cache cache) {
+    myCache = cache;
+  }
+
+  public void walkSuperClasses(int classQName, ClassInfoProcessor processor) throws CacheCorruptedException {
+    if (classQName == Cache.UNKNOWN) {
+      return;
+    }
+    int superQName = myCache.getSuperQualifiedName(classQName);
+
+    if (classQName == superQName) {
+      LOG.error("Superclass qualified name is the same as class' name: " + classQName);
+      return;
+    }
+
+    if (superQName != Cache.UNKNOWN) {
+      if (processor.process(superQName)) {
+        walkSuperClasses(superQName, processor);
+      }
+    }
+    for (int superInterfaceQName : myCache.getSuperInterfaces(classQName)) {
+      if (processor.process(superInterfaceQName)) {
+        walkSuperClasses(superInterfaceQName, processor);
+      }
+    }
+  }
+
+  public void walkSuperInterfaces(int classQName, ClassInfoProcessor processor) throws CacheCorruptedException {
+    if (classQName == Cache.UNKNOWN) {
+      return;
+    }
+
+    for (int superInterfaceQName : myCache.getSuperInterfaces(classQName)) {
+      if (processor.process(superInterfaceQName)) {
+        walkSuperInterfaces(superInterfaceQName, processor);
+      }
+    }
+  }
+
+  public void walkSubClasses(int fromClassQName, ClassInfoProcessor processor) throws CacheCorruptedException {
+    for (int subQName : myCache.getSubclasses(fromClassQName)) {
+      if (fromClassQName == subQName) {
+        LOG.error("Subclass qualified name is the same as class' name: " + fromClassQName);
+        return;
+      }
+      if (subQName != Cache.UNKNOWN) {
+        if (!processor.process(subQName)) {
+          break;
+        }
+      }
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/FieldChangeDescription.java b/java/compiler/impl/src/com/intellij/compiler/make/FieldChangeDescription.java
new file mode 100644
index 0000000..9d0ef47
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/FieldChangeDescription.java
@@ -0,0 +1,38 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.classParsing.FieldInfo;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 7, 2004
+ */
+class FieldChangeDescription extends ChangeDescription {
+  public final boolean flagsChanged;
+  public final boolean descriptorChanged;
+  public final boolean genericSignatureChanged;
+
+  public FieldChangeDescription(final FieldInfo oldField, final FieldInfo newField) {
+    descriptorChanged = oldField.getDescriptor() != newField.getDescriptor();
+    flagsChanged = oldField.getFlags() != newField.getFlags();
+    genericSignatureChanged = oldField.getGenericSignature() != newField.getGenericSignature();
+  }
+
+  public boolean isChanged() {
+    return flagsChanged || descriptorChanged || genericSignatureChanged;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/JavaDependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/JavaDependencyProcessor.java
new file mode 100644
index 0000000..b00d886
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/JavaDependencyProcessor.java
@@ -0,0 +1,1322 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Feb 19, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.cls.ClsUtil;
+import gnu.trove.TIntHashSet;
+import gnu.trove.TIntObjectHashMap;
+import gnu.trove.TIntObjectIterator;
+import gnu.trove.TIntObjectProcedure;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.*;
+
+class JavaDependencyProcessor {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.JavaDependencyProcessor");
+  private final DependencyCache myDependencyCache;
+  private final int myQName;
+  private final Map<Dependency.MethodRef, MethodInfo> myRefToMethodMap = new HashMap<Dependency.MethodRef, MethodInfo>();
+  private final Map<Dependency.FieldRef, FieldInfo> myRefToFieldMap = new HashMap<Dependency.FieldRef, FieldInfo>();
+  private final Set<MemberInfo> myAddedMembers = new HashSet<MemberInfo>();
+  private final Set<MemberInfo> myRemovedMembers = new HashSet<MemberInfo>();
+  private final Set<MemberInfo> myChangedMembers = new HashSet<MemberInfo>();
+  private final Map<MemberInfo, ChangeDescription> myChangeDescriptions = new HashMap<MemberInfo, ChangeDescription>();
+  private Dependency[] myBackDependencies;
+  private final boolean myMembersChanged;
+  private final boolean mySuperInterfaceAdded;
+  private final boolean mySuperInterfaceRemoved;
+  private final boolean mySuperClassChanged;
+  private final boolean mySuperlistGenericSignatureChanged;
+  private final boolean mySuperClassAdded;
+  private final Project myProject;
+  private final boolean myIsAnnotation;
+  private final boolean myIsRemoteInterface;
+  private final boolean myWereAnnotationTargetsRemoved;
+  private final boolean myRetentionPolicyChanged;
+  private final boolean myAnnotationSemanticsChanged;
+
+  public JavaDependencyProcessor(Project project, DependencyCache dependencyCache, int qName) throws CacheCorruptedException {
+    myProject = project;
+    myDependencyCache = dependencyCache;
+    myQName = qName;
+    final Cache cache = dependencyCache.getCache();
+    final Cache newClassesCache = dependencyCache.getNewClassesCache();
+
+    final MethodInfo[] oldMethods = cache.getMethods(qName);
+    for (MethodInfo method : oldMethods) {
+      myRefToMethodMap.put(new Dependency.MethodRef(method.getName(), method.getDescriptor()), method);
+    }
+    final TIntObjectHashMap<FieldInfo> oldFieldsMap = getFieldInfos(cache, qName);
+    oldFieldsMap.forEachEntry(new TIntObjectProcedure<FieldInfo>() {
+      public boolean execute(int fieldName, FieldInfo fieldInfo) {
+        myRefToFieldMap.put(new Dependency.FieldRef(fieldName), fieldInfo);
+        return true;
+      }
+    });
+    final Map<String, MethodInfoContainer> oldMethodsMap = getMethodInfos(oldMethods);
+    final Map<String, MethodInfoContainer> newMethodsMap = getMethodInfos(newClassesCache.getMethods(qName));
+    final TIntObjectHashMap<FieldInfo> newFieldsMap = getFieldInfos(newClassesCache, qName);
+    addAddedMembers(oldFieldsMap, oldMethodsMap, newFieldsMap, newMethodsMap, myAddedMembers);
+    addRemovedMembers(oldFieldsMap, oldMethodsMap, newFieldsMap, newMethodsMap, myRemovedMembers);
+    addChangedMembers(oldFieldsMap, oldMethodsMap, newFieldsMap, newMethodsMap, myChangedMembers);
+
+    myMembersChanged = !myAddedMembers.isEmpty() || !myRemovedMembers.isEmpty() || !myChangedMembers.isEmpty();
+    // track changes in super list
+
+    myIsRemoteInterface = MakeUtil.isInterface(cache.getFlags(myQName)) && cache.isRemote(qName);
+    myIsAnnotation = ClsUtil.isAnnotation(cache.getFlags(qName));
+    myWereAnnotationTargetsRemoved = myIsAnnotation && wereAnnotationTargesRemoved(cache, newClassesCache);
+    myRetentionPolicyChanged = myIsAnnotation && hasRetentionPolicyChanged(cache, newClassesCache);
+    myAnnotationSemanticsChanged = myIsAnnotation && hasAnnotationSemanticsChanged(cache, newClassesCache);
+
+    int[] oldInterfaces = cache.getSuperInterfaces(qName);
+    int[] newInterfaces = newClassesCache.getSuperInterfaces(qName);
+    mySuperInterfaceRemoved = wereInterfacesRemoved(oldInterfaces, newInterfaces);
+    mySuperInterfaceAdded = wereInterfacesRemoved(newInterfaces, oldInterfaces);
+
+    mySuperlistGenericSignatureChanged = isSuperlistGenericSignatureChanged(cache.getGenericSignature(qName), newClassesCache.getGenericSignature(qName));
+
+    boolean superclassesDiffer = cache.getSuperQualifiedName(qName) != newClassesCache.getSuperQualifiedName(qName);
+    boolean wasDerivedFromObject = CommonClassNames.JAVA_LANG_OBJECT.equals(dependencyCache.resolve(cache.getSuperQualifiedName(qName)));
+    mySuperClassChanged = !wasDerivedFromObject && superclassesDiffer;
+    mySuperClassAdded = wasDerivedFromObject && superclassesDiffer;
+  }
+
+  private static boolean hasMembersWithoutDefaults(Set<MemberInfo> addedMembers) {
+    for (final Object addedMember : addedMembers) {
+      MemberInfo memberInfo = (MemberInfo)addedMember;
+      if (memberInfo instanceof MethodInfo) {
+        final ConstantValue annotationDefault = ((MethodInfo)memberInfo).getAnnotationDefault();
+        if (annotationDefault == null || ConstantValue.EMPTY_CONSTANT_VALUE.equals(annotationDefault)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean wereAnnotationDefaultsRemoved() {
+    for (final MemberInfo memberInfo : myChangeDescriptions.keySet()) {
+      if (memberInfo instanceof MethodInfo) {
+        MethodChangeDescription description = (MethodChangeDescription)myChangeDescriptions.get(memberInfo);
+        if (description.removedAnnotationDefault) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean isSuperlistGenericSignatureChanged(int oldGenericSignature, int newGenericSignature) throws CacheCorruptedException {
+    if (oldGenericSignature == newGenericSignature) {
+      return false;
+    }
+    if (oldGenericSignature != -1 && newGenericSignature != -1) {
+      final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+      final String _oldGenericMethodSignature = cutFormalParams(symbolTable.getSymbol(oldGenericSignature));
+      final String _newGenericMethodSignature = cutFormalParams(symbolTable.getSymbol(newGenericSignature));
+      return !_oldGenericMethodSignature.equals(_newGenericMethodSignature);
+    }
+    return true;
+  }
+
+  private static String cutFormalParams(String genericClassSignature) {
+    if (genericClassSignature.charAt(0) == '<') {
+      int idx = genericClassSignature.indexOf('>');
+      return genericClassSignature.substring(idx + 1);
+    }
+    return genericClassSignature;
+  }
+
+  public void run() throws CacheCorruptedException {
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Checking dependencies for " + myDependencyCache.resolve(myQName));
+    }
+    final boolean superListChanged = mySuperClassChanged || mySuperClassAdded || mySuperInterfaceAdded || mySuperInterfaceRemoved || mySuperlistGenericSignatureChanged;
+    final Cache oldCache = myDependencyCache.getCache();
+    final Cache newCache = myDependencyCache.getNewClassesCache();
+
+    if (!myMembersChanged &&
+        oldCache.getFlags(myQName) == newCache.getFlags(myQName) &&
+        !superListChanged && !myWereAnnotationTargetsRemoved && !myRetentionPolicyChanged && !myAnnotationSemanticsChanged) {
+      return; // nothing to do
+    }
+
+    if (myIsAnnotation) {
+      if (myAnnotationSemanticsChanged) {
+        final TIntHashSet visited = new TIntHashSet();
+        visited.add(myQName);
+        markAnnotationDependenciesRecursively(getBackDependencies(), LOG.isDebugEnabled()? "; reason: semantics changed for " + myDependencyCache.resolve(myQName) : "", visited);
+        return;
+      }
+      if (hasMembersWithoutDefaults(myAddedMembers)) {
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: added annotation type member without default " + myDependencyCache.resolve(myQName) : "");
+        return;
+      }
+      if (!myRemovedMembers.isEmpty()) {
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: removed annotation type member " + myDependencyCache.resolve(myQName) : "");
+        return;
+      }
+      if (!myChangedMembers.isEmpty()) { // for annotations "changed" means return type changed
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: changed annotation member's type " + myDependencyCache.resolve(myQName) : "");
+        return;
+      }
+      if (wereAnnotationDefaultsRemoved()) {
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: removed annotation member's default value " + myDependencyCache.resolve(myQName): "");
+        return;
+      }
+      if (myWereAnnotationTargetsRemoved) {
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: removed annotation's targets " + myDependencyCache.resolve(myQName) : "");
+        return;
+      }
+      if (myRetentionPolicyChanged) {
+        markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: retention policy changed for " + myDependencyCache.resolve(myQName) : "");
+        return;
+      }
+    }
+
+    final DependencyCacheNavigator cacheNavigator = myDependencyCache.getCacheNavigator();
+
+    if (mySuperClassChanged || mySuperInterfaceRemoved || mySuperlistGenericSignatureChanged) {
+      // superclass changed == old removed and possibly new added
+      // if anything (class or interface) in the superlist was removed, should recompile all subclasses (both direct and indirect)
+      // and all back-dependencies of this class and its subclasses
+      markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: deleted items from the superlist or changed superlist generic signature of " + myDependencyCache.resolve(myQName) : "");
+      cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() {
+        public boolean process(int classQName) throws CacheCorruptedException {
+          markAll(oldCache.getBackDependencies(classQName), LOG.isDebugEnabled()? "; reason: deleted items from the superlist or changed superlist generic signature of " + myDependencyCache.resolve(myQName) : "");
+          return true;
+        }
+      });
+      return;
+    }
+
+    final boolean isKindChanged =
+      (MakeUtil.isInterface(oldCache.getFlags(myQName)) && !MakeUtil.isInterface(newCache.getFlags(myQName))) ||
+      (!MakeUtil.isInterface(oldCache.getFlags(myQName)) && MakeUtil.isInterface(newCache.getFlags(myQName)));
+    if (isKindChanged) {
+      markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: class kind changed (class/interface) " + myDependencyCache.resolve(myQName) : "");
+      cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() {
+        public boolean process(int classQName) throws CacheCorruptedException {
+          markAll(oldCache.getBackDependencies(classQName), LOG.isDebugEnabled()? "; reason: class kind changed (class/interface) " + myDependencyCache.resolve(myQName) : "");
+          return true;
+        }
+      });
+      return;
+    }
+
+    boolean becameFinal = !ClsUtil.isFinal(oldCache.getFlags(myQName)) && ClsUtil.isFinal(newCache.getFlags(myQName));
+    if (becameFinal) {
+      markAll(getBackDependencies(), LOG.isDebugEnabled()? "; reason: class became final: " + myDependencyCache.resolve(myQName) : "");
+    }
+    else {
+      boolean becameAbstract = !ClsUtil.isAbstract(oldCache.getFlags(myQName)) && ClsUtil.isAbstract(newCache.getFlags(myQName));
+      boolean accessRestricted = MakeUtil.isMoreAccessible(oldCache.getFlags(myQName), newCache.getFlags(myQName));
+      Set<MethodInfo> removedMethods = null;
+      Set<MethodInfo> addedMethods = null;
+      for (Dependency backDependency : getBackDependencies()) {
+        if (myDependencyCache.isTargetClassInfoMarked(backDependency)) continue;
+
+        if (accessRestricted) {
+          if (myDependencyCache.markTargetClassInfo(backDependency)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) + "; reason: " +
+                        myDependencyCache.resolve(myQName) + " made less accessible");
+            }
+          }
+          continue;
+        }
+        if (becameAbstract) {
+          if (processClassBecameAbstract(backDependency)) {
+            continue;
+          }
+        }
+        if (isDependentOnRemovedMembers(backDependency)) {
+          if (myDependencyCache.markTargetClassInfo(backDependency)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) +
+                        "; reason: the class uses removed members of " + myDependencyCache.resolve(myQName));
+            }
+          }
+          continue;
+        }
+        if (isDependentOnChangedMembers(backDependency)) {
+          if (myDependencyCache.markTargetClassInfo(backDependency)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) +
+                        "; reason: the class uses changed members of " + myDependencyCache.resolve(myQName));
+            }
+          }
+          continue;
+        }
+        final Collection<Dependency.MethodRef> usedMethods = backDependency.getMethodRefs();
+        if (removedMethods == null) {
+          removedMethods = extractMethods(myRemovedMembers, true);
+        }
+        if (isDependentOnEquivalentMethods(usedMethods, removedMethods)) {
+          if (myDependencyCache.markTargetClassInfo(backDependency)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) +
+                        "; reason: some overloaded methods of " + myDependencyCache.resolve(myQName) + " were removed");
+            }
+          }
+          continue;
+        }
+        if (addedMethods == null) {
+          addedMethods = extractMethods(myAddedMembers, true);
+        }
+        if (isDependentOnEquivalentMethods(usedMethods, addedMethods)) {
+          if (myDependencyCache.markTargetClassInfo(backDependency)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) +
+                        "; reason: some overloaded methods of " + myDependencyCache.resolve(myQName) + " were added");
+            }
+          }
+        }
+      }
+    }
+
+    final Set<MethodInfo> methodsToCheck = new HashSet<MethodInfo>();
+    extractMethods(myRemovedMembers, methodsToCheck, false);
+    
+    processInheritanceDependencies(methodsToCheck);
+
+    extractMethods(myAddedMembers, methodsToCheck, false);
+
+    if (!MakeUtil.isAnonymous(myDependencyCache.resolve(myQName))) {
+      // these checks make no sense for anonymous classes
+      
+      final TIntHashSet fieldNames = new TIntHashSet();
+      extractFieldNames(myAddedMembers, fieldNames);
+      int addedFieldsCount = fieldNames.size();
+      extractFieldNames(myRemovedMembers, fieldNames);
+      
+      if (!fieldNames.isEmpty()) {
+        cacheNavigator.walkSuperClasses(myQName, new ClassInfoProcessor() {
+          public boolean process(final int classQName) throws CacheCorruptedException {
+            markUseDependenciesOnFields(classQName, fieldNames);
+            return true;
+          }
+        });
+      }
+      
+      if (addedFieldsCount > 0 && MakeUtil.isInterface(oldCache.getFlags(myQName))) {
+        final TIntHashSet visitedClasses = new TIntHashSet();
+        visitedClasses.add(myQName);
+        cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() {
+          public boolean process(int subclassQName) throws CacheCorruptedException {
+            markUseDependenciesOnFields(subclassQName, fieldNames);
+            visitedClasses.add(subclassQName);
+            cacheNavigator.walkSuperClasses(subclassQName, new ClassInfoProcessor() {
+              public boolean process(int superclassQName) throws CacheCorruptedException {
+                if (visitedClasses.contains(superclassQName)) {
+                  return false;
+                }
+                markUseDependenciesOnFields(superclassQName, fieldNames);
+                visitedClasses.add(superclassQName);
+                return true;
+              }
+            });
+            return true;
+          }
+        });
+      }
+
+      if (!methodsToCheck.isEmpty()) {
+        cacheNavigator.walkSuperClasses(myQName, new ClassInfoProcessor() {
+          public boolean process(int classQName) throws CacheCorruptedException {
+            markUseDependenciesOnEquivalentMethods(classQName, methodsToCheck, myQName);
+            return true;
+          }
+        });
+
+        cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() {
+          public boolean process(int classQName) throws CacheCorruptedException {
+            markUseDependenciesOnEquivalentMethods(classQName, methodsToCheck, myQName);
+            return true;
+          }
+        });
+      }
+      // check referencing members in subclasses
+      
+      final TIntHashSet addedOrRemovedFields = new TIntHashSet();
+      final TIntHashSet addedOrRemovedMethods = new TIntHashSet();
+      for (Set<MemberInfo> infos : Arrays.asList(myAddedMembers, myRemovedMembers)) {
+        for (MemberInfo member : infos) {
+          if (!member.isPrivate()) {
+            if (member instanceof FieldInfo) {
+              addedOrRemovedFields.add(member.getName());
+            }
+            else if (member instanceof MethodInfo){
+              addedOrRemovedMethods.add(member.getName());
+            }
+          }
+        }
+        
+      }
+      if (!addedOrRemovedFields.isEmpty() || !addedOrRemovedMethods.isEmpty()) {
+        cacheNavigator.walkSubClasses(myQName, new ClassInfoProcessor() {
+          public boolean process(final int subclassQName) throws CacheCorruptedException {
+            if (!myDependencyCache.isClassInfoMarked(subclassQName)) {
+              if (referencesMembersWithNames(oldCache, subclassQName, addedOrRemovedFields, addedOrRemovedMethods)) {
+                final boolean marked = myDependencyCache.markClass(subclassQName);
+                if (marked && LOG.isDebugEnabled()) {
+                  LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; Reason: members were added/removed in superclass with names, that may clash with the names of members of another classes that this class references");
+                }
+              }
+            }
+            return true;
+          }
+        });
+      }
+    }
+  }
+  
+  private static boolean referencesMembersWithNames(Cache cache, final int qName, TIntHashSet fieldNames, TIntHashSet methodNames) throws CacheCorruptedException {
+    for (final int referencedClass : cache.getReferencedClasses(qName)) {
+      for (Dependency dependency : cache.getBackDependencies(referencedClass)) {
+        if (dependency.getClassQualifiedName() == qName) {
+          for (Dependency.FieldRef ref : dependency.getFieldRefs()) {
+            if (fieldNames.contains(ref.name)) {
+              return true;
+            }
+          }
+          for (Dependency.MethodRef ref : dependency.getMethodRefs()) {
+            if (methodNames.contains(ref.name)) {
+              return true;
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  private void markAnnotationDependenciesRecursively(final Dependency[] dependencies, final @NonNls String reason, final TIntHashSet visitedAnnotations)
+      throws CacheCorruptedException {
+    final Cache oldCache = myDependencyCache.getCache();
+    for (Dependency dependency : dependencies) {
+      if (myDependencyCache.markTargetClassInfo(dependency)) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Mark dependent class " + myDependencyCache.resolve(dependency.getClassQualifiedName()) + reason);
+        }
+      }
+      final int depQName = dependency.getClassQualifiedName();
+      if (ClsUtil.isAnnotation(oldCache.getFlags(depQName))) {
+        if (!visitedAnnotations.contains(depQName)) {
+          visitedAnnotations.add(depQName);
+          markAnnotationDependenciesRecursively(oldCache.getBackDependencies(depQName), LOG.isDebugEnabled()? "; reason: cascade semantics change for " + myDependencyCache.resolve(depQName) : "", visitedAnnotations);
+        }
+      }
+    }
+  }
+
+  private static final int[] ALL_TARGETS = {
+    AnnotationTargets.ANNOTATION_TYPE,
+    AnnotationTargets.CONSTRUCTOR,
+    AnnotationTargets.FIELD,
+    AnnotationTargets.LOCAL_VARIABLE,
+    AnnotationTargets.METHOD,
+    AnnotationTargets.PACKAGE,
+    AnnotationTargets.PARAMETER,
+    AnnotationTargets.TYPE
+  };
+  private boolean wereAnnotationTargesRemoved(final Cache oldCache, final Cache newCache) throws CacheCorruptedException {
+    final int oldAnnotationTargets = MakeUtil.getAnnotationTargets(oldCache, myQName, myDependencyCache.getSymbolTable());
+    final int newAnnotationTargets = MakeUtil.getAnnotationTargets(newCache, myQName, myDependencyCache.getSymbolTable());
+    if (oldAnnotationTargets == newAnnotationTargets) {
+      return false;
+    }
+    for (final int target : ALL_TARGETS) {
+      if ((oldAnnotationTargets & target) != 0 && (newAnnotationTargets & target) == 0) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean hasRetentionPolicyChanged(final Cache oldCache, final Cache newCache) throws CacheCorruptedException {
+    // if retention policy changed from SOURCE to CLASS or RUNTIME, all sources should be recompiled to propagate changes
+    final int oldPolicy = MakeUtil.getAnnotationRetentionPolicy(myQName, oldCache, myDependencyCache.getSymbolTable());
+    final int newPolicy = MakeUtil.getAnnotationRetentionPolicy(myQName, newCache, myDependencyCache.getSymbolTable());
+    if (oldPolicy == RetentionPolicies.SOURCE && (newPolicy == RetentionPolicies.CLASS || newPolicy == RetentionPolicies.RUNTIME)) {
+      return true;
+    }
+    return oldPolicy == RetentionPolicies.CLASS && newPolicy == RetentionPolicies.RUNTIME;
+  }
+
+  private boolean hasAnnotationSemanticsChanged(final Cache oldCache, final Cache newCache) throws CacheCorruptedException {
+    final TIntObjectHashMap<AnnotationConstantValue> oldAnnotations = fetchAllAnnotations(oldCache);
+    final TIntObjectHashMap<AnnotationConstantValue> newAnnotations = fetchAllAnnotations(newCache);
+    // filter certain known annotation which are processed separately
+    final int retentionAnnotation = myDependencyCache.getSymbolTable().getId("java.lang.annotation.Retention");
+    final int targetAnnotation = myDependencyCache.getSymbolTable().getId("java.lang.annotation.Target");
+    oldAnnotations.remove(retentionAnnotation);
+    oldAnnotations.remove(targetAnnotation);
+    newAnnotations.remove(retentionAnnotation);
+    newAnnotations.remove(targetAnnotation);
+
+    if (oldAnnotations.size() != newAnnotations.size()) {
+      return true; // number of annotation has changed
+    }
+    for (int annotName : oldAnnotations.keys()) {
+      if (!newAnnotations.contains(annotName)) {
+        return true;
+      }
+      final AnnotationNameValuePair[] oldValues = oldAnnotations.get(annotName).getMemberValues();
+      final AnnotationNameValuePair[] newValues = newAnnotations.get(annotName).getMemberValues();
+      if (annotationValuesDiffer(oldValues, newValues)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean annotationValuesDiffer(final AnnotationNameValuePair[] oldValues, final AnnotationNameValuePair[] newValues) {
+    if (oldValues.length != newValues.length) {
+      return true;
+    }
+    final TIntObjectHashMap<ConstantValue> names = new TIntObjectHashMap<ConstantValue>();
+    for (AnnotationNameValuePair value : oldValues) {
+      names.put(value.getName(), value.getValue());
+    }
+    for (AnnotationNameValuePair value : newValues) {
+      if (!names.containsKey(value.getName())) {
+        return true;
+      }
+      if (!value.getValue().equals(names.get(value.getName()))) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+
+  private TIntObjectHashMap<AnnotationConstantValue> fetchAllAnnotations(final Cache cache) throws CacheCorruptedException {
+    final int classId = myQName;
+    TIntObjectHashMap<AnnotationConstantValue> oldAnnotations = new TIntObjectHashMap<AnnotationConstantValue>();
+    for (AnnotationConstantValue annot : cache.getRuntimeVisibleAnnotations(classId)) {
+      oldAnnotations.put(annot.getAnnotationQName(), annot);
+    }
+    for (AnnotationConstantValue annot : cache.getRuntimeInvisibleAnnotations(classId)) {
+      oldAnnotations.put(annot.getAnnotationQName(), annot);
+    }
+    return oldAnnotations;
+  }
+
+  private void markAll(Dependency[] backDependencies, @NonNls String reason) throws CacheCorruptedException {
+    for (Dependency backDependency : backDependencies) {
+      if (myDependencyCache.markTargetClassInfo(backDependency)) {
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Mark dependent class " + myDependencyCache.resolve(backDependency.getClassQualifiedName()) + reason);
+        }
+      }
+    }
+  }
+
+  private static void extractFieldNames(Collection<MemberInfo> fromCollection, TIntHashSet toCollection) {
+    for (final Object aFromCollection : fromCollection) {
+      MemberInfo memberInfo = (MemberInfo)aFromCollection;
+      if (memberInfo instanceof FieldInfo) {
+        toCollection.add(memberInfo.getName());
+      }
+    }
+  }
+
+  private static Set<MethodInfo> extractMethods(Collection<MemberInfo> fromCollection, boolean includeConstructors) {
+    final Set<MethodInfo> methods = new HashSet<MethodInfo>();
+    extractMethods(fromCollection, methods, includeConstructors);
+    return methods;
+  }
+  
+  private static void extractMethods(Collection<MemberInfo> fromCollection, Collection<MethodInfo> toCollection, boolean includeConstructors) {
+    for (final MemberInfo memberInfo : fromCollection) {
+      if (memberInfo instanceof MethodInfo) {
+        final MethodInfo methodInfo = (MethodInfo)memberInfo;
+        if (includeConstructors) {
+          toCollection.add(methodInfo);
+        }
+        else {
+          if (!methodInfo.isConstructor()) {
+            toCollection.add(methodInfo);
+          }
+        }
+      }
+    }
+  }
+
+  private boolean processClassBecameAbstract(Dependency dependency) throws CacheCorruptedException {
+    for (Dependency.MethodRef ref : dependency.getMethodRefs()) {
+      final MethodInfo usedMethod = myRefToMethodMap.get(ref);
+      if (usedMethod == null) {
+        continue;
+      }
+      if (usedMethod.isConstructor()) {
+        if (myDependencyCache.markTargetClassInfo(dependency)) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Mark dependent class " + myDependencyCache.resolve(dependency.getClassQualifiedName()) + "; reason: " +
+                      myDependencyCache.resolve(myQName) + " made abstract");
+          }
+        }
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean isDependentOnRemovedMembers(Dependency dependency) {
+    for (Dependency.MethodRef ref : dependency.getMethodRefs()) {
+      if (myRemovedMembers.contains(myRefToMethodMap.get(ref))) {
+        return true;
+      }
+    }
+    for (Dependency.FieldRef ref : dependency.getFieldRefs()) {
+      if (myRemovedMembers.contains(myRefToFieldMap.get(ref))) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean isDependentOnChangedMembers(Dependency dependency) {
+    for (Dependency.FieldRef ref : dependency.getFieldRefs()) {
+      final FieldInfo fieldInfo = myRefToFieldMap.get(ref);
+      if (myChangedMembers.contains(fieldInfo)) {
+        return true;
+      }
+    }
+
+    for (Dependency.MethodRef ref : dependency.getMethodRefs()) {
+      final MethodInfo methodInfo = myRefToMethodMap.get(ref);
+      if (myChangedMembers.contains(methodInfo)) {
+        final MethodChangeDescription changeDescription = (MethodChangeDescription)myChangeDescriptions.get(methodInfo);
+        if (changeDescription.returnTypeDescriptorChanged ||
+            changeDescription.returnTypeGenericSignatureChanged ||
+            changeDescription.paramsGenericSignatureChanged ||
+            changeDescription.throwsListChanged ||
+            changeDescription.staticPropertyChanged ||
+            changeDescription.accessRestricted) {
+          return true;
+        }
+      }
+    }
+
+    return false;
+  }
+
+  private boolean isDependentOnEquivalentMethods(Collection<Dependency.MethodRef> checkedMembers, Set<MethodInfo> members) throws CacheCorruptedException {
+    // check if 'members' contains method with the same name and the same numbers of parameters, but with different types
+    if (checkedMembers.isEmpty() || members.isEmpty()) {
+      return false; // optimization
+    }
+    for (Dependency.MethodRef checkedMethod : checkedMembers) {
+      if (hasEquivalentMethod(members, checkedMethod)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private void markUseDependenciesOnEquivalentMethods(final int checkedInfoQName, Set<MethodInfo> methodsToCheck, int methodsClassName) throws CacheCorruptedException {
+    final Dependency[] backDependencies = myDependencyCache.getCache().getBackDependencies(checkedInfoQName);
+    for (Dependency dependency : backDependencies) {
+      if (myDependencyCache.isTargetClassInfoMarked(dependency)) {
+        continue;
+      }
+      if (isDependentOnEquivalentMethods(dependency.getMethodRefs(), methodsToCheck)) {
+        if (myDependencyCache.markTargetClassInfo(dependency)) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Mark dependent class " + myDependencyCache.resolve(dependency.getClassQualifiedName()) +
+                      "; reason: more specific methods added to " + myDependencyCache.resolve(methodsClassName));
+          }
+        }
+        myDependencyCache.addClassToUpdate(checkedInfoQName);
+      }
+    }
+  }
+
+  private void markUseDependenciesOnFields(final int classQName, TIntHashSet fieldNames) throws CacheCorruptedException {
+    final Cache oldCache = myDependencyCache.getCache();
+    for (Dependency useDependency : oldCache.getBackDependencies(classQName)) {
+      if (!myDependencyCache.isTargetClassInfoMarked(useDependency)) {
+        for (Dependency.FieldRef field : useDependency.getFieldRefs()) {
+          if (fieldNames.contains(field.name)) {
+            if (myDependencyCache.markTargetClassInfo(useDependency)) {
+              if (LOG.isDebugEnabled()) {
+                LOG.debug("Mark dependent class " + myDependencyCache.resolve(useDependency.getClassQualifiedName()) +
+                          "; reason: conflicting fields were added to the hierarchy of the class " + myDependencyCache.resolve(classQName));
+              }
+            }
+            myDependencyCache.addClassToUpdate(classQName);
+            break; // stop iterating fields
+          }
+        }
+      }
+    }
+  }
+  
+  private void processInheritanceDependencies(final Set<MethodInfo> removedMethods) throws CacheCorruptedException {
+    final Cache oldCache = myDependencyCache.getCache();
+    final Cache newCache = myDependencyCache.getNewClassesCache();
+
+    final boolean becameFinal = !ClsUtil.isFinal(oldCache.getFlags(myQName)) && ClsUtil.isFinal(newCache.getFlags(myQName));
+    final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+
+    final Set<MemberInfo> removedConcreteMethods = fetchNonAbstractMethods(myRemovedMembers);
+    final Set<MethodInfo> removedOverridableMethods;
+    if (!removedMethods.isEmpty()) {
+      removedOverridableMethods = new HashSet<MethodInfo>(removedMethods);
+      for (Iterator<MethodInfo> it = removedOverridableMethods.iterator(); it.hasNext();) {
+        final MethodInfo method = it.next();
+        if (method.isFinal() || method.isStatic() || method.isPrivate() || method.isConstructor()) {
+          it.remove();
+        }
+      }
+    }
+    else {
+      removedOverridableMethods = Collections.emptySet();
+    }
+    myDependencyCache.getCacheNavigator().walkSubClasses(myQName, new ClassInfoProcessor() {
+      public boolean process(final int subclassQName) throws CacheCorruptedException {
+        if (myDependencyCache.isClassInfoMarked(subclassQName)) {
+          return true;
+        }
+
+        if (!oldCache.containsClass(subclassQName)) {
+          return true;
+        }
+
+        if (!removedMethods.isEmpty() && myIsRemoteInterface && !MakeUtil.isInterface(oldCache.getFlags(subclassQName))) {
+          if (myDependencyCache.markClass(subclassQName)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) +
+                        "; reason: methods were removed from remote interface: " + myDependencyCache.resolve(myQName));
+            }
+          }
+          return true;
+        }
+
+        if (mySuperClassAdded || mySuperInterfaceAdded) {
+          if (myDependencyCache.markClass(subclassQName)) {
+            if (LOG.isDebugEnabled()) {
+              LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the superlist of " +
+                        myDependencyCache.resolve(myQName) + " is changed");
+            }
+          }
+          return true;
+        }
+
+        // if info became final, mark direct inheritors
+        if (becameFinal) {
+          if (myQName == oldCache.getSuperQualifiedName(subclassQName)) {
+            if (myDependencyCache.markClass(subclassQName)) {
+              if (LOG.isDebugEnabled()) {
+                LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the class " +
+                          myDependencyCache.resolve(myQName) + " was made final");
+              }
+            }
+            return true;
+          }
+        }
+
+        // process added members
+        for (final MemberInfo member : myAddedMembers) {
+          if (member instanceof MethodInfo) {
+            final MethodInfo method = (MethodInfo)member;
+            if (method.isAbstract()) {
+              // all derived classes should be marked in case an abstract method was added
+              if (myDependencyCache.markClass(subclassQName)) {
+                if (LOG.isDebugEnabled()) {
+                  LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: added abstract method to " +
+                            myDependencyCache.resolve(myQName));
+                }
+              }
+              return true;
+            }
+            if (!method.isPrivate()) {
+              final MethodInfo derivedMethod = oldCache.findMethodsBySignature(subclassQName, method.getDescriptor(symbolTable), symbolTable);
+              if (derivedMethod != null) {
+                if (!method.getReturnTypeDescriptor(symbolTable).equals(derivedMethod.getReturnTypeDescriptor(symbolTable))) {
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: return types of method " +
+                                method + " in base and derived classes are different");
+                    }
+                  }
+                  return true;
+                }
+                if (MakeUtil.isMoreAccessible(method.getFlags(), derivedMethod.getFlags())) {
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the method " + method +
+                                " in derived class is less accessible than in base class");
+                    }
+                  }
+                  return true;
+                }
+                if (!method.isStatic() && derivedMethod.isStatic()) {
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the method " + method +
+                                " in derived class is static, but added method in the base class is not");
+                    }
+                  }
+                  return true;
+                }
+                if (method.isFinal() && !derivedMethod.isFinal()) {
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the method " + method +
+                                " in base class is final, but in derived class is not");
+                    }
+                  }
+                  return true;
+                }
+                if (!CacheUtils.areArraysContentsEqual(method.getThrownExceptions(), derivedMethod.getThrownExceptions())) {
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: exception lists of " +
+                                method + " in base and derived classes are different");
+                    }
+                  }
+                  return true;
+                }
+              }
+              if (hasGenericsNameClashes(method, oldCache, subclassQName)) {
+                if (myDependencyCache.markClass(subclassQName)) {
+                  if (LOG.isDebugEnabled()) {
+                    LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) +
+                              "; reason: found method with the same name, different generic signature, but the same erasure as " + method);
+                  }
+                }
+                return true;
+              }
+            }
+          }
+          else if (member instanceof FieldInfo) {
+            if (oldCache.findFieldByName(subclassQName, member.getName()) != null) {
+              if (myDependencyCache.markClass(subclassQName)) {
+                if (LOG.isDebugEnabled()) {
+                  LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: added field " + member +
+                            " to base class");
+                }
+              }
+              return true;
+            }
+          }
+        }
+
+        // process changed members
+        for (final MemberInfo changedMember : myChangedMembers) {
+          if (changedMember instanceof MethodInfo) {
+            final MethodInfo oldMethod = (MethodInfo)changedMember;
+            MethodChangeDescription changeDescription = (MethodChangeDescription)myChangeDescriptions.get(oldMethod);
+            if (changeDescription.becameAbstract) {
+              if (!ClsUtil.isAbstract(oldCache.getFlags(subclassQName))) { // if the subclass was not abstract
+                if (myDependencyCache.markClass(subclassQName)) {
+                  if (LOG.isDebugEnabled()) {
+                    LOG.debug(
+                      "Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: changed base method " + oldMethod);
+                  }
+                }
+                return true;
+              }
+            }
+            
+            final String oldMethodDescriptor = oldMethod.getDescriptor(symbolTable);
+            
+            final MethodInfo derivedMethod = oldCache.findMethodsBySignature(subclassQName, oldMethodDescriptor, symbolTable);
+            if (derivedMethod != null) {
+              if (myDependencyCache.markClass(subclassQName)) {
+                if (LOG.isDebugEnabled()) {
+                  LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: changed base method " + oldMethod);
+                }
+              }
+              return true;
+            }
+            // now check if the changed method is compatible with methods declared in implemented interfaces of subclasses
+            myDependencyCache.getCacheNavigator().walkSuperInterfaces(subclassQName, new ClassInfoProcessor() {
+              boolean found = false;
+              public boolean process(final int ifaceQName) throws CacheCorruptedException {
+                if (found) {
+                  return false;
+                }
+                final MethodInfo implementee = oldCache.findMethodsBySignature(ifaceQName, oldMethodDescriptor, symbolTable);
+                if (implementee != null) {
+                  found = true;
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: changed base method, implementing corresponding method inherited from an interface" + oldMethod);
+                    }
+                  }
+                }
+                return !found;
+              }
+            });
+            if (myDependencyCache.isClassInfoMarked(subclassQName)) {
+              return true;
+            }
+          }
+        }
+
+        if (!ClsUtil.isAbstract(oldCache.getFlags(subclassQName))) {
+          if (hasUnimplementedAbstractMethods(subclassQName, new HashSet<MemberInfo>(removedConcreteMethods))) {
+            if (myDependencyCache.markClass(subclassQName)) {
+              if (LOG.isDebugEnabled()) {
+                LOG.debug("Mark dependent class " + myDependencyCache.resolve(subclassQName) + "; reason: the class should be declared abstract because abstract method implementation was removed from its superclass: " +
+                          myDependencyCache.resolve(myQName));
+              }
+            }
+            return true;
+          }
+        }
+
+        if (!removedOverridableMethods.isEmpty() && !myDependencyCache.isClassInfoMarked(subclassQName) && !myDependencyCache.getNewClassesCache().containsClass(subclassQName) /*not compiled in this session*/) {
+          final Cache cache = myDependencyCache.getCache();
+          for (MethodInfo subclassMethod : cache.getMethods(subclassQName)) {
+            if (!subclassMethod.isConstructor()) {
+              for (MethodInfo removedMethod : removedOverridableMethods) {
+                if (removedMethod.getName() == subclassMethod.getName() /*todo: check param signatures here for better accuracy*/) {
+                  // got it
+                  if (myDependencyCache.markClass(subclassQName)) {
+                    if (LOG.isDebugEnabled()) {
+                      LOG.debug("Mark dependent subclass " + myDependencyCache.resolve(subclassQName) + "; reason: the class has methods annotated with @Override and some methods were changed or removed in a base class" +
+                                myDependencyCache.resolve(myQName));
+                    }
+                  }
+                  return true;
+                }
+              }
+            }
+          }
+        }
+        // end of subclass processor
+        return true;
+      }
+    });
+  }
+
+  private static boolean hasGenericsNameClashes(final MethodInfo baseMethod, final Cache oldCache, final int subclassQName) throws CacheCorruptedException {
+    // it is illegal if 2 methods in a hierarchy have 1) same name 2) different signatures 3) same erasure
+    final List<MethodInfo> methods = oldCache.findMethodsByName(subclassQName, baseMethod.getName());
+    if (methods.size() > 0) {
+      for (final MethodInfo methodInSubclass : methods) {
+        if (ClsUtil.isBridge(methodInSubclass.getFlags())) {
+          continue;
+        }
+        if (baseMethod.getDescriptor() == methodInSubclass.getDescriptor() && baseMethod.getGenericSignature() != methodInSubclass.getGenericSignature()) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static Set<MemberInfo> fetchNonAbstractMethods(Set<MemberInfo> membersToCheck) {
+    final Set<MemberInfo> methodsToCheck = new HashSet<MemberInfo>();
+    for (final Object aMembersToCheck : membersToCheck) {
+      final MemberInfo memberInfo = (MemberInfo)aMembersToCheck;
+      if (memberInfo instanceof MethodInfo) {
+        final MethodInfo methodInfo = (MethodInfo)memberInfo;
+        if (!methodInfo.isAbstract() && !methodInfo.isConstructor()) {
+          methodsToCheck.add(memberInfo);
+        }
+      }
+    }
+    return methodsToCheck;
+  }
+
+  private boolean hasUnimplementedAbstractMethods(int superQName, final Set methodsToCheck) throws CacheCorruptedException {
+    if (myDependencyCache.getCache().containsClass(superQName)) {
+      return hasBaseAbstractMethods(superQName, methodsToCheck) ||
+             hasBaseAbstractMethodsInHierarchy(superQName, methodsToCheck);
+    }
+    else {
+      final String qName = myDependencyCache.resolve(superQName);
+      if (!CommonClassNames.JAVA_LANG_OBJECT.equals(qName)) {
+        if (hasBaseAbstractMethods2(qName, methodsToCheck)) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private boolean hasBaseAbstractMethodsInHierarchy(int fromClassQName, final Set methodsToCheck) throws CacheCorruptedException {
+    if (fromClassQName == Cache.UNKNOWN || methodsToCheck.isEmpty()) {
+      return false;
+    }
+    final Cache cache = myDependencyCache.getCache();
+    int superName = cache.getSuperQualifiedName(fromClassQName);
+    if (superName != Cache.UNKNOWN) {
+      if (hasUnimplementedAbstractMethods(superName, methodsToCheck)) {
+        return true;
+      }
+    }
+    if (methodsToCheck.isEmpty()) {
+      return false;
+    }
+    int[] superInterfaces = cache.getSuperInterfaces(fromClassQName);
+    for (int superInterface : superInterfaces) {
+      if (hasUnimplementedAbstractMethods(superInterface, methodsToCheck)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private boolean hasBaseAbstractMethods(int qName, Set methodsToCheck) throws CacheCorruptedException {
+    final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+    final Cache oldCache = myDependencyCache.getCache();
+    final Cache newCache = myDependencyCache.getNewClassesCache();
+    final Cache cache = newCache.containsClass(qName)? newCache : oldCache; // use recompiled version (if any) for searching methods
+    for (Iterator it = methodsToCheck.iterator(); it.hasNext();) {
+      final MethodInfo methodInfo = (MethodInfo)it.next();
+      final MethodInfo superMethod = cache.findMethodsBySignature(qName, methodInfo.getDescriptor(symbolTable), symbolTable);
+      if (superMethod != null) {
+        if (ClsUtil.isAbstract(superMethod.getFlags())) {
+          return true;
+        }
+        it.remove();
+      }
+    }
+    return false;
+  }
+
+  // search using PSI
+  private boolean hasBaseAbstractMethods2(final String qName, final Set methodsToCheck) throws CacheCorruptedException {
+    final boolean[] found = {false};
+    final CacheCorruptedException ex = ApplicationManager.getApplication().runReadAction(new Computable<CacheCorruptedException>() {
+      public CacheCorruptedException compute() {
+        try {
+          final PsiManager psiManager = PsiManager.getInstance(myProject);
+          final PsiClass aClass = JavaPsiFacade.getInstance(psiManager.getProject()).findClass(qName, GlobalSearchScope.allScope(myProject));
+          if (aClass == null) {
+            return null;
+          }
+          final PsiElementFactory factory = JavaPsiFacade.getInstance(psiManager.getProject()).getElementFactory();
+          final PsiNameHelper nameHelper = JavaPsiFacade.getInstance(myProject).getNameHelper();
+          for (Iterator it = methodsToCheck.iterator(); it.hasNext();) {
+            final MethodInfo methodInfo = (MethodInfo)it.next();
+            if (!nameHelper.isIdentifier(myDependencyCache.resolve(methodInfo.getName()), LanguageLevel.JDK_1_3)) { // fix for SCR 16068
+              continue;
+            }
+            // language level 1.3 will prevent exceptions from PSI if there are methods named "assert"
+            final PsiMethod methodPattern = factory.createMethodFromText(getMethodText(methodInfo), null, LanguageLevel.JDK_1_3);
+            final PsiMethod superMethod = aClass.findMethodBySignature(methodPattern, true);
+            if (superMethod != null) {
+              if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT)) {
+                found[0] = true;
+                return null;
+              }
+              it.remove();
+            }
+          }
+        }
+        catch (IncorrectOperationException e) {
+          LOG.error(e);
+        }
+        catch (CacheCorruptedException e) {
+          return e;
+        }
+        return null;
+      }
+    });
+    if (ex != null) {
+      throw ex;
+    }
+    return found[0];
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  private @NonNls String getMethodText(MethodInfo methodInfo) throws CacheCorruptedException {
+    final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+    StringBuilder text = new StringBuilder(16);
+    final String returnType = signatureToSourceTypeName(methodInfo.getReturnTypeDescriptor(symbolTable));
+    text.append(returnType);
+    text.append(" ");
+    text.append(myDependencyCache.resolve(methodInfo.getName()));
+    text.append("(");
+    final String[] parameterSignatures = methodInfo.getParameterDescriptors(symbolTable);
+    for (int idx = 0; idx < parameterSignatures.length; idx++) {
+      String parameterSignature = parameterSignatures[idx];
+      if (idx > 0) {
+        text.append(",");
+      }
+      text.append(signatureToSourceTypeName(parameterSignature));
+      text.append(" arg");
+      text.append(idx);
+    }
+    text.append(")");
+    return text.toString();
+  }
+
+  private static boolean wereInterfacesRemoved(int[] oldInterfaces, int[] newInterfaces) {
+    for (int oldInterface : oldInterfaces) {
+      boolean found = false;
+      for (int newInterface : newInterfaces) {
+        found = oldInterface == newInterface;
+        if (found) {
+          break;
+        }
+      }
+      if (!found) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  /** @return a map [fieldName->FieldInfo]*/
+  private static TIntObjectHashMap<FieldInfo> getFieldInfos(Cache cache, int qName) throws CacheCorruptedException {
+    final TIntObjectHashMap<FieldInfo> map = new TIntObjectHashMap<FieldInfo>();
+    for (FieldInfo fieldInfo : cache.getFields(qName)) {
+      map.put(fieldInfo.getName(), fieldInfo);
+    }
+    return map;
+  }
+
+  /** @return a map [methodSignature->MethodInfo]*/
+  private Map<String, MethodInfoContainer> getMethodInfos(final MethodInfo[] methods) throws CacheCorruptedException {
+    final Map<String, MethodInfoContainer> map = new HashMap<String, MethodInfoContainer>();
+    final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+    for (MethodInfo methodInfo : methods) {
+      final String signature = methodInfo.getDescriptor(symbolTable);
+      final MethodInfoContainer currentValue = map.get(signature);
+      // covariant methods have the same signature, so there might be several MethodInfos for one key
+      if (currentValue == null) {
+        map.put(signature, new MethodInfoContainer(methodInfo));
+      }
+      else {
+        currentValue.add(methodInfo);
+      }
+    }
+    return map;
+  }
+
+  private static void addAddedMembers(TIntObjectHashMap<FieldInfo> oldFields, Map<String, MethodInfoContainer> oldMethods,
+                               TIntObjectHashMap<FieldInfo> newFields, Map<String, MethodInfoContainer> newMethods,
+                               Collection<MemberInfo> members) {
+
+    for (final TIntObjectIterator<FieldInfo> it = newFields.iterator(); it.hasNext();) {
+      it.advance();
+      final int fieldName = it.key();
+      final FieldInfo fieldInfo = it.value();
+      if (!oldFields.containsKey(fieldName)) {
+        members.add(fieldInfo);
+      }
+    }
+    for (final String signature : newMethods.keySet()) {
+      if (!oldMethods.containsKey(signature)) {
+        members.addAll(newMethods.get(signature).getMethods());
+      }
+    }
+  }
+
+  private static void addRemovedMembers(TIntObjectHashMap<FieldInfo> oldFields, Map<String, MethodInfoContainer> oldMethods,
+                               TIntObjectHashMap<FieldInfo> newFields, Map<String, MethodInfoContainer> newMethods,
+                               Collection<MemberInfo> members)  {
+    addAddedMembers(newFields, newMethods, oldFields, oldMethods, members);
+  }
+
+  private void addChangedMembers(TIntObjectHashMap<FieldInfo> oldFields, Map<String, MethodInfoContainer> oldMethods,
+                               TIntObjectHashMap<FieldInfo> newFields, Map<String, MethodInfoContainer> newMethods,
+                               Collection<MemberInfo> members) throws CacheCorruptedException {
+    for (final TIntObjectIterator<FieldInfo> it = oldFields.iterator(); it.hasNext();) {
+      it.advance();
+      final int fieldName = it.key();
+      final FieldInfo oldInfo = it.value();
+      final FieldInfo newInfo = newFields.get(fieldName);
+      if (newInfo != null) {
+        final FieldChangeDescription changeDescription = new FieldChangeDescription(oldInfo, newInfo);
+        if (changeDescription.isChanged()) {
+          members.add(oldInfo);
+          myChangeDescriptions.put(oldInfo, changeDescription);
+        }
+      }
+    }
+
+    if (!oldMethods.isEmpty()) {
+      final SymbolTable symbolTable = myDependencyCache.getSymbolTable();
+      final Set<MethodInfo> processed = new HashSet<MethodInfo>();
+      for (final String signature : oldMethods.keySet()) {
+        final MethodInfoContainer oldMethodsContainer = oldMethods.get(signature);
+        final MethodInfoContainer newMethodsContainer = newMethods.get(signature);
+        if (newMethodsContainer != null) {
+          processed.clear();
+          if (oldMethodsContainer.size() == newMethodsContainer.size()) {
+            // first, process all corresponding method infos
+            for (MethodInfo oldInfo : oldMethodsContainer.getMethods()) {
+              MethodInfo _newInfo = null;
+              for (MethodInfo newInfo : newMethodsContainer.getMethods()) {
+                if (oldInfo.equals(newInfo)) {
+                  _newInfo = newInfo;
+                  break;
+                }
+              }
+              if (_newInfo != null) {
+                processed.add(oldInfo);
+                processed.add(_newInfo);
+                final MethodChangeDescription changeDescription = new MethodChangeDescription(oldInfo, _newInfo, symbolTable);
+                if (changeDescription.isChanged()) {
+                  members.add(oldInfo);
+                  myChangeDescriptions.put(oldInfo, changeDescription);
+                }
+              }
+            }
+          }
+          // processing the rest of infos, each pair
+          for (MethodInfo oldInfo : oldMethodsContainer.getMethods()) {
+            if (processed.contains(oldInfo)) {
+              continue;
+            }
+            for (MethodInfo newInfo : newMethodsContainer.getMethods()) {
+              if (processed.contains(newInfo)) {
+                continue;
+              }
+              final MethodChangeDescription changeDescription = new MethodChangeDescription(oldInfo, newInfo, symbolTable);
+              if (changeDescription.isChanged()) {
+                members.add(oldInfo);
+                myChangeDescriptions.put(oldInfo, changeDescription);
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  private boolean hasEquivalentMethod(Collection<MethodInfo> members, Dependency.MethodRef modelMethod) throws CacheCorruptedException {
+    final String[] modelSignature = modelMethod.getParameterDescriptors(myDependencyCache.getSymbolTable());
+    for (final MethodInfo method : members) {
+      if (modelMethod.name != method.getName()) {
+        continue;
+      }
+      final String[] methodSignature = method.getParameterDescriptors(myDependencyCache.getSymbolTable());
+      if (modelSignature.length != methodSignature.length) {
+        continue;
+      }
+
+      for (int i = 0; i < methodSignature.length; i++) {
+        if (!methodSignature[i].equals(modelSignature[i])) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Equivalent: " + modelMethod.getDescriptor(myDependencyCache.getSymbolTable()) + " <=> " +
+                      method.getDescriptor(myDependencyCache.getSymbolTable()));
+          }
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static @NonNls
+  String signatureToSourceTypeName(String signature)
+  {
+    try {
+      switch(signature.charAt(0)) {
+      case 'B' : return "byte";
+      case 'C' : return "char";
+      case 'D' : return "double";
+      case 'F' : return "float";
+      case 'I' : return "int";
+      case 'J' : return "long";
+
+      case 'L' : { // Full class name
+	int    index = signature.indexOf(';'); // Look for closing `;'
+
+	if(index < 0)
+	  throw new RuntimeException("Invalid signature: " + signature);
+
+        return signature.substring(1, index).replace('/', '.');
+      }
+
+      case 'S' : return "short";
+      case 'Z' : return "boolean";
+
+      case '[' : { // Array declaration
+	int          n;
+	StringBuffer brackets;
+	String       type;
+
+	brackets = new StringBuffer(); // Accumulate []'s
+
+	// Count opening brackets and look for optional size argument
+	for(n=0; signature.charAt(n) == '['; n++)
+	  brackets.append("[]");
+
+
+	// The rest of the string denotes a `<field_type>'
+	type = signatureToSourceTypeName(signature.substring(n));
+
+	return type + brackets.toString();
+      }
+
+      case 'V' : return "void";
+
+      default  : throw new RuntimeException("Invalid signature: `" +
+					    signature + "'");
+      }
+    } catch(StringIndexOutOfBoundsException e) { // Should never occur
+      throw new RuntimeException("Invalid signature: " + e + ":" + signature);
+    }
+  }
+
+  private Dependency[] getBackDependencies() throws CacheCorruptedException {
+    if (myBackDependencies == null) {
+      myBackDependencies = myDependencyCache.getCache().getBackDependencies(myQName);
+    }
+    return myBackDependencies;
+  }
+
+  private static class MethodInfoContainer {
+    private List<MethodInfo> myInfos = null;
+
+    protected MethodInfoContainer(MethodInfo info) {
+      myInfos = Collections.singletonList(info);
+    }
+
+    public List<MethodInfo> getMethods() {
+      return myInfos;
+    }
+
+    public int size() {
+      return myInfos.size();
+    }
+
+    public void add(MethodInfo info) {
+      if (myInfos.size() == 1) {
+        myInfos = new ArrayList<MethodInfo>(myInfos);
+      }
+      myInfos.add(info);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/MakeUtil.java b/java/compiler/impl/src/com/intellij/compiler/make/MakeUtil.java
new file mode 100644
index 0000000..52f347f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/MakeUtil.java
@@ -0,0 +1,300 @@
+/*
+ * 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.
+ */
+
+/**
+ * created at Jan 17, 2002
+ * @author Jeka
+ */
+package com.intellij.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.cls.ClsUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class MakeUtil {
+
+  private MakeUtil() {
+  }
+
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.make.MakeUtil");
+
+
+  public static VirtualFile getSourceRoot(CompileContext context, Module module, VirtualFile file) {
+    final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(module.getProject()).getFileIndex();
+    final VirtualFile root = fileIndex.getSourceRootForFile(file);
+    if (root != null) {
+      return root;
+    }
+    // try to find among roots of generated files.
+    final VirtualFile[] sourceRoots = context.getSourceRoots(module);
+    for (final VirtualFile sourceRoot : sourceRoots) {
+      if (fileIndex.isInSourceContent(sourceRoot)) {
+        continue; // skip content source roots, need only roots for generated files
+      }
+      if (VfsUtil.isAncestor(sourceRoot, file, false)) {
+        return sourceRoot;
+      }
+    }
+    return null;
+  }
+
+  /**
+   * cuts inner or anonymous class' parts and translates package names to lower case
+   */
+  private static String normalizeClassName(String qName) {
+    int index = qName.indexOf('$');
+    if (index >= 0) {
+      qName = qName.substring(0, index);
+    }
+    if (SystemInfo.isFileSystemCaseSensitive) {
+      return qName;
+    }
+    // the name of a dir should be lowercased because javac seem to allow difference in case
+    // between the physical directory and package name.
+    final int dotIndex = qName.lastIndexOf('.');
+    final StringBuilder builder = StringBuilderSpinAllocator.alloc();
+    try {
+      builder.append(qName);
+      for (int idx = 0; idx < dotIndex; idx++) {
+        builder.setCharAt(idx, Character.toLowerCase(builder.charAt(idx)));
+      }
+      return builder.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(builder);
+    }
+  }
+
+  public static boolean isAnonymous(String name) {
+    int index = name.lastIndexOf('$');
+    if (index >= 0) {
+      index++;
+      if (index < name.length()) {
+        try {
+          Integer.parseInt(name.substring(index));
+          return true;
+        }
+        catch (NumberFormatException e) {
+        }
+      }
+    }
+    return false;
+  }
+
+  /*
+     not needed currently
+  public static String getEnclosingClassName(String anonymousQName) {
+    return anonymousQName.substring(0, anonymousQName.lastIndexOf('$'));
+  }
+  */
+
+  /*
+   not needed currently
+  public static boolean isNative(int flags) {
+    return (ClsUtil.ACC_NATIVE & flags) != 0;
+  }
+  */
+
+  /**
+   * tests if the accessibility, denoted by flags1 is less restricted than the accessibility denoted by flags2
+   * @return true means flags1 is less restricted than flags2 <br>
+   *         false means flags1 define more restricted access than flags2 or they have equal accessibility
+   */
+  public static boolean isMoreAccessible(int flags1, int flags2) {
+    if (ClsUtil.isPrivate(flags2)) {
+      return ClsUtil.isPackageLocal(flags1) || ClsUtil.isProtected(flags1) || ClsUtil.isPublic(flags1);
+    }
+    if (ClsUtil.isPackageLocal(flags2)) {
+      return ClsUtil.isProtected(flags1) || ClsUtil.isPublic(flags1);
+    }
+    if (ClsUtil.isProtected(flags2)) {
+      return ClsUtil.isPublic(flags1);
+    }
+    return false;
+  }
+
+  @Nullable
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  public static String relativeClassPathToQName(String relativePath, char separator) {
+    if (!relativePath.endsWith(".class")) {
+      return null;
+    }
+    int start = 0;
+    int end = relativePath.length() - ".class".length();
+    if (relativePath.startsWith(String.valueOf(separator))) {
+      start += 1;
+    }
+    return (start <= end)? relativePath.substring(start, end).replace(separator, '.') : null;
+  }
+
+  public static @NonNls String parseObjectType(final String descriptor, int fromIndex) {
+    int semicolonIndex = descriptor.indexOf(';', fromIndex);
+    if (descriptor.charAt(fromIndex) == 'L' && semicolonIndex > fromIndex) { // isObjectType
+      return descriptor.substring(fromIndex + 1, semicolonIndex).replace('/', '.');
+    }
+    if (descriptor.charAt(fromIndex) == '[' && (descriptor.length() - fromIndex) > 0) { // isArrayType
+      return parseObjectType(descriptor, fromIndex + 1);
+    }
+    return null;
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  public static boolean isPrimitiveType(String descriptor) {
+    return
+      "V".equals(descriptor) ||
+      "B".equals(descriptor) ||
+      "C".equals(descriptor) ||
+      "D".equals(descriptor) ||
+      "F".equals(descriptor) ||
+      "I".equals(descriptor) ||
+      "J".equals(descriptor) ||
+      "S".equals(descriptor) ||
+      "Z".equals(descriptor);
+  }
+
+  public static boolean isArrayType(String descriptor) {
+    return StringUtil.startsWithChar(descriptor, '[');
+  }
+
+  public static String getComponentType(String descriptor) {
+    if (!isArrayType(descriptor)) {
+      return null;
+    }
+    return descriptor.substring(1);
+  }
+
+
+  /**
+   * @return a normalized path to source relative to a source root by class qualified name and sourcefile short name.
+   *  The path uses forward slashes "/".
+   */
+  public static String createRelativePathToSource(String qualifiedName, String srcName) {
+    qualifiedName = normalizeClassName(qualifiedName);
+    int index = qualifiedName.lastIndexOf('.');
+    if (index >= 0) {
+      srcName = qualifiedName.substring(0, index).replace('.', '/') + "/" + srcName;
+    }
+    return srcName;
+  }
+
+  public static boolean isInterface(int flags) {
+    return (ClsUtil.ACC_INTERFACE & flags) != 0;
+  }
+
+  public static int getAnnotationTargets(final Cache cache, final int annotationQName, final SymbolTable symbolTable) throws CacheCorruptedException {
+    final AnnotationConstantValue targetAnnotation = findAnnotation(
+      "java.lang.annotation.Target",
+      cache.getRuntimeVisibleAnnotations(annotationQName), symbolTable);
+    if (targetAnnotation == null) {
+      return AnnotationTargets.ALL; // all program elements are annotation targets by default
+    }
+    final AnnotationNameValuePair[] memberValues = targetAnnotation.getMemberValues();
+    ConstantValueArray value = (ConstantValueArray)memberValues[0].getValue();
+    final ConstantValue[] targets = value.getValue();
+    int annotationTargets = 0;
+    for (final ConstantValue target : targets) {
+      if (target instanceof EnumConstantValue) {
+        final String constantName = symbolTable.getSymbol(((EnumConstantValue)target).getConstantName());
+        if (AnnotationTargets.TYPE_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.TYPE;
+        }
+        if (AnnotationTargets.FIELD_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.FIELD;
+        }
+        if (AnnotationTargets.METHOD_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.METHOD;
+        }
+        if (AnnotationTargets.PARAMETER_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.PARAMETER;
+        }
+        if (AnnotationTargets.CONSTRUCTOR_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.CONSTRUCTOR;
+        }
+        if (AnnotationTargets.LOCAL_VARIABLE_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.LOCAL_VARIABLE;
+        }
+        if (AnnotationTargets.ANNOTATION_TYPE_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.ANNOTATION_TYPE;
+        }
+        if (AnnotationTargets.PACKAGE_STR.equals(constantName)) {
+          annotationTargets |= AnnotationTargets.PACKAGE;
+        }
+      }
+    }
+    return annotationTargets;
+  }
+
+  public static int getAnnotationRetentionPolicy(final int annotationQName, final Cache cache, final SymbolTable symbolTable) throws CacheCorruptedException {
+    final AnnotationConstantValue retentionPolicyAnnotation = findAnnotation(
+      "java.lang.annotation.Retention",
+      cache.getRuntimeVisibleAnnotations(annotationQName), symbolTable
+    );
+    if (retentionPolicyAnnotation == null) {
+      return RetentionPolicies.CLASS; // default retention policy
+    }
+    final AnnotationNameValuePair[] memberValues = retentionPolicyAnnotation.getMemberValues();
+    final EnumConstantValue value = (EnumConstantValue)memberValues[0].getValue();
+    final String constantName = symbolTable.getSymbol(value.getConstantName());
+    if (RetentionPolicies.SOURCE_STR.equals(constantName)) {
+      return RetentionPolicies.SOURCE;
+    }
+    if (RetentionPolicies.CLASS_STR.equals(constantName)) {
+      return RetentionPolicies.CLASS;
+    }
+    if (RetentionPolicies.RUNTIME_STR.equals(constantName)) {
+      return RetentionPolicies.RUNTIME;
+    }
+    LOG.error("Unknown retention policy: " + constantName);
+    return -1;
+  }
+
+  public static AnnotationConstantValue findAnnotation(@NonNls final String annotationQName,
+                                                       AnnotationConstantValue[] annotations, final SymbolTable symbolTable) throws CacheCorruptedException {
+    for (final AnnotationConstantValue annotation : annotations) {
+      if (annotationQName.equals(symbolTable.getSymbol(annotation.getAnnotationQName()))) {
+        return annotation;
+      }
+    }
+    return null;
+  }
+
+  public static String getModuleOutputDirPath(final Module module) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+      public String compute() {
+        final String url = CompilerModuleExtension.getInstance(module).getCompilerOutputUrl();
+        if (url == null) {
+          return null;
+        }
+        return VfsUtil.urlToPath(url);
+      }
+    });
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/MethodChangeDescription.java b/java/compiler/impl/src/com/intellij/compiler/make/MethodChangeDescription.java
new file mode 100644
index 0000000..2465703
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/MethodChangeDescription.java
@@ -0,0 +1,90 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.SymbolTable;
+import com.intellij.compiler.classParsing.ConstantValue;
+import com.intellij.compiler.classParsing.GenericMethodSignature;
+import com.intellij.compiler.classParsing.MethodInfo;
+import com.intellij.compiler.classParsing.SignatureParsingException;
+import com.intellij.util.cls.ClsUtil;
+
+import java.util.Arrays;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 7, 2004
+ */
+class MethodChangeDescription extends ChangeDescription {
+  public final boolean returnTypeDescriptorChanged;
+  public final boolean returnTypeGenericSignatureChanged;
+  public final boolean paramsGenericSignatureChanged;
+  public final boolean throwsListChanged;
+  public final boolean flagsChanged;
+  public final boolean staticPropertyChanged;
+  public final boolean accessRestricted;
+  public final boolean becameAbstract;
+  public final boolean removedAnnotationDefault;
+
+  public MethodChangeDescription(final MethodInfo oldMethod, final MethodInfo newMethod, SymbolTable symbolTable) throws CacheCorruptedException {
+    final String oldRtDescriptor = oldMethod.getReturnTypeDescriptor(symbolTable);
+    final String newRtDescriptor = newMethod.getReturnTypeDescriptor(symbolTable);
+    returnTypeDescriptorChanged = !oldRtDescriptor.equals(newRtDescriptor);
+
+    final int oldGenericSignature = oldMethod.getGenericSignature();
+    final int newGenericSignature = newMethod.getGenericSignature();
+    if (oldGenericSignature == newGenericSignature) {
+      returnTypeGenericSignatureChanged = false;
+      paramsGenericSignatureChanged = false;
+    }
+    else {
+      if (oldGenericSignature != -1 && newGenericSignature != -1) {
+        try {
+          final GenericMethodSignature _oldGenericMethodSignature = GenericMethodSignature.parse(symbolTable.getSymbol(oldGenericSignature));
+          final GenericMethodSignature _newGenericMethodSignature = GenericMethodSignature.parse(symbolTable.getSymbol(newGenericSignature));
+          returnTypeGenericSignatureChanged = !_oldGenericMethodSignature.getReturnTypeSignature().equals(_newGenericMethodSignature.getReturnTypeSignature());
+          paramsGenericSignatureChanged = !_oldGenericMethodSignature.getFormalTypeParams().equals(_newGenericMethodSignature.getFormalTypeParams()) ||
+                                          !Arrays.equals(_oldGenericMethodSignature.getParamSignatures(), _newGenericMethodSignature.getParamSignatures());
+        }
+        catch (SignatureParsingException e) {
+          throw new CacheCorruptedException(e);
+        }
+      }
+      else {
+        returnTypeGenericSignatureChanged = true;
+        paramsGenericSignatureChanged = true;
+      }
+    }
+
+    throwsListChanged = !CacheUtils.areArraysContentsEqual(oldMethod.getThrownExceptions(), newMethod.getThrownExceptions());
+
+    final int oldFlags = oldMethod.getFlags();
+    final int newFlags = newMethod.getFlags();
+    flagsChanged = oldFlags != newFlags;
+
+    staticPropertyChanged = (ClsUtil.isStatic(oldFlags) && !ClsUtil.isStatic(newFlags)) ||  (!ClsUtil.isStatic(oldFlags) && ClsUtil.isStatic(newFlags)); // was not static and became static or was static and became not static
+    accessRestricted = MakeUtil.isMoreAccessible(oldFlags, newFlags);
+    becameAbstract = !ClsUtil.isAbstract(oldFlags) && ClsUtil.isAbstract(newFlags);
+
+    final ConstantValue oldDefault = oldMethod.getAnnotationDefault();
+    final ConstantValue newDefault = newMethod.getAnnotationDefault();
+    removedAnnotationDefault = (oldDefault != null && !ConstantValue.EMPTY_CONSTANT_VALUE.equals(oldDefault)) && (newDefault == null || ConstantValue.EMPTY_CONSTANT_VALUE.equals(newDefault));
+  }
+
+  public boolean isChanged() {
+    return returnTypeDescriptorChanged || throwsListChanged || flagsChanged || returnTypeGenericSignatureChanged || paramsGenericSignatureChanged || removedAnnotationDefault;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/RetentionPolicies.java b/java/compiler/impl/src/com/intellij/compiler/make/RetentionPolicies.java
new file mode 100644
index 0000000..13cfaa5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/RetentionPolicies.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.compiler.make;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Apr 7, 2004
+ */
+public interface RetentionPolicies {
+  /**
+   * Annotations are to be discarded by the compiler.
+   */
+  int SOURCE = 0x1;
+
+  @NonNls String SOURCE_STR = "SOURCE";
+
+  /**
+   * Annotations are to be recorded in the class file by the compiler
+   * but need not be retained by the VM at run time.  This is the default
+   * behavior.
+   */
+  int CLASS = 0x2;
+
+  @NonNls String CLASS_STR = "CLASS";
+
+  /**
+   * Annotations are to be recorded in the class file by the compiler and
+   * retained by the VM at run time, so they may be read reflectively.
+   */
+  int RUNTIME = 0x4;
+
+  @NonNls String RUNTIME_STR = "RUNTIME";
+
+  int ALL = SOURCE | CLASS | RUNTIME;
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/SourceFileFinder.java b/java/compiler/impl/src/com/intellij/compiler/make/SourceFileFinder.java
new file mode 100644
index 0000000..1e17b86
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/make/SourceFileFinder.java
@@ -0,0 +1,122 @@
+/*
+ * 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.compiler.make;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.containers.HashMap;
+
+import java.util.Map;
+
+/**
+ * Assumes that source roots in the project has not changed and caches the snapshot of source roots for effective searching
+ * User: JEKA
+ * Date: Jul 17, 2003
+ * Time: 9:52:26 PM
+ */
+public class SourceFileFinder {
+  private final Project myProject;
+  private final CompileContext myCompileContext;
+  private Map<VirtualFile, String> myProjectSourceRoots = null;
+  private final CompilerConfiguration myCompilerConfiguration;
+
+  public SourceFileFinder(Project project, CompileContext compileContext) {
+    myProject = project;
+    myCompileContext = compileContext;
+    myCompilerConfiguration = CompilerConfiguration.getInstance(project);
+  }
+
+  public VirtualFile findSourceFile(String qualifiedName, final String srcName, boolean checkIfExcludedFromMake) {
+    // optimization
+    final int dollar = qualifiedName.indexOf('$');
+    final String outerQName = (dollar >= 0)? qualifiedName.substring(0, dollar) : qualifiedName;
+    final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(outerQName, GlobalSearchScope.projectScope(myProject));
+    for (PsiClass aClass : classes) {
+      final PsiFile file = aClass.getContainingFile();
+      if (srcName.equals(file.getName())) {
+        final VirtualFile vFile = file.getVirtualFile();
+        if (vFile != null && (!checkIfExcludedFromMake || !myCompilerConfiguration.isExcludedFromCompilation(vFile))) {
+          return vFile;
+        }
+      }
+    }
+
+    String relativePath = MakeUtil.createRelativePathToSource(qualifiedName, srcName);
+    Map<VirtualFile, String> dirs = getAllSourceRoots();
+    if (!StringUtil.startsWithChar(relativePath, '/')) {
+      relativePath = "/" + relativePath;
+    }
+    LocalFileSystem fs = LocalFileSystem.getInstance();
+    for (final VirtualFile virtualFile : dirs.keySet()) {
+      final String prefix = dirs.get(virtualFile);
+      String path;
+      if (prefix.length() > 0) {
+        if (FileUtil.startsWith(relativePath, prefix)) {
+          // if there is package prefix assigned to the root, the relative path should be corrected
+          path = virtualFile.getPath() + relativePath.substring(prefix.length() - 1);
+        }
+        else {
+          // if there is package prefix, but the relative path does not match it, skip the root
+          continue;
+        }
+      }
+      else {
+        path = virtualFile.getPath() + relativePath;
+      }
+      VirtualFile file = fs.findFileByPath(path);
+      if (file != null && (!checkIfExcludedFromMake || !myCompilerConfiguration.isExcludedFromCompilation(virtualFile))) {
+        return file;
+      }
+    }
+    return null;
+  }
+
+  private Map<VirtualFile, String> getAllSourceRoots() {
+    if (myProjectSourceRoots == null) {
+      myProjectSourceRoots = new HashMap<VirtualFile, String>();
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+          final Module[] allModules = ModuleManager.getInstance(myProject).getModules();
+          for (Module allModule : allModules) {
+            final VirtualFile[] sourceRoots = myCompileContext.getSourceRoots(allModule);
+            for (final VirtualFile sourceRoot : sourceRoots) {
+              String packageName = fileIndex.getPackageNameByDirectory(sourceRoot);
+              myProjectSourceRoots
+                .put(sourceRoot, packageName == null || packageName.length() == 0 ? "" : "/" + packageName.replace('.', '/') + "/");
+            }
+          }
+        }
+      });
+    }
+    return myProjectSourceRoots;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java
new file mode 100644
index 0000000..74ed9e1
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsConfigurable.java
@@ -0,0 +1,105 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+
+import javax.swing.*;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 5, 2009
+ */
+public class AnnotationProcessorsConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+
+  private final Project myProject;
+  private AnnotationProcessorsPanel myMainPanel;
+
+  public AnnotationProcessorsConfigurable(final Project project) {
+    myProject = project;
+  }
+
+  public String getDisplayName() {
+    return "Annotation Processors";
+  }
+
+  public String getHelpTopic() {
+    return "reference.projectsettings.compiler.annotationProcessors";
+  }
+
+  @NotNull
+  public String getId() {
+    return getHelpTopic();
+  }
+
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    myMainPanel = new AnnotationProcessorsPanel(myProject);
+    return myMainPanel;
+  }
+
+  public boolean isModified() {
+    final CompilerConfigurationImpl config = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+
+    if (!config.getDefaultProcessorProfile().equals(myMainPanel.getDefaultProfile())) {
+      return true;
+    }
+
+    final Map<String, ProcessorConfigProfile> configProfiles = new java.util.HashMap<String, ProcessorConfigProfile>();
+    for (ProcessorConfigProfile profile : config.getModuleProcessorProfiles()) {
+      configProfiles.put(profile.getName(), profile);
+    }
+    final List<ProcessorConfigProfile> panelProfiles = myMainPanel.getModuleProfiles();
+    if (configProfiles.size() != panelProfiles.size()) {
+      return true;
+    }
+    for (ProcessorConfigProfile panelProfile : panelProfiles) {
+      final ProcessorConfigProfile configProfile = configProfiles.get(panelProfile.getName());
+      if (configProfile == null || !configProfile.equals(panelProfile)) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  public void apply() throws ConfigurationException {
+    final CompilerConfigurationImpl config = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    config.setDefaultProcessorProfile(myMainPanel.getDefaultProfile());
+    config.setModuleProcessorProfiles(myMainPanel.getModuleProfiles());
+  }
+
+  public void reset() {
+    final CompilerConfigurationImpl config = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    myMainPanel.initProfiles(config.getDefaultProcessorProfile(), config.getModuleProcessorProfiles());
+  }
+
+  public void disposeUIResources() {
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java
new file mode 100644
index 0000000..37a8ceb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/AnnotationProcessorsPanel.java
@@ -0,0 +1,390 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.ShortcutSet;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.InputValidatorEx;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.Splitter;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.openapi.ui.popup.JBPopupFactory;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.AnActionButton;
+import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.IdeBorderFactory;
+import com.intellij.ui.ToolbarDecorator;
+import com.intellij.ui.awt.RelativePoint;
+import com.intellij.ui.components.JBList;
+import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.ui.EditableTreeModel;
+import com.intellij.util.ui.tree.TreeUtil;
+import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+import org.jetbrains.jps.model.java.impl.compiler.ProcessorConfigProfileImpl;
+
+import javax.swing.*;
+import javax.swing.event.TreeSelectionEvent;
+import javax.swing.event.TreeSelectionListener;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+import java.awt.event.MouseEvent;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Konstantin Bulenkov
+ */
+@SuppressWarnings({"unchecked", "UseOfObsoleteCollectionType"})
+public class AnnotationProcessorsPanel extends JPanel {
+  private final ProcessorConfigProfile myDefaultProfile = new ProcessorConfigProfileImpl("");
+  private final List<ProcessorConfigProfile> myModuleProfiles = new ArrayList<ProcessorConfigProfile>();
+  private final Map<String, Module> myAllModulesMap = new HashMap<String, Module>();
+  private final Project myProject;
+  private final Tree myTree;
+  private final ProcessorProfilePanel myProfilePanel;
+  private ProcessorConfigProfile mySelectedProfile = null;
+
+  public AnnotationProcessorsPanel(Project project) {
+    super(new BorderLayout());
+    Splitter splitter = new Splitter(false, 0.3f);
+    add(splitter, BorderLayout.CENTER);
+    myProject = project;
+    for (Module module : ModuleManager.getInstance(project).getModules()) {
+      myAllModulesMap.put(module.getName(), module);
+    }
+    myTree = new Tree(new MyTreeModel());
+    myTree.setRootVisible(false);
+        final JPanel treePanel =
+          ToolbarDecorator.createDecorator(myTree).addExtraAction(new AnActionButton("Move to", AllIcons.Actions.Nextfile) {
+            @Override
+            public void actionPerformed(AnActionEvent e) {
+              final MyModuleNode node = (MyModuleNode)myTree.getSelectionPath().getLastPathComponent();
+              final TreePath[] selectedNodes = myTree.getSelectionPaths();
+              final ProcessorConfigProfile nodeProfile = ((ProfileNode)node.getParent()).myProfile;
+              final List<ProcessorConfigProfile> profiles = new ArrayList<ProcessorConfigProfile>();
+              profiles.add(myDefaultProfile);
+              for (ProcessorConfigProfile profile : myModuleProfiles) {
+                profiles.add(profile);
+              }
+              profiles.remove(nodeProfile);
+              final JBList list = new JBList(profiles);
+              final JBPopup popup = JBPopupFactory.getInstance().createListPopupBuilder(list)
+                .setTitle("Move to")
+                .setItemChoosenCallback(new Runnable() {
+                  @Override
+                  public void run() {
+                    final Object value = list.getSelectedValue();
+                    if (value instanceof ProcessorConfigProfile) {
+                      final ProcessorConfigProfile chosenProfile = (ProcessorConfigProfile)value;
+                      final Module toSelect = (Module)node.getUserObject();
+                      if (selectedNodes != null) {
+                        for (TreePath selectedNode : selectedNodes) {
+                          final Object node = selectedNode.getLastPathComponent();
+                          if (node instanceof MyModuleNode) {
+                            final Module module = (Module)((MyModuleNode)node).getUserObject();
+                            if (nodeProfile != myDefaultProfile) {
+                              nodeProfile.removeModuleName(module.getName());
+                            }
+                            if (chosenProfile != myDefaultProfile) {
+                              chosenProfile.addModuleName(module.getName());
+                            }
+                          }
+                        }
+                      }
+
+                      final RootNode root = (RootNode)myTree.getModel().getRoot();
+                      root.sync();
+                      final DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(root, toSelect);
+                      if (node != null) {
+                        TreeUtil.selectNode(myTree, node);
+                      }
+                    }
+                  }
+                })
+                .createPopup();
+              RelativePoint point =
+                e.getInputEvent() instanceof MouseEvent ? getPreferredPopupPoint() : TreeUtil.getPointForSelection(myTree);
+              popup.show(point);
+            }
+
+            @Override
+            public ShortcutSet getShortcut() {
+              return ActionManager.getInstance().getAction("Move").getShortcutSet();
+            }
+
+            @Override
+            public boolean isEnabled() {
+              return myTree.getSelectionPath() != null
+                     && myTree.getSelectionPath().getLastPathComponent() instanceof MyModuleNode
+                     && !myModuleProfiles.isEmpty();
+            }
+          }).createPanel();
+    splitter.setFirstComponent(treePanel);
+    myTree.setCellRenderer(new MyCellRenderer());
+
+    myTree.addTreeSelectionListener(new TreeSelectionListener() {
+      @Override
+      public void valueChanged(TreeSelectionEvent e) {
+        final TreePath path = myTree.getSelectionPath();
+        if (path != null) {
+          Object node = path.getLastPathComponent();
+          if (node instanceof MyModuleNode) {
+            node = ((MyModuleNode)node).getParent();
+          }
+          if (node instanceof ProfileNode) {
+            final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile;
+            final ProcessorConfigProfile selectedProfile = mySelectedProfile;
+            if (nodeProfile != selectedProfile) {
+              if (selectedProfile != null) {
+                myProfilePanel.saveTo(selectedProfile);
+              }
+              mySelectedProfile = nodeProfile;
+              myProfilePanel.setProfile(nodeProfile);
+            }
+          }
+        }
+      }
+    });
+    myProfilePanel = new ProcessorProfilePanel(project);
+    myProfilePanel.setBorder(IdeBorderFactory.createEmptyBorder(0, 6, 0, 0));
+    splitter.setSecondComponent(myProfilePanel);
+  }
+
+  public void initProfiles(ProcessorConfigProfile defaultProfile, Collection<ProcessorConfigProfile> moduleProfiles) {
+    myDefaultProfile.initFrom(defaultProfile);
+    myModuleProfiles.clear();
+    for (ProcessorConfigProfile profile : moduleProfiles) {
+      ProcessorConfigProfile copy = new ProcessorConfigProfileImpl("");
+      copy.initFrom(profile);
+      myModuleProfiles.add(copy);
+    }
+    final RootNode root = (RootNode)myTree.getModel().getRoot();
+    root.sync();
+    final DefaultMutableTreeNode node = TreeUtil.findNodeWithObject(root, myDefaultProfile);
+    if (node != null) {
+      TreeUtil.selectNode(myTree, node);
+    }
+
+  }
+
+  public ProcessorConfigProfile getDefaultProfile() {
+    final ProcessorConfigProfile selectedProfile = mySelectedProfile;
+    if (myDefaultProfile == selectedProfile) {
+      myProfilePanel.saveTo(selectedProfile);
+    }
+    return myDefaultProfile;
+  }
+
+  public List<ProcessorConfigProfile> getModuleProfiles() {
+    final ProcessorConfigProfile selectedProfile = mySelectedProfile;
+    if (myDefaultProfile != selectedProfile) {
+      myProfilePanel.saveTo(selectedProfile);
+    }
+    return myModuleProfiles;
+  }
+
+  private static void expand(JTree tree) {
+    int oldRowCount = 0;
+    do {
+      int rowCount = tree.getRowCount();
+      if (rowCount == oldRowCount) break;
+      oldRowCount = rowCount;
+      for (int i = 0; i < rowCount; i++) {
+        tree.expandRow(i);
+      }
+    }
+    while (true);
+  }
+
+  private class MyTreeModel extends DefaultTreeModel implements EditableTreeModel{
+    public MyTreeModel() {
+      super(new RootNode());
+    }
+
+    @Override
+    public TreePath addNode(TreePath parentOrNeighbour) {
+      final String newProfileName = Messages.showInputDialog(
+        myProject, "Profile name", "Create new profile", null, "",
+        new InputValidatorEx() {
+          @Override
+          public boolean checkInput(String inputString) {
+            if (StringUtil.isEmpty(inputString) ||
+                Comparing.equal(inputString, myDefaultProfile.getName())) {
+              return false;
+            }
+            for (ProcessorConfigProfile profile : myModuleProfiles) {
+              if (Comparing.equal(inputString, profile.getName())) {
+                return false;
+              }
+            }
+            return true;
+          }
+
+          @Override
+          public boolean canClose(String inputString) {
+            return checkInput(inputString);
+          }
+
+          @Override
+          public String getErrorText(String inputString) {
+            if (checkInput(inputString)) {
+              return null;
+            }
+            return StringUtil.isEmpty(inputString)
+                   ? "Profile name shouldn't be empty"
+                   : "Profile " + inputString + " already exists";
+          }
+        });
+      if (newProfileName != null) {
+        final ProcessorConfigProfile profile = new ProcessorConfigProfileImpl(newProfileName);
+        myModuleProfiles.add(profile);
+        ((DataSynchronizable)getRoot()).sync();
+        final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), profile);
+        if (object != null) {
+          TreeUtil.selectNode(myTree, object);
+        }
+      }
+      return null;
+    }
+
+    @Override
+    public void removeNode(TreePath nodePath) {
+      Object node = nodePath.getLastPathComponent();
+      if (node instanceof ProfileNode) {
+        final ProcessorConfigProfile nodeProfile = ((ProfileNode)node).myProfile;
+        if (nodeProfile != myDefaultProfile) {
+          if (mySelectedProfile == nodeProfile) {
+            mySelectedProfile = null;
+          }
+          myModuleProfiles.remove(nodeProfile);
+          ((DataSynchronizable)getRoot()).sync();
+          final DefaultMutableTreeNode object = TreeUtil.findNodeWithObject((DefaultMutableTreeNode)getRoot(), myDefaultProfile);
+          if (object != null) {
+            TreeUtil.selectNode(myTree, object);
+          }
+        }
+      }
+    }
+
+    @Override
+    public void moveNodeTo(TreePath parentOrNeighbour) {
+    }
+
+  }
+
+
+  private class RootNode extends DefaultMutableTreeNode implements DataSynchronizable {
+    @Override
+    public DataSynchronizable sync() {
+      final Vector newKids =  new Vector();
+      newKids.add(new ProfileNode(myDefaultProfile, this, true).sync());
+      for (ProcessorConfigProfile profile : myModuleProfiles) {
+        newKids.add(new ProfileNode(profile, this, false).sync());
+      }
+      children = newKids;
+      ((DefaultTreeModel)myTree.getModel()).reload();
+      expand(myTree);
+      return this;
+    }
+  }
+
+  private interface DataSynchronizable {
+    DataSynchronizable sync();
+  }
+
+  private class ProfileNode extends DefaultMutableTreeNode implements DataSynchronizable {
+    private final ProcessorConfigProfile myProfile;
+    private final boolean myIsDefault;
+
+    public ProfileNode(ProcessorConfigProfile profile, RootNode parent, boolean isDefault) {
+      super(profile);
+      setParent(parent);
+      myIsDefault = isDefault;
+      myProfile = profile;
+    }
+
+    @Override
+    public DataSynchronizable sync() {
+      final List<Module> nodeModules = new ArrayList<Module>();
+      if (myIsDefault) {
+        final Set<String> nonDefaultProfileModules = new HashSet<String>();
+        for (ProcessorConfigProfile profile : myModuleProfiles) {
+          nonDefaultProfileModules.addAll(profile.getModuleNames());
+        }
+        for (Map.Entry<String, Module> entry : myAllModulesMap.entrySet()) {
+          if (!nonDefaultProfileModules.contains(entry.getKey())) {
+            nodeModules.add(entry.getValue());
+          }
+        }
+      }
+      else {
+        for (String moduleName : myProfile.getModuleNames()) {
+          final Module module = myAllModulesMap.get(moduleName);
+          if (module != null) {
+            nodeModules.add(module);
+          }
+        }
+      }
+      Collections.sort(nodeModules, ModuleComparator.INSTANCE);
+      final Vector vector = new Vector();
+      for (Module module : nodeModules) {
+        vector.add(new MyModuleNode(module, this));
+      }
+      children = vector;
+      return this;
+    }
+
+  }
+
+  private static class MyModuleNode extends DefaultMutableTreeNode {
+    public MyModuleNode(Module module, ProfileNode parent) {
+      super(module);
+      setParent(parent);
+      setAllowsChildren(false);
+    }
+  }
+
+  private static class MyCellRenderer extends ColoredTreeCellRenderer {
+    @Override
+    public void customizeCellRenderer(JTree tree, Object value, boolean selected, boolean expanded, boolean leaf, int row, boolean hasFocus) {
+      if (value instanceof ProfileNode) {
+        append(((ProfileNode)value).myProfile.getName());
+      }
+      else if (value instanceof MyModuleNode) {
+        final Module module = (Module)((MyModuleNode)value).getUserObject();
+        setIcon(AllIcons.Nodes.Module);
+        append(module.getName());
+      }
+    }
+  }
+
+  private static class ModuleComparator implements Comparator<Module> {
+    static final ModuleComparator INSTANCE = new ModuleComparator();
+    @Override
+    public int compare(Module o1, Module o2) {
+      return o1.getName().compareTo(o2.getName());
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ComparingUtils.java b/java/compiler/impl/src/com/intellij/compiler/options/ComparingUtils.java
new file mode 100644
index 0000000..bac1d24
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/ComparingUtils.java
@@ -0,0 +1,53 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.ui.RawCommandLineEditor;
+
+import javax.swing.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class ComparingUtils {
+  public static boolean isModified(TextFieldWithBrowseButton field, String value) {
+    return !field.getText().equals(value);
+  }
+
+  public static boolean isModified(JCheckBox checkBox, boolean value) {
+    return checkBox.isSelected() != value;
+  }
+
+  public static boolean isModified(JTextField textField, int value) {
+    try {
+      int fieldValue = Integer.parseInt(textField.getText().trim());
+      return fieldValue != value;
+    }
+    catch(NumberFormatException e) {
+      return false;
+    }
+  }
+
+  public static boolean isModified(RawCommandLineEditor editor, String value) {
+    return !editor.getText().equals(value);
+  }
+
+  public static boolean isModified(JTextField textField, String value) {
+    return !textField.getText().equals(value);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerConfigurable.java
new file mode 100644
index 0000000..3cb2305
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerConfigurable.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.compiler.options;
+
+import com.intellij.compiler.CompilerSettingsFactory;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+public class CompilerConfigurable implements SearchableConfigurable.Parent, Configurable.NoScroll {
+
+  private final Project myProject;
+  private final CompilerUIConfigurable myCompilerUIConfigurable;
+  private Configurable[] myKids;
+
+  public CompilerConfigurable(Project project) {
+    myProject = project;
+    myCompilerUIConfigurable = new CompilerUIConfigurable(myProject);
+  }
+
+  public String getDisplayName() {
+    return CompilerBundle.message("compiler.configurable.display.name");
+  }
+
+  public String getHelpTopic() {
+    return "project.propCompiler";
+  }
+
+  @NotNull
+  public String getId() {
+    return getHelpTopic();
+  }
+
+  @Nullable
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myCompilerUIConfigurable.createComponent();
+  }
+
+  public boolean hasOwnContent() {
+    return true;
+  }
+
+  public boolean isVisible() {
+    return true;
+  }
+
+  public boolean isModified() {
+    return myCompilerUIConfigurable.isModified();
+  }
+
+  public void apply() throws ConfigurationException {
+    myCompilerUIConfigurable.apply();
+  }
+
+  public void reset() {
+    myCompilerUIConfigurable.reset();
+  }
+
+  public void disposeUIResources() {
+    myCompilerUIConfigurable.disposeUIResources();
+  }
+
+  public Configurable[] getConfigurables() {
+    if (myKids == null) {
+      final CompilerSettingsFactory[] factories = Extensions.getExtensions(CompilerSettingsFactory.EP_NAME, myProject);
+      myKids = ContainerUtil.mapNotNull(factories, new NullableFunction<CompilerSettingsFactory, Configurable>() {
+        @Nullable
+        @Override
+        public Configurable fun(CompilerSettingsFactory factory) {
+            return factory.create(myProject);
+        }
+      }, new Configurable[0]);
+    }
+
+    return myKids;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
new file mode 100644
index 0000000..729a320
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerOptionsPanel.form
@@ -0,0 +1,154 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.CompilerUIConfigurable">
+  <grid id="1663f" binding="myPanel" layout-manager="GridLayoutManager" row-count="10" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="28" y="24" width="883" height="379"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <vspacer id="67edf">
+        <constraints>
+          <grid row="9" column="0" row-span="1" col-span="3" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <grid id="b341d" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="b0748" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="label.option.resource.patterns.text"/>
+            </properties>
+          </component>
+          <component id="263f1" class="javax.swing.JTextField" binding="myResourcePatternsField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties>
+              <focusable value="true"/>
+              <margin top="0" left="2" bottom="0" right="0"/>
+              <text value="" noi18n="true"/>
+            </properties>
+          </component>
+          <component id="78174" class="com.intellij.ui.components.JBLabel" binding="myPatternLegendLabel">
+            <constraints>
+              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="8" fill="0" indent="1" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <componentStyle value="SMALL"/>
+              <fontColor value="BRIGHTER"/>
+              <text value="label"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <component id="889a8" class="javax.swing.JCheckBox" binding="myCbClearOutputDirectory">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="label.option.clear.output.directory.on.rebuild"/>
+        </properties>
+      </component>
+      <component id="366e" class="javax.swing.JCheckBox" binding="myCbAssertNotNull">
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="add.notnull.assertions"/>
+        </properties>
+      </component>
+      <component id="348ee" class="javax.swing.JCheckBox" binding="myCbAutoShowFirstError">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text resource-bundle="messages/CompilerBundle" key="label.option.autoshow.first.error"/>
+        </properties>
+      </component>
+      <component id="ce617" class="javax.swing.JCheckBox" binding="myCbUseExternalBuild" default-binding="true">
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Use external build"/>
+        </properties>
+      </component>
+      <component id="b9b2d" class="javax.swing.JCheckBox" binding="myCbEnableAutomake">
+        <constraints>
+          <grid row="5" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Make project automatically"/>
+        </properties>
+      </component>
+      <component id="17126" class="javax.swing.JLabel" binding="myHeapSizeLabel">
+        <constraints>
+          <grid row="7" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Compiler process heap size (Mbytes):"/>
+        </properties>
+      </component>
+      <component id="a28b8" class="javax.swing.JTextField" binding="myHeapSizeField">
+        <constraints>
+          <grid row="7" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="0" indent="0" use-parent-layout="false">
+            <preferred-size width="50" height="-1"/>
+          </grid>
+        </constraints>
+        <properties/>
+      </component>
+      <component id="5b86a" class="javax.swing.JLabel" binding="myVMOptionsLabel">
+        <constraints>
+          <grid row="8" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Additional compiler process VM options:"/>
+        </properties>
+      </component>
+      <component id="b5547" class="javax.swing.JTextField" binding="myVMOptionsField">
+        <constraints>
+          <grid row="8" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+            <preferred-size width="150" height="-1"/>
+          </grid>
+        </constraints>
+        <properties/>
+      </component>
+      <component id="ba694" class="javax.swing.JCheckBox" binding="myCbParallelCompilation">
+        <constraints>
+          <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="2" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Compile independent modules in parallel"/>
+        </properties>
+      </component>
+      <component id="91979" class="javax.swing.JLabel">
+        <constraints>
+          <grid row="6" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="(may require larger heap size)"/>
+        </properties>
+      </component>
+      <component id="732b1" class="javax.swing.JLabel">
+        <constraints>
+          <grid row="5" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="(only works while not running / debugging)"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
new file mode 100644
index 0000000..21863bd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/CompilerUIConfigurable.java
@@ -0,0 +1,216 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.MalformedPatternException;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.Gray;
+import com.intellij.ui.JBColor;
+import com.intellij.ui.components.JBLabel;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.StringTokenizer;
+
+public class CompilerUIConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.options.CompilerUIConfigurable");
+  private JPanel myPanel;
+  private final Project myProject;
+
+  private JTextField myResourcePatternsField;
+  private JCheckBox myCbClearOutputDirectory;
+  private JCheckBox myCbAssertNotNull;
+  private JBLabel myPatternLegendLabel;
+  private JCheckBox myCbAutoShowFirstError;
+  private JCheckBox myCbUseExternalBuild;
+  private JCheckBox myCbEnableAutomake;
+  private JCheckBox myCbParallelCompilation;
+  private JTextField myHeapSizeField;
+  private JTextField myVMOptionsField;
+  private JLabel myHeapSizeLabel;
+  private JLabel myVMOptionsLabel;
+
+  public CompilerUIConfigurable(final Project project) {
+    myProject = project;
+
+    myPatternLegendLabel.setText("<html><body>" +
+                                 "Use <b>;</b> to separate patterns and <b>!</b> to negate a pattern. " +
+                                 "Accepted wildcards: <b>?</b> &mdash; exactly one symbol; <b>*</b> &mdash; zero or more symbols; " +
+                                 "<b>/</b> &mdash; path separator; <b>/**/</b> &mdash; any number of directories; " +
+                                 "<i>&lt;dir_name&gt;</i>:<i>&lt;pattern&gt;</i> &mdash; restrict to source roots with the specified name" +
+                                 "</body></html>");
+    myPatternLegendLabel.setForeground(new JBColor(Gray._50, Gray._130));
+    myCbUseExternalBuild.addItemListener(new ItemListener() {
+      @Override
+      public void itemStateChanged(ItemEvent e) {
+        updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
+      }
+    });
+  }
+
+  public void reset() {
+
+    final CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
+    myCbAutoShowFirstError.setSelected(workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
+    myCbClearOutputDirectory.setSelected(workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
+    myCbAssertNotNull.setSelected(configuration.isAddNotNullAssertions());
+    myCbUseExternalBuild.setSelected(workspaceConfiguration.USE_COMPILE_SERVER);
+    myCbEnableAutomake.setSelected(workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
+    myCbParallelCompilation.setSelected(workspaceConfiguration.PARALLEL_COMPILATION);
+    myHeapSizeField.setText(String.valueOf(workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE));
+    final String options = workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
+    myVMOptionsField.setText(options == null? "" : options.trim());
+    updateExternalMakeOptionControls(myCbUseExternalBuild.isSelected());
+
+    configuration.convertPatterns();
+
+    myResourcePatternsField.setText(patternsToString(configuration.getResourceFilePatterns()));
+  }
+
+  private static String patternsToString(final String[] patterns) {
+    final StringBuilder extensionsString = new StringBuilder();
+    for (int idx = 0; idx < patterns.length; idx++) {
+      if (idx > 0) {
+        extensionsString.append(";");
+      }
+      extensionsString.append(patterns[idx]);
+    }
+    return extensionsString.toString();
+  }
+
+  public void apply() throws ConfigurationException {
+
+    CompilerConfigurationImpl configuration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
+    workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR = myCbAutoShowFirstError.isSelected();
+    workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY = myCbClearOutputDirectory.isSelected();
+    boolean wasUsingExternalMake = workspaceConfiguration.USE_COMPILE_SERVER;
+    workspaceConfiguration.USE_COMPILE_SERVER = myCbUseExternalBuild.isSelected();
+    workspaceConfiguration.MAKE_PROJECT_ON_SAVE = myCbEnableAutomake.isSelected();
+    workspaceConfiguration.PARALLEL_COMPILATION = myCbParallelCompilation.isSelected();
+    try {
+      workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE = Integer.parseInt(myHeapSizeField.getText().trim());
+    }
+    catch (NumberFormatException ignored) {
+      LOG.info(ignored);
+    }
+    workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = myVMOptionsField.getText().trim();
+
+    configuration.setAddNotNullAssertions(myCbAssertNotNull.isSelected());
+    configuration.removeResourceFilePatterns();
+    String extensionString = myResourcePatternsField.getText().trim();
+    applyResourcePatterns(extensionString, (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject));
+    if (wasUsingExternalMake != workspaceConfiguration.USE_COMPILE_SERVER) {
+      myProject.getMessageBus().syncPublisher(ExternalBuildOptionListener.TOPIC).externalBuildOptionChanged(workspaceConfiguration.USE_COMPILE_SERVER);
+    }
+  }
+
+  private static void applyResourcePatterns(String extensionString, final CompilerConfigurationImpl configuration)
+    throws ConfigurationException {
+    StringTokenizer tokenizer = new StringTokenizer(extensionString, ";", false);
+    List<String[]> errors = new ArrayList<String[]>();
+
+    while (tokenizer.hasMoreTokens()) {
+      String namePattern = tokenizer.nextToken();
+      try {
+        configuration.addResourceFilePattern(namePattern);
+      }
+      catch (MalformedPatternException e) {
+        errors.add(new String[]{namePattern, e.getLocalizedMessage()});
+      }
+    }
+
+    if (errors.size() > 0) {
+      final StringBuilder pattersnsWithErrors = new StringBuilder();
+      for (final Object error : errors) {
+        String[] pair = (String[])error;
+        pattersnsWithErrors.append("\n");
+        pattersnsWithErrors.append(pair[0]);
+        pattersnsWithErrors.append(": ");
+        pattersnsWithErrors.append(pair[1]);
+      }
+
+      throw new ConfigurationException(
+        CompilerBundle.message("error.compiler.configurable.malformed.patterns", pattersnsWithErrors.toString()), CompilerBundle.message("bad.resource.patterns.dialog.title")
+      );
+    }
+  }
+
+  public boolean isModified() {
+    boolean isModified = false;
+    final CompilerWorkspaceConfiguration workspaceConfiguration = CompilerWorkspaceConfiguration.getInstance(myProject);
+    isModified |= ComparingUtils.isModified(myCbAutoShowFirstError, workspaceConfiguration.AUTO_SHOW_ERRORS_IN_EDITOR);
+    isModified |= ComparingUtils.isModified(myCbUseExternalBuild, workspaceConfiguration.USE_COMPILE_SERVER);
+    isModified |= ComparingUtils.isModified(myCbEnableAutomake, workspaceConfiguration.MAKE_PROJECT_ON_SAVE);
+    isModified |= ComparingUtils.isModified(myCbParallelCompilation, workspaceConfiguration.PARALLEL_COMPILATION);
+    isModified |= ComparingUtils.isModified(myHeapSizeField, workspaceConfiguration.COMPILER_PROCESS_HEAP_SIZE);
+    isModified |= ComparingUtils.isModified(myVMOptionsField, workspaceConfiguration.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS);
+
+    final CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(myProject);
+    isModified |= ComparingUtils.isModified(myCbAssertNotNull, compilerConfiguration.isAddNotNullAssertions());
+    isModified |= ComparingUtils.isModified(myCbClearOutputDirectory, workspaceConfiguration.CLEAR_OUTPUT_DIRECTORY);
+    isModified |= ComparingUtils.isModified(myResourcePatternsField, patternsToString(compilerConfiguration.getResourceFilePatterns()));
+
+    return isModified;
+  }
+
+  public String getDisplayName() {
+    return "General";
+  }
+
+  public String getHelpTopic() {
+    return null;
+  }
+
+  @NotNull
+  public String getId() {
+    return "compiler.general";
+  }
+
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public void disposeUIResources() {
+  }
+
+  private void updateExternalMakeOptionControls(boolean enabled) {
+    myCbEnableAutomake.setEnabled(enabled);
+    myCbParallelCompilation.setEnabled(enabled);
+    myHeapSizeField.setEnabled(enabled);
+    myVMOptionsField.setEnabled(enabled);
+    myHeapSizeLabel.setEnabled(enabled);
+    myVMOptionsLabel.setEnabled(enabled);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ExternalBuildOptionListener.java b/java/compiler/impl/src/com/intellij/compiler/options/ExternalBuildOptionListener.java
new file mode 100644
index 0000000..c3c92ad
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/ExternalBuildOptionListener.java
@@ -0,0 +1,29 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.util.messages.Topic;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface ExternalBuildOptionListener extends EventListener {
+  Topic<ExternalBuildOptionListener> TOPIC = Topic.create("External build option", ExternalBuildOptionListener.class);
+
+  void externalBuildOptionChanged(boolean externalBuildEnabled);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.form b/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.form
new file mode 100644
index 0000000..40c0fc0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.form
@@ -0,0 +1,61 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.JavaCompilersTab">
+  <grid id="3d361" binding="myPanel" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="63" y="62" width="325" height="176"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="d786c" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="9fc5b" class="javax.swing.JLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <labelFor value="99748"/>
+              <text resource-bundle="messages/CompilerBundle" key="option.use.compiler.text"/>
+            </properties>
+          </component>
+          <component id="99748" class="javax.swing.JComboBox" binding="myCompiler">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties/>
+          </component>
+        </children>
+      </grid>
+      <xy id="12adb" binding="myContentPanel" layout-manager="XYLayout" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="1" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </xy>
+      <grid id="a6152" binding="myTargetOptionsPanel" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children/>
+      </grid>
+      <vspacer id="7c703">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.java b/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.java
new file mode 100644
index 0000000..09adaba
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/JavaCompilersTab.java
@@ -0,0 +1,170 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.compiler.impl.javaCompiler.BackendCompiler;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.ui.ListCellRendererWrapper;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Vector;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class JavaCompilersTab implements SearchableConfigurable, Configurable.NoScroll {
+  private JPanel myPanel;
+  private JPanel myContentPanel;
+  private JComboBox myCompiler;
+  private JPanel myTargetOptionsPanel;
+  private final CardLayout myCardLayout;
+
+  private final Project myProject;
+  private final BackendCompiler myDefaultCompiler;
+  private BackendCompiler mySelectedCompiler;
+  private final CompilerConfigurationImpl myCompilerConfiguration;
+  private final Collection<Configurable> myConfigurables;
+  private final TargetOptionsComponent myTargetLevelComponent;
+
+  public JavaCompilersTab(final Project project) {
+    this(project, ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getRegisteredJavaCompilers(),
+         ((CompilerConfigurationImpl)CompilerConfiguration.getInstance(project)).getDefaultCompiler());
+  }
+
+  public JavaCompilersTab(final Project project, Collection<BackendCompiler> compilers, BackendCompiler defaultCompiler) {
+    myProject = project;
+    myDefaultCompiler = defaultCompiler;
+    myCompilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    myConfigurables = new ArrayList<Configurable>(compilers.size());
+
+    myCardLayout = new CardLayout();
+    myContentPanel.setLayout(myCardLayout);
+
+    myTargetOptionsPanel.setLayout(new BorderLayout());
+    myTargetLevelComponent = new TargetOptionsComponent(project);
+    myTargetOptionsPanel.add(myTargetLevelComponent, BorderLayout.CENTER);
+
+    for (BackendCompiler compiler : compilers) {
+      Configurable configurable = compiler.createConfigurable();
+      myConfigurables.add(configurable);
+
+      myContentPanel.add(configurable.createComponent(), compiler.getId());
+    }
+    myCompiler.setModel(new DefaultComboBoxModel(new Vector(compilers)));
+    myCompiler.setRenderer(new ListCellRendererWrapper<BackendCompiler>() {
+      @Override
+      public void customize(final JList list, final BackendCompiler value, final int index, final boolean selected, final boolean hasFocus) {
+        setText(value != null ? value.getPresentableName() : "");
+      }
+    });
+    myCompiler.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        final BackendCompiler compiler = (BackendCompiler)myCompiler.getSelectedItem();
+        if (compiler != null) {
+          selectCompiler(compiler);
+        }
+      }
+    });
+  }
+
+  public String getDisplayName() {
+    return CompilerBundle.message("java.compiler.description");
+  }
+
+  public String getHelpTopic() {
+    return "reference.projectsettings.compiler.javacompiler";
+  }
+
+  @NotNull
+  public String getId() {
+    return getHelpTopic();
+  }
+
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public boolean isModified() {
+    if (!Comparing.equal(mySelectedCompiler, myCompilerConfiguration.getDefaultCompiler())) {
+      return true;
+    }
+    for (Configurable configurable : myConfigurables) {
+      if (configurable.isModified()) {
+        return true;
+      }
+    }
+    if (!Comparing.equal(myTargetLevelComponent.getProjectBytecodeTarget(), myCompilerConfiguration.getProjectBytecodeTarget())) {
+      return true;
+    }
+    if (!Comparing.equal(myTargetLevelComponent.getModulesBytecodeTargetMap(), myCompilerConfiguration.getModulesBytecodeTargetMap())) {
+      return true;
+    }
+    return false;
+  }
+
+  public void apply() throws ConfigurationException {
+    for (Configurable configurable : myConfigurables) {
+      configurable.apply();
+    }
+    myCompilerConfiguration.setDefaultCompiler(mySelectedCompiler);
+    myCompilerConfiguration.setProjectBytecodeTarget(myTargetLevelComponent.getProjectBytecodeTarget());
+    myCompilerConfiguration.setModulesBytecodeTargetMap(myTargetLevelComponent.getModulesBytecodeTargetMap());
+
+    myTargetLevelComponent.setProjectBytecodeTargetLevel(myCompilerConfiguration.getProjectBytecodeTarget());
+    myTargetLevelComponent.setModuleTargetLevels(myCompilerConfiguration.getModulesBytecodeTargetMap());
+  }
+
+  public void reset() {
+    for (Configurable configurable : myConfigurables) {
+      configurable.reset();
+    }
+    selectCompiler(myCompilerConfiguration.getDefaultCompiler());
+    myTargetLevelComponent.setProjectBytecodeTargetLevel(myCompilerConfiguration.getProjectBytecodeTarget());
+    myTargetLevelComponent.setModuleTargetLevels(myCompilerConfiguration.getModulesBytecodeTargetMap());
+  }
+
+  public void disposeUIResources() {
+  }
+
+  private void selectCompiler(BackendCompiler compiler) {
+    if(compiler == null) {
+      compiler = myDefaultCompiler;
+    }
+    myCompiler.setSelectedItem(compiler);
+    mySelectedCompiler = compiler;
+    myCardLayout.show(myContentPanel, compiler.getId());
+    myContentPanel.revalidate();
+    myContentPanel.repaint();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ProcessedModulesTable.java b/java/compiler/impl/src/com/intellij/compiler/options/ProcessedModulesTable.java
new file mode 100644
index 0000000..f95025b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/ProcessedModulesTable.java
@@ -0,0 +1,439 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.ui.SpeedSearchBase;
+import com.intellij.ui.SpeedSearchComparator;
+import com.intellij.ui.TableUtil;
+import com.intellij.ui.ToolbarDecorator;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.ui.EditableModel;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+public class ProcessedModulesTable extends JPanel {
+  private JBTable myTable = null;
+  private MyTableModel myTableModel = null;
+
+  public ProcessedModulesTable(final Project project) {
+    super(new BorderLayout());
+
+    myTableModel = new MyTableModel(project);
+    myTable = new JBTable(myTableModel);
+    myTable.getEmptyText().setText("No modules configured");
+
+    //myTable.setShowGrid(false);
+    myTable.setIntercellSpacing(new Dimension(0, 0));
+    myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    myTable.setColumnSelectionAllowed(false);
+
+    final TableColumnModel columnModel = myTable.getColumnModel();
+
+    final TableColumn dirNameColumn = columnModel.getColumn(myTableModel.DIRNAME_COLUMN_INDEX);
+    final String title = "Generated Sources Directory Name";
+    dirNameColumn.setHeaderValue(title);
+    final JTableHeader tableHeader = myTable.getTableHeader();
+    final FontMetrics metrics = tableHeader.getFontMetrics(tableHeader.getFont());
+    final int preferredWidth = metrics.stringWidth(title) + 12;
+    dirNameColumn.setPreferredWidth(preferredWidth);
+    dirNameColumn.setMaxWidth(preferredWidth + 20);
+    dirNameColumn.setCellRenderer(new MyElementColumnCellRenderer());
+
+    final TableColumn moduleColumn = columnModel.getColumn(myTableModel.ELEMENT_COLUMN_INDEX);
+    moduleColumn.setHeaderValue("Module");
+    moduleColumn.setCellRenderer(new MyElementColumnCellRenderer());
+
+    final JPanel panel = ToolbarDecorator.createDecorator(myTable)
+      .disableUpDownActions()
+      .setPreferredSize(new Dimension(100, 155))
+      .createPanel();
+    add(panel, BorderLayout.CENTER);
+
+    final SpeedSearchBase<JBTable> speedSearch = new SpeedSearchBase<JBTable>(myTable) {
+      public int getSelectedIndex() {
+        return myTable.getSelectedRow();
+      }
+
+      @Override
+      protected int convertIndexToModel(int viewIndex) {
+        return myTable.convertRowIndexToModel(viewIndex);
+      }
+
+      public Object[] getAllElements() {
+        final int count = myTableModel.getRowCount();
+        Object[] elements = new Object[count];
+        for (int idx = 0; idx < count; idx++) {
+          elements[idx] = myTableModel.getModuleAt(idx);
+        }
+        return elements;
+      }
+
+      public String getElementText(Object element) {
+        return ((Module)element).getName() + " (" + FileUtil.toSystemDependentName(((Module)element).getModuleFilePath()) + ")";
+      }
+
+      public void selectElement(Object element, String selectedText) {
+        final int count = myTableModel.getRowCount();
+        for (int row = 0; row < count; row++) {
+          if (element.equals(myTableModel.getModuleAt(row))) {
+            final int viewRow = myTable.convertRowIndexToView(row);
+            myTable.getSelectionModel().setSelectionInterval(viewRow, viewRow);
+            TableUtil.scrollSelectionToVisible(myTable);
+            break;
+          }
+        }
+      }
+    };
+    speedSearch.setComparator(new SpeedSearchComparator(false));
+  }
+
+  public void refresh() {
+    myTableModel.fireTableDataChanged();
+  }
+
+  public void refresh(Module element) {
+    final int row = myTableModel.getElementRow(element);
+    if (row >= 0) {
+      myTableModel.fireTableRowsUpdated(row, row);
+    }
+  }
+
+  private int[] mySavedSelection = null;
+  public void saveSelection() {
+    mySavedSelection = myTable.getSelectedRows();
+  }
+
+  public void restoreSelection() {
+    if (mySavedSelection != null) {
+      TableUtil.selectRows(myTable, mySavedSelection);
+      mySavedSelection = null;
+    }
+  }
+
+  public void addModule(Module element, String dirName) {
+    myTableModel.addElement(element, dirName);
+    selectRow(myTableModel.getRowCount() - 1);
+    myTable.requestFocus();
+  }
+
+  public void removeModule(Module element) {
+    final int elementRow = myTableModel.getElementRow(element);
+    if (elementRow < 0) {
+      return; // no such element
+    }
+    final boolean wasSelected = myTable.getSelectionModel().isSelectedIndex(elementRow);
+
+    myTableModel.removeElement(element);
+
+    if (wasSelected) {
+      final int rowCount = myTableModel.getRowCount();
+      if (rowCount > 0) {
+        selectRow(elementRow % rowCount);
+      }
+      else {
+        myTable.getSelectionModel().clearSelection();
+      }
+    }
+    myTable.requestFocus();
+  }
+
+  public void removeAllElements() {
+    myTableModel.removeAllElements();
+    myTable.getSelectionModel().clearSelection();
+  }
+
+  private void selectRow(final int row) {
+    myTable.getSelectionModel().setSelectionInterval(row, row);
+    myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+  }
+
+  @Nullable
+  public Module getSelectedElement() {
+    final int selectedRow = getSelectedElementRow();
+    return selectedRow < 0? null : myTableModel.getModuleAt(selectedRow);
+  }
+
+  public int getSelectedElementRow() {
+    return myTable.getSelectedRow();
+  }
+
+  public List<Module> getSelectedElements() {
+    final List<Module> elements = new ArrayList<Module>();
+    final int[] selectedRows = myTable.getSelectedRows();
+    for (int selectedRow : selectedRows) {
+      if (selectedRow < 0) {
+        continue;
+      }
+      elements.add(myTableModel.getModuleAt(selectedRow));
+    }
+    return elements;
+  }
+
+  public void selectElements(Collection<? extends Module> elements) {
+    if (elements.size() == 0) {
+      myTable.clearSelection();
+      return;
+    }
+    final int[] rows = getElementsRows(elements);
+    TableUtil.selectRows(myTable, rows);
+    TableUtil.scrollSelectionToVisible(myTable);
+    myTable.requestFocus();
+  }
+
+  private int[] getElementsRows(final Collection<? extends Module> elements) {
+    final int[] rows = new int[elements.size()];
+    int index = 0;
+    for (final Module element : elements) {
+      rows[index++] = myTableModel.getElementRow(element);
+    }
+    return rows;
+  }
+
+  public List<Pair<Module, String>> getAllModules() {
+    final int count = myTableModel.getRowCount();
+    List<Pair<Module, String>> elements = new ArrayList<Pair<Module, String>>();
+    for (int idx = 0; idx < count; idx++) {
+      final Module module = myTableModel.getModuleAt(idx);
+      elements.add(new Pair<Module, String>(module, myTableModel.getGenDirName(module)));
+    }
+    return elements;
+  }
+
+  public void sort(Comparator<Module> comparator) {
+    myTableModel.sort(comparator);
+  }
+
+  public void setEnabled(boolean enabled) {
+    super.setEnabled(enabled);
+    myTable.setRowSelectionAllowed(enabled);
+    myTableModel.fireTableDataChanged();
+  }
+
+  public void stopEditing() {
+    TableCellEditor editor = myTable.getCellEditor();
+    if (editor != null) {
+      editor.stopCellEditing();
+    }
+  }
+
+  public JComponent getComponent() {
+    return myTable;
+  }
+
+  public void clear() {
+    myTableModel.clear();
+  }
+
+  public int getElementCount() {
+    return myTableModel.getRowCount();
+  }
+
+  public Module getElementAt(int row) {
+    return myTableModel.getModuleAt(row);
+  }
+
+  private final class MyTableModel extends AbstractTableModel implements EditableModel {
+    private final List<Module> myElements = new ArrayList<Module>();
+    private final Map<Module, String> myDirNameMap = new HashMap<Module, String>();
+    public final int ELEMENT_COLUMN_INDEX = 0;
+    public final int DIRNAME_COLUMN_INDEX = 1;
+    private final Project myProject;
+
+    private MyTableModel(Project project) {
+      myProject = project;
+    }
+
+    public void sort(Comparator<Module> comparator) {
+      Collections.sort(myElements, comparator);
+      fireTableDataChanged();
+    }
+
+    public List<Module> getAllModules() {
+      return Collections.unmodifiableList(myElements);
+    }
+
+    public Module getModuleAt(int index) {
+      return myElements.get(index);
+    }
+
+    public String getGenDirName(Module module) {
+      return myDirNameMap.get(module);
+    }
+
+    void addElement(Module module, final String dirName) {
+      myElements.add(module);
+      if (dirName != null && dirName.length() > 0) {
+        myDirNameMap.put(module, dirName);
+      }
+      int row = myElements.size() - 1;
+      fireTableRowsInserted(row, row);
+    }
+
+    @Override
+    public void addRow() {
+      final Set<Module> projectModules = new HashSet<Module>(Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
+      projectModules.removeAll(getAllModules());
+      final ChooseModulesDialog chooser = new ChooseModulesDialog(ProcessedModulesTable.this, new ArrayList<Module>(projectModules), "ChooseModule");
+      chooser.show();
+      if (chooser.isOK()) {
+        final List<Module> chosen = chooser.getChosenElements();
+        for (Module module : chosen) {
+          addElement(module, null);
+        }
+      }      
+    }
+
+    public void removeRow(int idx) {
+      final Module element = myElements.remove(idx);
+      myDirNameMap.remove(element);
+      fireTableRowsDeleted(idx, idx);
+    }
+
+    @Override
+    public void exchangeRows(int oldIndex, int newIndex) {
+    }
+
+    @Override
+    public boolean canExchangeRows(int oldIndex, int newIndex) {
+      return false;
+    }
+
+    public void removeElement(Module element) {
+      final boolean reallyRemoved = myElements.remove(element);
+      if (reallyRemoved) {
+        myDirNameMap.remove(element);
+        fireTableDataChanged();
+      }
+    }
+
+    public int getElementRow(Module element) {
+      return myElements.indexOf(element);
+    }
+
+    public void removeAllElements() {
+      myElements.clear();
+      fireTableDataChanged();
+    }
+
+    public int getRowCount() {
+      return myElements.size();
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    @Nullable
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      Module element = myElements.get(rowIndex);
+      if (columnIndex == ELEMENT_COLUMN_INDEX) {
+        return element;
+      }
+      if (columnIndex == DIRNAME_COLUMN_INDEX) {
+        return myDirNameMap.get(element);
+      }
+      return null;
+    }
+
+    public void setValueAt(Object value, int rowIndex, int columnIndex) {
+      if (columnIndex == DIRNAME_COLUMN_INDEX) {
+        final Module module = myElements.get(rowIndex);
+        if (value != null) {
+          String dir = FileUtil.toSystemIndependentName((String)value);
+          while (dir.startsWith("/")) {
+            dir = dir.substring(1);
+          }
+          if (dir.length() > 0) {
+            myDirNameMap.put(module, dir);
+          }
+          else {
+            myDirNameMap.remove(module);
+          }
+        }
+        else {
+          myDirNameMap.remove(module);
+        }
+        fireTableRowsUpdated(rowIndex, rowIndex);
+      }
+    }
+
+    public Class getColumnClass(int columnIndex) {
+      if (columnIndex == DIRNAME_COLUMN_INDEX) {
+        return String.class;
+      }
+      return super.getColumnClass(columnIndex);
+    }
+
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      if (!ProcessedModulesTable.this.isEnabled()) {
+        return false;
+      }
+      if (columnIndex == DIRNAME_COLUMN_INDEX) {
+        return true;
+      }
+      return false;
+    }
+
+    public void clear() {
+      myElements.clear();
+      myDirNameMap.clear();
+      fireTableDataChanged();
+    }
+  }
+
+  private class MyElementColumnCellRenderer extends DefaultTableCellRenderer {
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      final Color color = UIUtil.getTableFocusCellBackground();
+      Component component;
+      final Module module = value instanceof Module? (Module)value : null;
+      try {
+        UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
+        component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+        if (module != null) {
+          setText(module.getName() + " (" + FileUtil.toSystemDependentName(module.getModuleFilePath()) + ")");
+        }
+        if (component instanceof JLabel) {
+          ((JLabel)component).setBorder(noFocusBorder);
+        }
+      }
+      finally {
+        UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
+      }
+      component.setEnabled(ProcessedModulesTable.this.isEnabled());
+      if (component instanceof JLabel) {
+        final Icon icon = module != null ? ModuleType.get(module).getIcon() : null;
+        JLabel label = (JLabel)component;
+        label.setIcon(icon);
+        label.setDisabledIcon(icon);
+      }
+      component.setForeground(isSelected ? table.getSelectionForeground() : table.getForeground());
+      return component;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java
new file mode 100644
index 0000000..1553b84
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/ProcessorProfilePanel.java
@@ -0,0 +1,513 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.ui.EditableModel;
+import org.jetbrains.jps.model.java.compiler.ProcessorConfigProfile;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.JTableHeader;
+import javax.swing.table.TableCellEditor;
+import javax.swing.table.TableModel;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+import java.io.File;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 5/28/12
+ */
+public class ProcessorProfilePanel extends JPanel {
+  private final Project myProject;
+
+  private JRadioButton myRbClasspath;
+  private JRadioButton myRbProcessorsPath;
+  private TextFieldWithBrowseButton myProcessorPathField;
+  private JTextField myGeneratedProductionDirField;
+  private JTextField myGeneratedTestsDirField;
+  private JRadioButton myRbRelativeToOutputRoot;
+  private JRadioButton myRbRelativeToContentRoot;
+  private ProcessorTableModel myProcessorsModel;
+  private JCheckBox myCbEnableProcessing;
+  private JBTable myProcessorTable;
+  private JBTable myOptionsTable;
+  private JPanel myProcessorPanel;
+  private JPanel myOptionsPanel;
+  private OptionsTableModel myOptionsModel;
+  private JLabel myWarninglabel;
+  private JLabel myStoreGenSourcesLabel;
+  private JLabel myProductionLabel;
+  private JLabel myTestLabel;
+  private JPanel myProcessorTablePanel;
+  private JPanel myOptionsTablePanel;
+
+
+  public ProcessorProfilePanel(Project project) {
+    super(new GridBagLayout());
+    myProject = project;
+
+    myCbEnableProcessing = new JCheckBox("Enable annotation processing");
+
+    {
+      myRbClasspath = new JRadioButton("Obtain processors from project classpath");
+      myRbProcessorsPath = new JRadioButton("Processor path:");
+      ButtonGroup group = new ButtonGroup();
+      group.add(myRbClasspath);
+      group.add(myRbProcessorsPath);
+    }
+
+    {
+      myRbRelativeToContentRoot = new JRadioButton("Module content root");
+      myRbRelativeToOutputRoot = new JRadioButton("Module output directory");
+      final ButtonGroup group = new ButtonGroup();
+      group.add(myRbRelativeToContentRoot);
+      group.add(myRbRelativeToOutputRoot);
+    }
+
+    myProcessorPathField = new TextFieldWithBrowseButton(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createAllButJarContentsDescriptor();
+        final VirtualFile[] files = FileChooser.chooseFiles(descriptor, myProcessorPathField, myProject, null);
+        if (files.length > 0) {
+          final StringBuilder builder = new StringBuilder();
+          for (VirtualFile file : files) {
+            if (builder.length() > 0) {
+              builder.append(File.pathSeparator);
+            }
+            builder.append(FileUtil.toSystemDependentName(file.getPath()));
+          }
+          myProcessorPathField.setText(builder.toString());
+        }
+      }
+    });
+
+    myProcessorTablePanel = new JPanel(new BorderLayout());
+    myProcessorsModel = new ProcessorTableModel();
+    myProcessorTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processors", false));
+    myProcessorTable = new JBTable(myProcessorsModel);
+    myProcessorTable.getEmptyText().setText("Compiler will run all automatically discovered processors");
+    myProcessorPanel = createTablePanel(myProcessorTable);
+    myProcessorTablePanel.add(myProcessorPanel, BorderLayout.CENTER);
+
+    myOptionsTablePanel = new JPanel(new BorderLayout());
+    myOptionsModel = new OptionsTableModel();
+    myOptionsTablePanel.setBorder(IdeBorderFactory.createTitledBorder("Annotation Processor options", false));
+    myOptionsTable = new JBTable(myOptionsModel);
+    myOptionsTable.getEmptyText().setText("No processor-specific options configured");
+    myOptionsPanel = createTablePanel(myOptionsTable);
+    myOptionsTablePanel.add(myOptionsPanel, BorderLayout.CENTER);
+
+    myGeneratedProductionDirField = new JTextField();
+    myGeneratedTestsDirField = new JTextField();
+
+    myWarninglabel = new JLabel("<html>WARNING!<br>" +
+                                              /*"All source files located in the generated sources output directory WILL BE EXCLUDED from annotation processing. " +*/
+                                              "If option 'Clear output directory on rebuild' is enabled, " +
+                                              "the entire contents of directories where generated sources are stored WILL BE CLEARED on rebuild.</html>");
+    myWarninglabel.setFont(myWarninglabel.getFont().deriveFont(Font.BOLD));
+
+    add(myCbEnableProcessing,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(0, 0, 0, 0), 0, 0));
+    add(myRbClasspath,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(10, 0, 0, 0), 0, 0));
+    add(myRbProcessorsPath,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.NONE, new Insets(5, 0, 0, 0), 0, 0));
+    add(myProcessorPathField,
+        new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(5, 5, 0, 0), 0, 0));
+
+    myStoreGenSourcesLabel = new JLabel("Store generated sources relative to: ");
+    add(myStoreGenSourcesLabel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0));
+    add(myRbRelativeToOutputRoot,
+        new GridBagConstraints(1, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0));
+    add(myRbRelativeToContentRoot,
+        new GridBagConstraints(2, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(15, 5, 0, 0), 0, 0));
+
+    myProductionLabel = new JLabel("Production sources directory:");
+    add(myProductionLabel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0));
+    add(myGeneratedProductionDirField,
+        new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0));
+
+    myTestLabel = new JLabel("Test sources directory:");
+    add(myTestLabel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 1, 1, 0.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0));
+    add(myGeneratedTestsDirField,
+        new GridBagConstraints(1, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0));
+
+    add(myProcessorTablePanel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0));
+    add(myOptionsTablePanel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.BOTH, new Insets(10, 0, 0, 0), 0, 0));
+    add(myWarninglabel,
+        new GridBagConstraints(0, GridBagConstraints.RELATIVE, 3, 1, 1.0, 0.0, GridBagConstraints.WEST, GridBagConstraints.HORIZONTAL, new Insets(10, 5, 0, 0), 0, 0));
+
+    myRbClasspath.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        updateEnabledState();
+      }
+    });
+
+    myProcessorTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+      public void valueChanged(ListSelectionEvent e) {
+        if (!e.getValueIsAdjusting()) {
+          updateEnabledState();
+        }
+      }
+    });
+
+    myCbEnableProcessing.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        updateEnabledState();
+      }
+    });
+
+    updateEnabledState();
+
+  }
+
+  public void setProfile(ProcessorConfigProfile config) {
+    myCbEnableProcessing.setSelected(config.isEnabled());
+
+    (config.isObtainProcessorsFromClasspath()? myRbClasspath : myRbProcessorsPath).setSelected(true);
+    myProcessorPathField.setText(FileUtil.toSystemDependentName(config.getProcessorPath()));
+
+    final String productionDirName = config.getGeneratedSourcesDirectoryName(false);
+    myGeneratedProductionDirField.setText(productionDirName != null? productionDirName.trim() : "");
+    final String testsDirName = config.getGeneratedSourcesDirectoryName(true);
+    myGeneratedTestsDirField.setText(testsDirName != null? testsDirName.trim() : "");
+    if (config.isOutputRelativeToContentRoot()) {
+      myRbRelativeToContentRoot.setSelected(true);
+    }
+    else {
+      myRbRelativeToOutputRoot.setSelected(true);
+    }
+    myProcessorsModel.setProcessors(config.getProcessors());
+    myOptionsModel.setOptions(config.getProcessorOptions());
+
+    updateEnabledState();
+  }
+
+  public void saveTo(ProcessorConfigProfile profile) {
+    profile.setEnabled(myCbEnableProcessing.isSelected());
+    profile.setObtainProcessorsFromClasspath(myRbClasspath.isSelected());
+    profile.setProcessorPath(myProcessorPathField.getText().trim());
+
+    final String productionDir = myGeneratedProductionDirField.getText().trim();
+    profile.setGeneratedSourcesDirectoryName(StringUtil.isEmpty(productionDir)? null : productionDir, false);
+    final String testsDir = myGeneratedTestsDirField.getText().trim();
+    profile.setGeneratedSourcesDirectoryName(StringUtil.isEmpty(testsDir)? null : testsDir, true);
+
+    profile.setOutputRelativeToContentRoot(myRbRelativeToContentRoot.isSelected());
+
+    profile.clearProcessors();
+    for (String processor : myProcessorsModel.getProcessors()) {
+      profile.addProcessor(processor);
+    }
+    profile.clearProcessorOptions();
+    for (Map.Entry<String, String> entry : myOptionsModel.getOptions().entrySet()) {
+      profile.setOption(entry.getKey(), entry.getValue());
+    }
+  }
+
+  private static JPanel createTablePanel(final JBTable table) {
+    return ToolbarDecorator.createDecorator(table)
+      .disableUpAction()
+      .disableDownAction()
+      .setAddAction(new AnActionButtonRunnable() {
+        @Override
+        public void run(AnActionButton anActionButton) {
+          final TableCellEditor cellEditor = table.getCellEditor();
+          if (cellEditor != null) {
+            cellEditor.stopCellEditing();
+          }
+          final TableModel model = table.getModel();
+          ((EditableModel)model).addRow();
+          TableUtil.editCellAt(table, model.getRowCount() - 1, 0);
+        }
+      })
+      .createPanel();
+  }
+
+  private void updateEnabledState() {
+   final boolean enabled = myCbEnableProcessing.isSelected();
+    final boolean useProcessorpath = !myRbClasspath.isSelected();
+    myRbClasspath.setEnabled(enabled);
+    myRbProcessorsPath.setEnabled(enabled);
+    myProcessorPathField.setEnabled(enabled && useProcessorpath);
+    updateTable(myProcessorPanel, myProcessorTable, enabled);
+    updateTable(myOptionsPanel, myOptionsTable, enabled);
+    myGeneratedProductionDirField.setEnabled(enabled);
+    myGeneratedTestsDirField.setEnabled(enabled);
+    myRbRelativeToOutputRoot.setEnabled(enabled);
+    myRbRelativeToContentRoot.setEnabled(enabled);
+    myWarninglabel.setEnabled(enabled);
+    myStoreGenSourcesLabel.setEnabled(enabled);
+    myProductionLabel.setEnabled(enabled);
+    myTestLabel.setEnabled(enabled);
+    myProcessorTablePanel.setEnabled(enabled);
+    myOptionsTablePanel.setEnabled(enabled);
+  }
+
+  private static void updateTable(final JPanel tablePanel, final JBTable table, boolean enabled) {
+    final AnActionButton addButton = ToolbarDecorator.findAddButton(tablePanel);
+    if (addButton != null) {
+      addButton.setEnabled(enabled);
+    }
+    final AnActionButton removeButton = ToolbarDecorator.findRemoveButton(tablePanel);
+    if (removeButton != null) {
+      removeButton.setEnabled(enabled && table.getSelectedRow() >= 0);
+    }
+    table.setEnabled(enabled);
+    final JTableHeader header = table.getTableHeader();
+    if (header != null) {
+      header.repaint();
+    }
+  }
+
+  private static class OptionsTableModel extends AbstractTableModel implements EditableModel {
+    private final java.util.List<KeyValuePair> myRows = new ArrayList<KeyValuePair>();
+
+    public String getColumnName(int column) {
+      switch (column) {
+        case 0: return "Option Name";
+        case 1: return "Value";
+      }
+      return super.getColumnName(column);
+    }
+
+    public Class<?> getColumnClass(int columnIndex) {
+      return String.class;
+    }
+
+    public int getRowCount() {
+      return myRows.size();
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      return columnIndex == 0 || columnIndex == 1;
+    }
+
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      switch (columnIndex) {
+        case 0: return myRows.get(rowIndex).key;
+        case 1: return myRows.get(rowIndex).value;
+      }
+      return null;
+    }
+
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+      if (aValue != null) {
+        switch (columnIndex) {
+          case 0:
+            myRows.get(rowIndex).key = (String)aValue;
+            break;
+          case 1:
+            myRows.get(rowIndex).value = (String)aValue;
+            break;
+        }
+      }
+    }
+
+    public void removeRow(int idx) {
+      myRows.remove(idx);
+      fireTableRowsDeleted(idx, idx);
+    }
+
+    @Override
+    public void exchangeRows(int oldIndex, int newIndex) {
+    }
+
+    @Override
+    public boolean canExchangeRows(int oldIndex, int newIndex) {
+      return false;
+    }
+
+    public void addRow() {
+      myRows.add(new KeyValuePair());
+      final int index = myRows.size() - 1;
+      fireTableRowsInserted(index, index);
+    }
+
+    public void setOptions(Map<String, String> options) {
+      clear();
+      if (!options.isEmpty()) {
+        for (Map.Entry<String, String> entry : options.entrySet()) {
+          myRows.add(new KeyValuePair(entry.getKey(), entry.getValue()));
+        }
+        Collections.sort(myRows, new Comparator<KeyValuePair>() {
+          @Override
+          public int compare(KeyValuePair o1, KeyValuePair o2) {
+            return o1.key.compareToIgnoreCase(o2.key);
+          }
+        });
+        fireTableRowsInserted(0, options.size()-1);
+      }
+    }
+
+    public void clear() {
+      final int count = myRows.size();
+      if (count > 0) {
+        myRows.clear();
+        fireTableRowsDeleted(0, count-1);
+      }
+    }
+
+    public Map<String, String> getOptions() {
+      final Map<String, String> map = new java.util.HashMap<String, String>();
+      for (KeyValuePair pair : myRows) {
+        map.put(pair.key.trim(), pair.value.trim());
+      }
+      map.remove("");
+      return map;
+    }
+
+    private static final class KeyValuePair {
+      String key;
+      String value;
+
+      KeyValuePair() {
+        this("", "");
+      }
+
+      KeyValuePair(String key, String value) {
+        this.key = key;
+        this.value = value;
+      }
+    }
+  }
+
+  private static class ProcessorTableModel extends AbstractTableModel implements EditableModel {
+    private final List<String> myRows = new ArrayList<String>();
+
+    public String getColumnName(int column) {
+      switch (column) {
+        case 0: return "Processor FQ Name";
+      }
+      return super.getColumnName(column);
+    }
+
+    public Class<?> getColumnClass(int columnIndex) {
+      return String.class;
+    }
+
+    public int getRowCount() {
+      return myRows.size();
+    }
+
+    public int getColumnCount() {
+      return 1;
+    }
+
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      return columnIndex == 0;
+    }
+
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      switch (columnIndex) {
+        case 0: return myRows.get(rowIndex);
+      }
+      return null;
+    }
+
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+      if (aValue != null) {
+        switch (columnIndex) {
+          case 0:
+            myRows.set(rowIndex, (String)aValue);
+            break;
+        }
+      }
+    }
+
+    public void removeRow(int idx) {
+      myRows.remove(idx);
+      fireTableRowsDeleted(idx, idx);
+    }
+
+    @Override
+    public void exchangeRows(int oldIndex, int newIndex) {
+    }
+
+    @Override
+    public boolean canExchangeRows(int oldIndex, int newIndex) {
+      return false;
+    }
+
+    public void addRow() {
+      myRows.add("");
+      final int index = myRows.size() - 1;
+      fireTableRowsInserted(index, index);
+    }
+
+    public void setProcessors(Collection<String> processors) {
+      clear();
+      if (!processors.isEmpty()) {
+        for (String processor : processors) {
+          myRows.add(processor);
+        }
+        Collections.sort(myRows, new Comparator<String>() {
+          public int compare(String o1, String o2) {
+            return o1.compareToIgnoreCase(o2);
+          }
+        });
+        fireTableRowsInserted(0, processors.size()-1);
+      }
+    }
+
+    public void clear() {
+      final int count = myRows.size();
+      if (count > 0) {
+        myRows.clear();
+        fireTableRowsDeleted(0, count-1);
+      }
+    }
+
+    public Collection<String> getProcessors() {
+      final Set<String> set = new HashSet<String>();
+      for (String row : myRows) {
+        if (row != null) {
+          set.add(row.trim());
+        }
+      }
+      set.remove("");
+      return set;
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/RmicConfigurable.java b/java/compiler/impl/src/com/intellij/compiler/options/RmicConfigurable.java
new file mode 100644
index 0000000..96b4aab
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/RmicConfigurable.java
@@ -0,0 +1,115 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.compiler.impl.rmiCompiler.RmicConfiguration;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.RawCommandLineEditor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.model.java.compiler.RmicCompilerOptions;
+
+import javax.swing.*;
+import java.awt.event.ItemEvent;
+import java.awt.event.ItemListener;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 30, 2004
+ */
+public class RmicConfigurable implements SearchableConfigurable, Configurable.NoScroll {
+  private JPanel myPanel;
+  private JCheckBox myCbEnabled;
+  private JCheckBox myCbGenerateIiopStubs;
+  private JCheckBox myCbDebuggingInfo;
+  private JCheckBox myCbGenerateNoWarnings;
+  private RawCommandLineEditor myAdditionalOptionsField;
+  private final RmicCompilerOptions myRmicSettings;
+  private JLabel myFieldLabel;
+
+  public RmicConfigurable(final Project project) {
+    myRmicSettings = RmicConfiguration.getOptions(project);
+    myCbEnabled.addItemListener(new ItemListener() {
+      public void itemStateChanged(ItemEvent e) {
+        setOptionsEnabled(e.getStateChange() == ItemEvent.SELECTED);
+      }
+    });
+    myAdditionalOptionsField.setDialogCaption(myFieldLabel.getText());
+  }
+
+  private void setOptionsEnabled(final boolean selected) {
+    myCbGenerateIiopStubs.setEnabled(selected);
+    myCbGenerateNoWarnings.setEnabled(selected);
+    myCbDebuggingInfo.setEnabled(selected);
+    myFieldLabel.setEnabled(selected);
+    myAdditionalOptionsField.setEnabled(selected);
+  }
+
+  public String getDisplayName() {
+    return CompilerBundle.message("rmi.compiler.description");
+  }
+
+  public String getHelpTopic() {
+    return "reference.projectsettings.compiler.rmicompiler";
+  }
+
+  @NotNull
+  public String getId() {
+    return getHelpTopic();
+  }
+
+  public Runnable enableSearch(String option) {
+    return null;
+  }
+
+  public JComponent createComponent() {
+    return myPanel;
+  }
+
+  public boolean isModified() {
+    boolean isModified = false;
+    isModified |= ComparingUtils.isModified(myCbEnabled, myRmicSettings.IS_EANABLED);
+    isModified |= ComparingUtils.isModified(myCbGenerateIiopStubs, myRmicSettings.GENERATE_IIOP_STUBS);
+    isModified |= ComparingUtils.isModified(myCbDebuggingInfo, myRmicSettings.DEBUGGING_INFO);
+    isModified |= ComparingUtils.isModified(myCbGenerateNoWarnings, myRmicSettings.GENERATE_NO_WARNINGS);
+    isModified |= ComparingUtils.isModified(myAdditionalOptionsField, myRmicSettings.ADDITIONAL_OPTIONS_STRING);
+    return isModified;
+  }
+
+  public void apply() throws ConfigurationException {
+    myRmicSettings.IS_EANABLED =  myCbEnabled.isSelected();
+    myRmicSettings.GENERATE_IIOP_STUBS =  myCbGenerateIiopStubs.isSelected();
+    myRmicSettings.DEBUGGING_INFO = myCbDebuggingInfo.isSelected();
+    myRmicSettings.GENERATE_NO_WARNINGS = myCbGenerateNoWarnings.isSelected();
+    myRmicSettings.ADDITIONAL_OPTIONS_STRING = myAdditionalOptionsField.getText();
+  }
+
+  public void reset() {
+    myCbEnabled.setSelected(myRmicSettings.IS_EANABLED);
+    setOptionsEnabled(myRmicSettings.IS_EANABLED);
+    myCbGenerateIiopStubs.setSelected(myRmicSettings.GENERATE_IIOP_STUBS);
+    myCbDebuggingInfo.setSelected(myRmicSettings.DEBUGGING_INFO);
+    myCbGenerateNoWarnings.setSelected(myRmicSettings.GENERATE_NO_WARNINGS);
+    myAdditionalOptionsField.setText(myRmicSettings.ADDITIONAL_OPTIONS_STRING);
+  }
+
+  public void disposeUIResources() {
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/RmicOptionsPanel.form b/java/compiler/impl/src/com/intellij/compiler/options/RmicOptionsPanel.form
new file mode 100644
index 0000000..a5a4aaf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/RmicOptionsPanel.form
@@ -0,0 +1,82 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.compiler.options.RmicConfigurable">
+  <grid id="49284" binding="myPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="37" y="129" width="521" height="280"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <grid id="9b938" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="3c8c0" class="javax.swing.JCheckBox" binding="myCbEnabled">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="rmic.option.enable.rmi.stubs"/>
+            </properties>
+          </component>
+          <component id="70faa" class="javax.swing.JCheckBox" binding="myCbGenerateIiopStubs">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="rmic.option.generate.iiop.stubs"/>
+            </properties>
+          </component>
+          <component id="3d38f" class="javax.swing.JCheckBox" binding="myCbDebuggingInfo">
+            <constraints>
+              <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <selected value="false"/>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.debugging.info"/>
+            </properties>
+          </component>
+          <component id="90803" class="javax.swing.JCheckBox" binding="myCbGenerateNoWarnings">
+            <constraints>
+              <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.generate.no.warnings"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <grid id="3f1e9" layout-manager="GridLayoutManager" row-count="1" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="10" left="8" bottom="0" right="0"/>
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="1" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="f8a80" class="javax.swing.JLabel" binding="myFieldLabel">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text resource-bundle="messages/CompilerBundle" key="java.compiler.option.additional.command.line.parameters"/>
+            </properties>
+          </component>
+          <component id="479c2" class="com.intellij.ui.RawCommandLineEditor" binding="myAdditionalOptionsField">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false">
+                <preferred-size width="150" height="-1"/>
+              </grid>
+            </constraints>
+            <properties/>
+          </component>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/TargetOptionsComponent.java b/java/compiler/impl/src/com/intellij/compiler/options/TargetOptionsComponent.java
new file mode 100644
index 0000000..a4864c8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/TargetOptionsComponent.java
@@ -0,0 +1,395 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ChooseModulesDialog;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.ui.ItemRemovable;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.plaf.basic.BasicComboBoxEditor;
+import javax.swing.table.AbstractTableModel;
+import javax.swing.table.DefaultTableCellRenderer;
+import javax.swing.table.TableColumn;
+import java.awt.*;
+import java.util.*;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 5/9/12
+ */
+public class TargetOptionsComponent extends JPanel {
+  private static final String[] KNOWN_TARGETS = new String[] {"1.1", "1.2", "1.3","1.4","1.5", "1.6", "1.7", "1.8"};
+  private static final String COMPILER_DEFAULT = "JDK default";
+
+  private ComboBox myCbProjectTargetLevel;
+  private JBTable myTable;
+  private final Project myProject;
+
+  public TargetOptionsComponent(Project project) {
+    super(new GridBagLayout());
+    myProject = project;
+    //setBorder(BorderFactory.createTitledBorder("Bytecode target level"));
+    myCbProjectTargetLevel = createTargetOptionsCombo();
+
+    myTable = new JBTable(new TargetLevelTableModel());
+    myTable.setRowHeight(22);
+    myTable.getEmptyText().setText("All modules will be compiled with project bytecode version");
+
+    final TableColumn moduleColumn = myTable.getColumnModel().getColumn(0);
+    moduleColumn.setHeaderValue("Module");
+    moduleColumn.setCellRenderer(new ModuleCellRenderer());
+
+    final TableColumn targetLevelColumn = myTable.getColumnModel().getColumn(1);
+    final String columnTitle = "Target bytecode version";
+    targetLevelColumn.setHeaderValue(columnTitle);
+    targetLevelColumn.setCellEditor(new TargetLevelCellEditor());
+    targetLevelColumn.setCellRenderer(new TargetLevelCellRenderer());
+    final int width = myTable.getFontMetrics(myTable.getFont()).stringWidth(columnTitle) + 10;
+    targetLevelColumn.setPreferredWidth(width);
+    targetLevelColumn.setMinWidth(width);
+    targetLevelColumn.setMaxWidth(width);
+
+    add(new JLabel("Project bytecode version (leave blank for jdk default): "),
+        constraints(0, 0, 1, 1, 0.0, 0.0, GridBagConstraints.NONE));
+    add(myCbProjectTargetLevel, constraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NONE));
+    add(new JLabel("Per-module bytecode version:"), constraints(0, 1, 2, 1, 1.0, 0.0, GridBagConstraints.NONE));
+    final JPanel tableComp = ToolbarDecorator.createDecorator(myTable)
+      .disableUpAction()
+      .disableDownAction()
+      .setAddAction(new AnActionButtonRunnable() {
+        @Override
+        public void run(AnActionButton anActionButton) {
+          addModules();
+        }
+      })
+      .setRemoveAction(new AnActionButtonRunnable() {
+        @Override
+        public void run(AnActionButton anActionButton) {
+          removeSelectedModules();
+        }
+      }).createPanel();
+
+    tableComp.setPreferredSize(new Dimension(myTable.getWidth(), 150));
+    add(tableComp, constraints(0, 2, 2, 1, 1.0, 1.0, GridBagConstraints.BOTH));
+  }
+
+  private void removeSelectedModules() {
+    final int[] rows = myTable.getSelectedRows();
+    if (rows.length > 0) {
+      TableUtil.removeSelectedItems(myTable);
+    }
+  }
+
+  private void addModules() {
+    final TargetLevelTableModel model = (TargetLevelTableModel)myTable.getModel();
+    final List<Module> items = new ArrayList<Module>(Arrays.asList(ModuleManager.getInstance(myProject).getModules()));
+    Set<Module> alreadyAdded = new HashSet<Module>();
+    for (TargetLevelTableModel.Item item : model.getItems()) {
+      alreadyAdded.add(item.module);
+    }
+    for (Iterator<Module> it = items.iterator(); it.hasNext(); ) {
+      Module module = it.next();
+      if (alreadyAdded.contains(module)) {
+        it.remove();
+      }
+    }
+    Collections.sort(items, new Comparator<Module>() {
+      @Override
+      public int compare(Module o1, Module o2) {
+        return o1.getName().compareTo(o2.getName());
+      }
+    });
+    final ChooseModulesDialog chooser = new ChooseModulesDialog(this, items, "Choose module");
+    chooser.show();
+    final List<Module> elements = chooser.getChosenElements();
+    if (!elements.isEmpty()) {
+      model.addItems(elements);
+    }
+  }
+
+  public void setProjectBytecodeTargetLevel(String level) {
+    myCbProjectTargetLevel.setSelectedItem(level == null? "" : level);
+  }
+
+  @Nullable
+  public String getProjectBytecodeTarget() {
+    final String item = ((String)myCbProjectTargetLevel.getSelectedItem()).trim();
+    return "".equals(item)? null : item;
+  }
+
+  public Map<String, String> getModulesBytecodeTargetMap() {
+    TargetLevelTableModel model = (TargetLevelTableModel)myTable.getModel();
+    final Map<String, String> map = new HashMap<String, String>();
+    for (TargetLevelTableModel.Item item : model.getItems()) {
+      map.put(item.module.getName(), item.targetLevel);
+    }
+    return map;
+  }
+
+  public void setModuleTargetLevels(Map<String, String> moduleLevels) {
+    final Map<Module, String> map = new HashMap<Module, String>();
+    for (Module module : ModuleManager.getInstance(myProject).getModules()) {
+      final String target = moduleLevels.get(module.getName());
+      if (target != null) {
+        map.put(module, target);
+      }
+    }
+    ((TargetLevelTableModel)myTable.getModel()).setItems(map);
+  }
+
+  private static GridBagConstraints constraints(final int gridx, final int gridy, final int gridwidth, final int gridheight, final double weightx, final double weighty, final int fill) {
+    return new GridBagConstraints(gridx, gridy, gridwidth, gridheight, weightx, weighty, GridBagConstraints.WEST, fill, new Insets(5, 5, 0, 0), 0, 0);
+  }
+
+  private static final class TargetLevelTableModel extends AbstractTableModel implements ItemRemovable{
+    private final List<Item> myItems = new ArrayList<Item>();
+    @Override
+    public int getRowCount() {
+      return myItems.size();
+    }
+
+    @Override
+    public int getColumnCount() {
+      return 2;
+    }
+
+    @Override
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      return columnIndex != 0;
+    }
+
+    @Override
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      final Item item = myItems.get(rowIndex);
+      return columnIndex == 0? item.module : item.targetLevel;
+    }
+
+    @Override
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+      final Item item = myItems.get(rowIndex);
+      item.targetLevel = ((String)aValue).trim();
+      fireTableCellUpdated(rowIndex, columnIndex);
+    }
+
+    //public void addItem(Module module)  {
+    //  final int size = myItems.size();
+    //  myItems.add(new Item(module.getName()));
+    //  fireTableRowsInserted(size, size);
+    //}
+
+    public void addItems(Collection<Module> modules)  {
+      for (Module module : modules) {
+        myItems.add(new Item(module));
+      }
+      sorItems();
+      fireTableDataChanged();
+    }
+
+    private void sorItems() {
+      Collections.sort(myItems, new Comparator<Item>() {
+        @Override
+        public int compare(Item o1, Item o2) {
+          return o1.module.getName().compareTo(o2.module.getName());
+        }
+      });
+    }
+
+    public List<Item> getItems() {
+      return myItems;
+    }
+
+    @Override
+    public void removeRow(int idx) {
+      myItems.remove(idx);
+    }
+
+    public void setItems(Map<Module, String> items) {
+      myItems.clear();
+      for (Map.Entry<Module, String> entry : items.entrySet()) {
+        myItems.add(new Item(entry.getKey(), entry.getValue()));
+      }
+      sorItems();
+      fireTableDataChanged();
+    }
+
+    private static final class Item {
+      final Module module;
+      String targetLevel = "";
+
+      Item(Module module) {
+        this.module = module;
+      }
+
+      Item(Module module, String targetLevel) {
+        this.module = module;
+        this.targetLevel = targetLevel;
+      }
+    }
+  }
+
+  private static final class TargetLevelComboboxModel extends AbstractListModel implements ComboBoxModel{
+
+    private final List<String> myOptions = new ArrayList<String>();
+    private String mySelectedItem = "";
+
+    TargetLevelComboboxModel() {
+      //myOptions.add("");
+      for (int i = KNOWN_TARGETS.length - 1; i >= 0; i--) {
+        myOptions.add(KNOWN_TARGETS[i]);
+      }
+    }
+
+    @Override
+    public int getSize() {
+      return myOptions.size();
+    }
+
+    @Override
+    public void setSelectedItem(Object anItem) {
+      mySelectedItem = toModelItem((String)anItem);
+      fireContentsChanged(this, 0, myOptions.size());
+    }
+
+    @Override
+    public Object getSelectedItem() {
+      return mySelectedItem;
+    }
+
+    @Override
+    public Object getElementAt(int index) {
+      return myOptions.get(index);
+    }
+
+    private String toModelItem(String item) {
+      item = item.trim();
+      for (String option : myOptions) {
+        if (option.equals(item)) {
+          return option;
+        }
+      }
+      return item;
+    }
+  }
+
+  private static ComboBox createTargetOptionsCombo() {
+    final ComboBox combo = new ComboBox(new TargetLevelComboboxModel());
+    //combo.setRenderer(new DefaultListCellRenderer() {
+    //  @Override
+    //  public Component getListCellRendererComponent(JList list, Object value, int index, boolean isSelected, boolean cellHasFocus) {
+    //    try {
+    //      return super.getListCellRendererComponent(list, value, index, isSelected, cellHasFocus);
+    //    }
+    //    finally {
+    //      //if ("".equals(value)) {
+    //      //  setText(COMPILER_DEFAULT);
+    //      //}
+    //    }
+    //  }
+    //});
+    combo.setEditable(true);
+    combo.setEditor(new BasicComboBoxEditor() {
+      @Override
+      protected JTextField createEditorComponent() {
+        return new HintTextField(COMPILER_DEFAULT, 10);
+      }
+    });
+    return combo;
+  }
+
+  private static class ModuleCellRenderer extends DefaultTableCellRenderer {
+    @Override
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      try {
+        return super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      }
+      finally {
+        final Module module = (Module)value;
+        setText(module.getName());
+        setIcon(ModuleType.get(module).getIcon());
+      }
+    }
+  }
+
+  private static class TargetLevelCellEditor extends DefaultCellEditor {
+    private TargetLevelCellEditor() {
+      super(createTargetOptionsCombo());
+      setClickCountToStart(0);
+    }
+  }
+
+  private static class TargetLevelCellRenderer extends DefaultTableCellRenderer {
+    @Override
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      if (component instanceof JLabel) {
+        final JLabel comp = (JLabel)component;
+        comp.setHorizontalAlignment(SwingConstants.CENTER);
+        if ("".equals(value)) {
+          comp.setForeground(JBColor.GRAY);
+          comp.setText(COMPILER_DEFAULT);
+        }
+        else {
+          comp.setForeground(table.getForeground());
+        }
+      }
+      return component;
+    }
+  }
+
+  static class HintTextField extends JTextField {
+    private final char[] myHint;
+
+    public HintTextField(final String hint) {
+      this(hint, 0);
+    }
+
+    public HintTextField(final String hint, final int columns) {
+      super(hint, columns);
+      myHint = hint.toCharArray();
+    }
+
+    @Override
+    protected void paintComponent(Graphics g) {
+      super.paintComponent(g);
+      final boolean isFocused = isFocusOwner();
+      if (!isFocused && getText().isEmpty()) {
+        final Color oldColor = g.getColor();
+        final Font oldFont = g.getFont();
+        try {
+          g.setColor(JBColor.GRAY);
+          //g.setFont(oldFont.deriveFont(Font.ITALIC));
+          final FontMetrics metrics = g.getFontMetrics();
+          int x = Math.abs(getWidth() - metrics.charsWidth(myHint, 0, myHint.length)) / 2;
+          int y = Math.abs(getHeight() - metrics.getHeight()) / 2 + metrics.getAscent();
+          g.drawChars(myHint, 0, myHint.length, x, y);
+        }
+        finally {
+          g.setColor(oldColor);
+          g.setFont(oldFont);
+        }
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/options/ValidationConfiguration.java b/java/compiler/impl/src/com/intellij/compiler/options/ValidationConfiguration.java
new file mode 100644
index 0000000..2b8a43e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/options/ValidationConfiguration.java
@@ -0,0 +1,89 @@
+/*
+ * 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.compiler.options;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author Dmitry Avdeev
+ */
+@State(
+  name = "ValidationConfiguration",
+  storages = {
+    @Storage( file = StoragePathMacros.WORKSPACE_FILE),
+    @Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/validation.xml", scheme = StorageScheme.DIRECTORY_BASED)
+  }
+)
+public class ValidationConfiguration implements PersistentStateComponent<ValidationConfiguration> {
+
+  public boolean VALIDATE_ON_BUILD = false;
+  public Map<String, Boolean> VALIDATORS = new HashMap<String, Boolean>();
+
+  public static boolean shouldValidate(Compiler validator, CompileContext context) {
+    ValidationConfiguration configuration = getInstance(context.getProject());
+    return (configuration.VALIDATE_ON_BUILD) && configuration.isSelected(validator);
+  }
+
+  public boolean isSelected(Compiler validator) {
+    return isSelected(validator.getDescription());
+  }
+
+  public boolean isSelected(String validatorDescription) {
+    final Boolean selected = VALIDATORS.get(validatorDescription);
+    return selected == null || selected.booleanValue();
+  }
+
+  public void setSelected(Compiler validator, boolean selected) {
+    setSelected(validator.getDescription(), selected);
+  }
+
+  public void setSelected(String validatorDescription, boolean selected) {
+    VALIDATORS.put(validatorDescription, selected);
+  }
+
+  public static ValidationConfiguration getInstance(Project project) {
+    return ServiceManager.getService(project, ValidationConfiguration.class);
+  }
+
+  public static ExcludedEntriesConfiguration getExcludedEntriesConfiguration(Project project) {
+    return ServiceManager.getService(project, ExcludedFromValidationConfiguration.class);
+  }
+
+  public ValidationConfiguration getState() {
+    return this;
+  }
+
+  public void loadState(final ValidationConfiguration state) {
+    XmlSerializerUtil.copyBean(state, this);
+  }
+
+  @State(
+      name = "ExcludeFromValidation",
+      storages = {
+          @Storage( file = StoragePathMacros.PROJECT_FILE),
+          @Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/excludeFromValidation.xml", scheme = StorageScheme.DIRECTORY_BASED)
+      }
+  )
+  public static class ExcludedFromValidationConfiguration extends ExcludedEntriesConfiguration {}
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
new file mode 100644
index 0000000..527b627
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/progress/CompilerTask.java
@@ -0,0 +1,607 @@
+/*
+ * 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: Jan 22, 2003
+ * Time: 2:25:31 PM
+ */
+package com.intellij.compiler.progress;
+
+import com.intellij.compiler.CompilerManagerImpl;
+import com.intellij.compiler.CompilerMessageImpl;
+import com.intellij.compiler.impl.CompilerErrorTreeView;
+import com.intellij.ide.errorTreeView.NewErrorTreeViewPanel;
+import com.intellij.ide.errorTreeView.impl.ErrorTreeViewConfiguration;
+import com.intellij.ide.impl.ProjectUtil;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.progress.EmptyProgressIndicator;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.progress.util.ProgressIndicatorBase;
+import com.intellij.openapi.project.DumbModeAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerListener;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.AppIconScheme;
+import com.intellij.openapi.wm.ToolWindow;
+import com.intellij.openapi.wm.ToolWindowId;
+import com.intellij.openapi.wm.ToolWindowManager;
+import com.intellij.openapi.wm.ex.ProgressIndicatorEx;
+import com.intellij.pom.Navigatable;
+import com.intellij.problems.WolfTheProblemSolver;
+import com.intellij.ui.AppIcon;
+import com.intellij.ui.content.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.messages.MessageBusConnection;
+import com.intellij.util.ui.MessageCategory;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.StringTokenizer;
+import java.util.concurrent.Semaphore;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+public class CompilerTask extends Task.Backgroundable {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.progress.CompilerProgressIndicator");
+  private static final Key<Key<?>> CONTENT_ID_KEY = Key.create("CONTENT_ID");
+  private static final String APP_ICON_ID = "compiler";
+  private Key<Key<?>> myContentIdKey = CONTENT_ID_KEY;
+  private final Key<Key<?>> myContentId = Key.create("compile_content");
+  private NewErrorTreeViewPanel myErrorTreeView;
+  private final Object myMessageViewLock = new Object();
+  private final String myContentName;
+  private final boolean myHeadlessMode;
+  private final boolean myForceAsyncExecution;
+  private int myErrorCount = 0;
+  private int myWarningCount = 0;
+  private boolean myMessagesAutoActivated = false;
+
+  private volatile ProgressIndicator myIndicator = new EmptyProgressIndicator();
+  private Runnable myCompileWork;
+  private final AtomicBoolean myMessageViewWasPrepared = new AtomicBoolean(false);
+  private Runnable myRestartWork;
+
+  public CompilerTask(@NotNull Project project, String contentName, final boolean headlessMode, boolean forceAsync) {
+    super(project, contentName);
+    myContentName = contentName;
+    myHeadlessMode = headlessMode;
+    myForceAsyncExecution = forceAsync;
+  }
+
+  public void setContentIdKey(Key<Key<?>> contentIdKey) {
+    myContentIdKey = contentIdKey != null? contentIdKey : CONTENT_ID_KEY;
+  }
+
+  public String getProcessId() {
+    return "compilation";
+  }
+
+  @Override
+  public DumbModeAction getDumbModeAction() {
+    return DumbModeAction.WAIT;
+  }
+
+  public boolean shouldStartInBackground() {
+    return true;
+  }
+
+  public ProgressIndicator getIndicator() {
+    return myIndicator;
+  }
+
+  @Nullable
+  public NotificationInfo getNotificationInfo() {
+    return new NotificationInfo(myErrorCount > 0? "Compiler (errors)" : "Compiler (success)", "Compilation Finished", myErrorCount + " Errors, " + myWarningCount + " Warnings", true);
+  }
+
+  private CloseListener myCloseListener;
+
+  public void run(@NotNull final ProgressIndicator indicator) {
+    myIndicator = indicator;
+
+    final ProjectManager projectManager = ProjectManager.getInstance();
+    projectManager.addProjectManagerListener(myProject, myCloseListener = new CloseListener());
+
+    final Semaphore semaphore = ((CompilerManagerImpl)CompilerManager.getInstance(myProject)).getCompilationSemaphore();
+    boolean acquired = false;
+    try {
+
+      try {
+        while (!acquired) {
+          acquired = semaphore.tryAcquire(500, TimeUnit.MILLISECONDS);
+          if (indicator.isCanceled()) {
+            // give up obtaining the semaphore,
+            // let compile work begin in order to stop gracefuly on cancel event
+            break;
+          }
+        }
+      }
+      catch (InterruptedException ignored) {
+      }
+
+      if (!isHeadless()) {
+        addIndicatorDelegate();
+      }
+      myCompileWork.run();
+    }
+    finally {
+      try {
+        indicator.stop();
+        projectManager.removeProjectManagerListener(myProject, myCloseListener);
+      }
+      finally {
+        if (acquired) {
+          semaphore.release();
+        }
+      }
+    }
+  }
+
+  private void prepareMessageView() {
+    if (!myIndicator.isRunning()) {
+      return;
+    }
+    if (myMessageViewWasPrepared.getAndSet(true)) {
+      return;
+    }
+
+    ApplicationManager.getApplication().invokeLater(new Runnable() {
+      public void run() {
+        if (myProject.isDisposed()) return;
+        synchronized (myMessageViewLock) {
+          // clear messages from the previous compilation
+          if (myErrorTreeView == null) {
+            // if message view != null, the contents has already been cleared
+            removeAllContents(myProject, null);
+          }
+        }
+      }
+    });
+  }
+
+  private void addIndicatorDelegate() {
+    ProgressIndicator indicator = myIndicator;
+    if (!(indicator instanceof ProgressIndicatorEx)) return;
+    ((ProgressIndicatorEx)indicator).addStateDelegate(new ProgressIndicatorBase() {
+
+      public void cancel() {
+        super.cancel();
+        closeUI();
+        stopAppIconProgress();
+      }
+
+      public void stop() {
+        super.stop();
+        if (!isCanceled()) {
+          closeUI();
+        }
+        stopAppIconProgress();
+      }
+
+      private void stopAppIconProgress() {
+        UIUtil.invokeLaterIfNeeded(new Runnable() {
+          public void run() {
+            AppIcon appIcon = AppIcon.getInstance();
+            if (appIcon.hideProgress(myProject, APP_ICON_ID)) {
+              if (myErrorCount > 0) {
+                appIcon.setErrorBadge(myProject, String.valueOf(myErrorCount));
+                appIcon.requestAttention(myProject, true);
+              } else {
+                appIcon.setOkBadge(myProject, true);
+                appIcon.requestAttention(myProject, false);
+              }
+            }
+          }
+        });
+      }
+
+      public void setText(final String text) {
+        super.setText(text);
+        updateProgressText();
+      }
+
+      public void setText2(final String text) {
+        super.setText2(text);
+        updateProgressText();
+      }
+
+      public void setFraction(final double fraction) {
+        super.setFraction(fraction);
+        updateProgressText();
+        UIUtil.invokeLaterIfNeeded(new Runnable() {
+          public void run() {
+            AppIcon.getInstance().setProgress(myProject, APP_ICON_ID, AppIconScheme.Progress.BUILD, fraction, true);
+          }
+        });
+      }
+
+      protected void onProgressChange() {
+        prepareMessageView();
+      }
+    });
+  }
+
+  public void cancel() {
+    if (!myIndicator.isCanceled()) {
+      myIndicator.cancel();
+    }
+  }
+
+  public void addMessage(final CompilerMessage message) {
+    prepareMessageView();
+
+    final CompilerMessageCategory messageCategory = message.getCategory();
+    if (CompilerMessageCategory.WARNING.equals(messageCategory)) {
+      myWarningCount += 1;
+    }
+    else if (CompilerMessageCategory.ERROR.equals(messageCategory)) {
+      myErrorCount += 1;
+      informWolf(message);
+    }
+
+    if (ApplicationManager.getApplication().isDispatchThread()) {
+      openMessageView();
+      doAddMessage(message);
+    }
+    else {
+      final Window window = getWindow();
+      final ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL;
+      ApplicationManager.getApplication().invokeLater(new Runnable() {
+        public void run() {
+          if (!myProject.isDisposed()) {
+            openMessageView();
+            doAddMessage(message);
+          }
+        }
+      }, modalityState);
+    }
+  }
+
+  private void informWolf(final CompilerMessage message) {
+    WolfTheProblemSolver wolf = WolfTheProblemSolver.getInstance(myProject);
+    VirtualFile file = getVirtualFile(message);
+    wolf.queue(file);
+  }
+
+  private void doAddMessage(final CompilerMessage message) {
+    synchronized (myMessageViewLock) {
+      if (myErrorTreeView != null) {
+        final Navigatable navigatable = message.getNavigatable();
+        final VirtualFile file = message.getVirtualFile();
+        final CompilerMessageCategory category = message.getCategory();
+        final int type = translateCategory(category);
+        final String[] text = convertMessage(message);
+        if (navigatable != null) {
+          final String groupName = file != null? file.getPresentableUrl() : category.getPresentableText();
+          myErrorTreeView.addMessage(type, text, groupName, navigatable, message.getExportTextPrefix(), message.getRenderTextPrefix(), message.getVirtualFile());
+        }
+        else {
+          myErrorTreeView.addMessage(type, text, file, -1, -1, message.getVirtualFile());
+        }
+
+        final boolean shouldAutoActivate =
+          !myMessagesAutoActivated &&
+          (
+            CompilerMessageCategory.ERROR.equals(category) ||
+            (CompilerMessageCategory.WARNING.equals(category) && !ErrorTreeViewConfiguration.getInstance(myProject).isHideWarnings())
+          );
+        if (shouldAutoActivate) {
+          myMessagesAutoActivated = true;
+          activateMessageView();
+        }
+      }
+    }
+  }
+
+  private static String[] convertMessage(final CompilerMessage message) {
+    String text = message.getMessage();
+    if (!text.contains("\n")) {
+      return new String[]{text};
+    }
+    ArrayList<String> lines = new ArrayList<String>();
+    StringTokenizer tokenizer = new StringTokenizer(text, "\n", false);
+    while (tokenizer.hasMoreTokens()) {
+      lines.add(tokenizer.nextToken());
+    }
+    return ArrayUtil.toStringArray(lines);
+  }
+
+  public static int translateCategory(CompilerMessageCategory category) {
+    if (CompilerMessageCategory.ERROR.equals(category)) {
+      return MessageCategory.ERROR;
+    }
+    if (CompilerMessageCategory.WARNING.equals(category)) {
+      return MessageCategory.WARNING;
+    }
+    if (CompilerMessageCategory.STATISTICS.equals(category)) {
+      return MessageCategory.STATISTICS;
+    }
+    if (CompilerMessageCategory.INFORMATION.equals(category)) {
+      return MessageCategory.INFORMATION;
+    }
+    LOG.error("Unknown message category: " + category);
+    return 0;
+  }
+
+  public void start(Runnable compileWork, Runnable restartWork) {
+    myCompileWork = compileWork;
+    myRestartWork = restartWork;
+    queue();
+  }
+
+  private void updateProgressText() {
+    if (isHeadlessMode()) {
+      return;
+    }
+  }
+
+  // error tree view initialization must be invoked from event dispatch thread
+  private void openMessageView() {
+    if (isHeadlessMode()) {
+      return;
+    }
+    if (myIndicator.isCanceled()) {
+      return;
+    }
+    
+    final JComponent component;
+    synchronized (myMessageViewLock) {
+      if (myErrorTreeView != null) {
+        return;
+      }
+      myErrorTreeView = new CompilerErrorTreeView(
+          myProject,
+          myRestartWork
+      );
+      
+      myErrorTreeView.setProcessController(new NewErrorTreeViewPanel.ProcessController() {
+        public void stopProcess() {
+          cancel();
+        }
+
+        public boolean isProcessStopped() {
+          return !myIndicator.isRunning();
+        }
+      });
+      component = myErrorTreeView.getComponent();
+    }
+    
+    final MessageView messageView = MessageView.SERVICE.getInstance(myProject);
+    final Content content = ContentFactory.SERVICE.getInstance().createContent(component, myContentName, true);
+    content.putUserData(myContentIdKey, myContentId);
+    messageView.getContentManager().addContent(content);
+    myCloseListener.setContent(content, messageView.getContentManager());
+    removeAllContents(myProject, content);
+    messageView.getContentManager().setSelectedContent(content);
+  }
+
+  public void showCompilerContent() {
+    synchronized (myMessageViewLock) {
+      if (myErrorTreeView != null) {
+        final MessageView messageView = MessageView.SERVICE.getInstance(myProject);
+        Content[] contents = messageView.getContentManager().getContents();
+        for (Content content : contents) {
+          if (content.getUserData(myContentIdKey) != null) {
+            messageView.getContentManager().setSelectedContent(content);
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  private void removeAllContents(Project project, Content notRemove) {
+    final MessageView messageView = MessageView.SERVICE.getInstance(project);
+    Content[] contents = messageView.getContentManager().getContents();
+    for (Content content : contents) {
+      if (content.isPinned()) {
+        continue;
+      }
+      if (content == notRemove) {
+        continue;
+      }
+      if (content.getUserData(myContentIdKey) != null) { // the content was added by me
+        messageView.getContentManager().removeContent(content, true);
+      }
+    }
+  }
+
+  private void activateMessageView() {
+    synchronized (myMessageViewLock) {
+      if (myErrorTreeView != null) {
+        final ToolWindow tw = ToolWindowManager.getInstance(myProject).getToolWindow(ToolWindowId.MESSAGES_WINDOW);
+        if (tw != null) {
+          tw.activate(null, false);
+        }
+      }
+    }
+  }
+
+  private void closeUI() {
+    if (isHeadlessMode()) {
+      return;
+    }
+    Window window = getWindow();
+    ModalityState modalityState = window != null ? ModalityState.stateForComponent(window) : ModalityState.NON_MODAL;
+    final Application application = ApplicationManager.getApplication();
+    application.invokeLater(new Runnable() {
+      public void run() {
+        synchronized (myMessageViewLock) {
+          if (myErrorTreeView != null) {
+            final boolean shouldRetainView = myErrorCount > 0 || myWarningCount > 0 && !myErrorTreeView.isHideWarnings();
+            if (shouldRetainView) {
+              addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.error.count", myErrorCount)));
+              addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.STATISTICS, CompilerBundle.message("statistics.warnings.count", myWarningCount)));
+              //activateMessageView();
+              myErrorTreeView.selectFirstMessage();
+            }
+            else {
+              removeAllContents(myProject, null);
+            }
+          }
+        }
+      }
+    }, modalityState);
+  }
+
+  public Window getWindow(){
+    return null;
+  }
+
+  public boolean isHeadless() {
+    return myHeadlessMode && !myForceAsyncExecution;
+  }
+
+  private boolean isHeadlessMode() {
+    return myHeadlessMode;
+  }
+
+  private static VirtualFile getVirtualFile(final CompilerMessage message) {
+    VirtualFile virtualFile = message.getVirtualFile();
+    if (virtualFile == null) {
+      Navigatable navigatable = message.getNavigatable();
+      if (navigatable instanceof OpenFileDescriptor) {
+        virtualFile = ((OpenFileDescriptor)navigatable).getFile();
+      }
+    }
+    return virtualFile;
+  }
+
+  public static TextRange getTextRange(final CompilerMessage message) {
+    Navigatable navigatable = message.getNavigatable();
+    if (navigatable instanceof OpenFileDescriptor) {
+      int offset = ((OpenFileDescriptor)navigatable).getOffset();
+      return new TextRange(offset, offset);
+    }
+    return TextRange.EMPTY_RANGE;
+  }
+
+  private class CloseListener extends ContentManagerAdapter implements ProjectManagerListener {
+    private Content myContent;
+    private ContentManager myContentManager;
+    private boolean myIsApplicationExitingOrProjectClosing = false;
+    private boolean myUserAcceptedCancel = false;
+
+    public boolean canCloseProject(final Project project) {
+      assert project != null;
+      if (!project.equals(myProject)) {
+        return true;
+      }
+      if (shouldAskUser()) {
+        int result = Messages.showOkCancelDialog(
+          myProject,
+          CompilerBundle.message("warning.compiler.running.on.project.close"),
+          CompilerBundle.message("compiler.running.dialog.title"),
+          Messages.getQuestionIcon()
+        );
+        if (result != 0) {
+          return false; // veto closing
+        }
+        myUserAcceptedCancel = true;
+
+        final MessageBusConnection connection = project.getMessageBus().connect();
+        connection.subscribe(CompilerTopics.COMPILATION_STATUS, new CompilationStatusAdapter() {
+          public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
+            connection.disconnect();
+            ProjectUtil.closeAndDispose(project);
+          }
+        });
+        cancel();
+        return false; // cancel compiler and let it finish, after compilation close the project, but currently - veto closing
+      }
+      return !myIndicator.isRunning();
+    }
+
+    public void setContent(Content content, ContentManager contentManager) {
+      myContent = content;
+      myContentManager = contentManager;
+      contentManager.addContentManagerListener(this);
+    }
+
+    public void contentRemoved(ContentManagerEvent event) {
+      if (event.getContent() == myContent) {
+        synchronized (myMessageViewLock) {
+          if (myErrorTreeView != null) {
+            myErrorTreeView.dispose();
+            myErrorTreeView = null;
+            if (myIndicator.isRunning()) {
+              cancel();
+            }
+            if (AppIcon.getInstance().hideProgress(myProject, "compiler")) {
+              AppIcon.getInstance().setErrorBadge(myProject, null);
+            }
+          }
+        }
+        myContentManager.removeContentManagerListener(this);
+        myContent.release();
+        myContent = null;
+      }
+    }
+
+    public void contentRemoveQuery(ContentManagerEvent event) {
+      if (event.getContent() == myContent) {
+        if (!myIndicator.isCanceled() && shouldAskUser()) {
+          int result = Messages.showOkCancelDialog(
+            myProject,
+            CompilerBundle.message("warning.compiler.running.on.toolwindow.close"),
+            CompilerBundle.message("compiler.running.dialog.title"),
+            Messages.getQuestionIcon()
+          );
+          if (result != 0) {
+            event.consume(); // veto closing
+          }
+          myUserAcceptedCancel = true;
+        }
+      }
+    }
+
+    private boolean shouldAskUser() {
+      // do not ask second time if user already accepted closing
+      return !myUserAcceptedCancel && !myIsApplicationExitingOrProjectClosing && myIndicator.isRunning();
+    }
+
+    public void projectOpened(Project project) {
+    }
+
+    public void projectClosed(Project project) {
+      if (project.equals(myProject) && myContent != null) {
+        myContentManager.removeContent(myContent, true);
+      }
+    }
+
+    public void projectClosing(Project project) {
+      if (project.equals(myProject)) {
+        myIsApplicationExitingOrProjectClosing = true;
+      }
+    }
+  }
+}
+                                      
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java
new file mode 100644
index 0000000..05bfe72
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/AutoMakeMessageHandler.java
@@ -0,0 +1,171 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.compiler.CompilerMessageImpl;
+import com.intellij.compiler.ProblemsView;
+import com.intellij.notification.Notification;
+import com.intellij.openapi.compiler.CompilationStatusListener;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.CompilerTopics;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.problems.Problem;
+import com.intellij.problems.WolfTheProblemSolver;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+
+import java.util.Collections;
+import java.util.UUID;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 4/25/12
+*/
+class AutoMakeMessageHandler extends DefaultMessageHandler {
+  private static final Key<Notification> LAST_AUTO_MAKE_NOFITICATION = Key.create("LAST_AUTO_MAKE_NOFITICATION");
+  private CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Status myBuildStatus;
+  private final Project myProject;
+  private final WolfTheProblemSolver myWolf;
+
+  public AutoMakeMessageHandler(Project project) {
+    super(project);
+    myProject = project;
+    myBuildStatus = CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.Status.SUCCESS;
+    myWolf = WolfTheProblemSolver.getInstance(project);
+  }
+
+  @Override
+  public void buildStarted(UUID sessionId) {
+  }
+
+  @Override
+  protected void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event) {
+    if (myProject.isDisposed()) {
+      return;
+    }
+    switch (event.getEventType()) {
+      case BUILD_COMPLETED:
+        if (event.hasCompletionStatus()) {
+          myBuildStatus = event.getCompletionStatus();
+        }
+        return;
+
+      case FILES_GENERATED:
+        final CompilationStatusListener publisher = myProject.getMessageBus().syncPublisher(CompilerTopics.COMPILATION_STATUS);
+        for (CmdlineRemoteProto.Message.BuilderMessage.BuildEvent.GeneratedFile generatedFile : event.getGeneratedFilesList()) {
+          final String root = FileUtil.toSystemIndependentName(generatedFile.getOutputRoot());
+          final String relativePath = FileUtil.toSystemIndependentName(generatedFile.getRelativePath());
+          publisher.fileGenerated(root, relativePath);
+        }
+        return;
+
+      default:
+        return;
+    }
+  }
+
+  @Override
+  protected void handleCompileMessage(final UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message) {
+    if (myProject.isDisposed()) {
+      return;
+    }
+    final CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind kind = message.getKind();
+    if (kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.PROGRESS) {
+      final ProblemsView view = ProblemsView.SERVICE.getInstance(myProject);
+      if (message.hasDone()) {
+        view.setProgress(message.getText(), message.getDone());
+      }
+      else {
+        view.setProgress(message.getText());
+      }
+    }
+    else if (kind == CmdlineRemoteProto.Message.BuilderMessage.CompileMessage.Kind.ERROR) {
+      informWolf(myProject, message);
+
+      final String sourceFilePath = message.hasSourceFilePath() ? message.getSourceFilePath() : null;
+      final VirtualFile vFile = sourceFilePath != null? LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(sourceFilePath)) : null;
+      final long line = message.hasLine() ? message.getLine() : -1;
+      final long column = message.hasColumn() ? message.getColumn() : -1;
+      ProblemsView.SERVICE.getInstance(myProject).addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.ERROR, message.getText(), vFile, (int)line, (int)column, null), sessionId);
+    }
+  }
+
+  @Override
+  public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) {
+    final String msg = "Auto make failure: " + failure.getDescription();
+    CompilerManager.NOTIFICATION_GROUP.createNotification(msg, MessageType.INFO);
+    ProblemsView.SERVICE.getInstance(myProject).addMessage(new CompilerMessageImpl(myProject, CompilerMessageCategory.ERROR, msg), sessionId);
+  }
+
+  @Override
+  public void sessionTerminated(UUID sessionId) {
+    String statusMessage = null/*"Auto make completed"*/;
+    switch (myBuildStatus) {
+      case SUCCESS:
+        //statusMessage = "Auto make completed successfully";
+        break;
+      case UP_TO_DATE:
+        //statusMessage = "All files are up-to-date";
+        break;
+      case ERRORS:
+        statusMessage = "Auto make completed with errors";
+        break;
+      case CANCELED:
+        //statusMessage = "Auto make has been canceled";
+        break;
+    }
+    if (statusMessage != null) {
+      final Notification notification = CompilerManager.NOTIFICATION_GROUP.createNotification(statusMessage, MessageType.INFO);
+      if (!myProject.isDisposed()) {
+        notification.notify(myProject);
+      }
+      myProject.putUserData(LAST_AUTO_MAKE_NOFITICATION, notification);
+    } 
+    else {
+      Notification notification = myProject.getUserData(LAST_AUTO_MAKE_NOFITICATION);
+      if (notification != null) {
+        notification.expire();
+        myProject.putUserData(LAST_AUTO_MAKE_NOFITICATION, null);
+      }
+    }
+    final ProblemsView view = ProblemsView.SERVICE.getInstance(myProject);
+    view.clearProgress();
+    view.clearOldMessages(null, sessionId);
+  }
+
+  private void informWolf(Project project, CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message) {
+    final String srcPath = message.getSourceFilePath();
+    if (srcPath != null && !project.isDisposed()) {
+      final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(srcPath);
+      if (vFile != null) {
+        final int line = (int)message.getLine();
+        final int column = (int)message.getColumn();
+        if (line > 0 && column > 0) {
+          final Problem problem = myWolf.convertToProblem(vFile, line, column, new String[]{message.getText()});
+          myWolf.weHaveGotProblems(vFile, Collections.singletonList(problem));
+        }
+        else {
+          myWolf.queue(vFile);
+        }
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
new file mode 100644
index 0000000..a819b47
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -0,0 +1,1100 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.ProjectTopics;
+import com.intellij.application.options.PathMacrosImpl;
+import com.intellij.compiler.CompilerWorkspaceConfiguration;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
+import com.intellij.compiler.server.impl.CompileServerClasspathManager;
+import com.intellij.execution.ExecutionAdapter;
+import com.intellij.execution.ExecutionException;
+import com.intellij.execution.ExecutionManager;
+import com.intellij.execution.configurations.GeneralCommandLine;
+import com.intellij.execution.configurations.RunProfile;
+import com.intellij.execution.process.*;
+import com.intellij.execution.ui.RunContentDescriptor;
+import com.intellij.execution.ui.RunContentManager;
+import com.intellij.ide.PowerSaveMode;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathMacros;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectCoreUtil;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.project.ProjectManagerAdapter;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.ModuleRootAdapter;
+import com.intellij.openapi.roots.ModuleRootEvent;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.ShutDownTracker;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.openapi.vfs.newvfs.BulkFileListener;
+import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
+import com.intellij.util.Alarm;
+import com.intellij.util.Function;
+import com.intellij.util.concurrency.SequentialTaskExecutor;
+import com.intellij.util.io.storage.HeavyProcessLatch;
+import com.intellij.util.messages.MessageBusConnection;
+import com.intellij.util.net.NetUtils;
+import gnu.trove.THashSet;
+import org.jboss.netty.bootstrap.ServerBootstrap;
+import org.jboss.netty.channel.*;
+import org.jboss.netty.channel.group.ChannelGroup;
+import org.jboss.netty.channel.group.ChannelGroupFuture;
+import org.jboss.netty.channel.group.DefaultChannelGroup;
+import org.jboss.netty.channel.socket.nio.NioServerSocketChannelFactory;
+import org.jboss.netty.handler.codec.protobuf.ProtobufDecoder;
+import org.jboss.netty.handler.codec.protobuf.ProtobufEncoder;
+import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32FrameDecoder;
+import org.jboss.netty.handler.codec.protobuf.ProtobufVarint32LengthFieldPrepender;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+import org.jetbrains.ide.PooledThreadExecutor;
+import org.jetbrains.jps.api.CmdlineProtoUtil;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+import org.jetbrains.jps.api.GlobalOptions;
+import org.jetbrains.jps.api.RequestFuture;
+import org.jetbrains.jps.cmdline.BuildMain;
+import org.jetbrains.jps.cmdline.ClasspathBootstrap;
+import org.jetbrains.jps.incremental.Utils;
+
+import javax.tools.*;
+import java.io.File;
+import java.io.FileOutputStream;
+import java.io.IOException;
+import java.io.InputStream;
+import java.net.InetAddress;
+import java.net.InetSocketAddress;
+import java.nio.charset.Charset;
+import java.util.*;
+import java.util.concurrent.Executor;
+import java.util.concurrent.RejectedExecutionException;
+import java.util.concurrent.TimeUnit;
+import java.util.concurrent.atomic.AtomicBoolean;
+
+import static org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 9/6/11
+ */
+public class BuildManager implements ApplicationComponent{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.BuildManager");
+  private static final String SYSTEM_ROOT = "compile-server";
+  private static final String LOGGER_CONFIG = "log.xml";
+  private static final String DEFAULT_LOGGER_CONFIG = "defaultLogConfig.xml";
+  private static final int MAKE_TRIGGER_DELAY = 3 * 1000 /*3 seconds*/;
+  private final boolean IS_UNIT_TEST_MODE;
+  private static final String IWS_EXTENSION = ".iws";
+  private static final String IPR_EXTENSION = ".ipr";
+  private static final String IDEA_PROJECT_DIR_PATTERN = "/.idea/";
+  private static final Function<String, Boolean> PATH_FILTER = 
+    SystemInfo.isFileSystemCaseSensitive?
+    new Function<String, Boolean>() {
+      @Override
+      public Boolean fun(String s) {
+        return !(s.contains(IDEA_PROJECT_DIR_PATTERN) || s.endsWith(IWS_EXTENSION) || s.endsWith(IPR_EXTENSION));
+      }
+    } :
+    new Function<String, Boolean>() {
+      @Override
+      public Boolean fun(String s) {
+        return !(StringUtil.endsWithIgnoreCase(s, IWS_EXTENSION) || StringUtil.endsWithIgnoreCase(s, IPR_EXTENSION) || StringUtil.containsIgnoreCase(s, IDEA_PROJECT_DIR_PATTERN));
+      }
+    };
+
+  private final File mySystemDirectory;
+  private final ProjectManager myProjectManager;
+
+  private final Map<RequestFuture, Project> myAutomakeFutures = new HashMap<RequestFuture, Project>();
+  private final Map<String, RequestFuture> myBuildsInProgress = Collections.synchronizedMap(new HashMap<String, RequestFuture>());
+  private final CompileServerClasspathManager myClasspathManager = new CompileServerClasspathManager();
+  private final Executor myPooledThreadExecutor = new PooledThreadExecutor();
+  private final SequentialTaskExecutor myRequestsProcessor = new SequentialTaskExecutor(myPooledThreadExecutor);
+  private final Map<String, ProjectData> myProjectDataMap = Collections.synchronizedMap(new HashMap<String, ProjectData>());
+
+  private final Alarm myAlarm = new Alarm(Alarm.ThreadToUse.SHARED_THREAD);
+  private final AtomicBoolean myAutoMakeInProgress = new AtomicBoolean(false);
+
+  private final ChannelGroup myAllOpenChannels = new DefaultChannelGroup("build-manager");
+  private final BuildMessageDispatcher myMessageDispatcher = new BuildMessageDispatcher();
+  private volatile int myListenPort = -1;
+  private volatile CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings myGlobals;
+  @Nullable
+  private final Charset mySystemCharset;
+
+  public BuildManager(final ProjectManager projectManager) {
+    IS_UNIT_TEST_MODE = ApplicationManager.getApplication().isUnitTestMode();
+    myProjectManager = projectManager;
+    mySystemCharset = CharsetToolkit.getDefaultSystemCharset();
+    final String systemPath = PathManager.getSystemPath();
+    File system = new File(systemPath);
+    try {
+      system = system.getCanonicalFile();
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+    mySystemDirectory = system;
+
+    projectManager.addProjectManagerListener(new ProjectWatcher());
+    
+    final MessageBusConnection conn = ApplicationManager.getApplication().getMessageBus().connect();
+    conn.subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
+      @Override
+      public void after(@NotNull List<? extends VFileEvent> events) {
+        if (shouldTriggerMake(events)) {
+          scheduleAutoMake();
+        }
+      }
+
+      private boolean shouldTriggerMake(List<? extends VFileEvent> events) {
+        if (PowerSaveMode.isEnabled()) {
+          return false;
+        }
+        List<Project> activeProjects = null;
+        for (VFileEvent event : events) {
+          final VirtualFile eventFile = event.getFile();
+          if (eventFile == null || ProjectCoreUtil.isProjectOrWorkspaceFile(eventFile)) {
+            continue;
+          }
+          
+          if (activeProjects == null) {
+            activeProjects = getActiveProjects();
+            if (activeProjects.isEmpty()) {
+              return false;
+            }
+          }
+          // todo: probably we do not need this excessive filtering
+          for (Project project : activeProjects) {
+            if (!project.isInitialized() || ProjectRootManager.getInstance(project).getFileIndex().isInContent(eventFile)) {
+              return true;
+            }
+          }
+        }
+        return false;
+      }
+
+      private List<Project> getActiveProjects() {
+        final Project[] projects = myProjectManager.getOpenProjects();
+        if (projects.length == 0) {
+          return Collections.emptyList();
+        }
+        final List<Project> projectList = new ArrayList<Project>();
+        for (Project project : projects) {
+          if (project.isDefault() || project.isDisposed()) {
+            continue;
+          }
+          projectList.add(project);
+        }
+        return projectList;
+      }
+    });
+
+    ShutDownTracker.getInstance().registerShutdownTask(new Runnable() {
+      @Override
+      public void run() {
+        stopListening();
+      }
+    });
+  }
+
+  public static BuildManager getInstance() {
+    return ApplicationManager.getApplication().getComponent(BuildManager.class);
+  }
+
+  public void notifyFilesChanged(final Collection<File> paths) {
+    doNotify(paths, false);
+  }
+
+  public void notifyFilesDeleted(Collection<File> paths) {
+    doNotify(paths, true);
+  }
+
+  public void runCommand(Runnable command) {
+    myRequestsProcessor.submit(command);
+  }
+
+  private void doNotify(final Collection<File> paths, final boolean notifyDeletion) {
+    // ensure events processed in the order they arrived
+    runCommand(new Runnable() {
+
+      @Override
+      public void run() {
+        final List<String> filtered = new ArrayList<String>(paths.size());
+        for (File file : paths) {
+          final String path = FileUtil.toSystemIndependentName(file.getPath());
+          if (PATH_FILTER.fun(path)) {
+            filtered.add(path);
+          }
+        }
+        if (filtered.isEmpty()) {
+          return;
+        }
+        synchronized (myProjectDataMap) {
+          if (IS_UNIT_TEST_MODE) {
+            if (notifyDeletion) {
+              LOG.info("Registering deleted paths: " + filtered);
+            }
+            else {
+              LOG.info("Registering changed paths: " + filtered);
+            }
+          }
+          for (Map.Entry<String, ProjectData> entry : myProjectDataMap.entrySet()) {
+            final ProjectData data = entry.getValue();
+            if (notifyDeletion) {
+              data.addDeleted(filtered);
+            }
+            else {
+              data.addChanged(filtered);
+            }
+            final RequestFuture future = myBuildsInProgress.get(entry.getKey());
+            if (future != null && !future.isCancelled() && !future.isDone()) {
+              final UUID sessionId = future.getRequestID();
+              final Channel channel = myMessageDispatcher.getConnectedChannel(sessionId);
+              if (channel != null) {
+                final CmdlineRemoteProto.Message.ControllerMessage message =
+                  CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType(
+                    CmdlineRemoteProto.Message.ControllerMessage.Type.FS_EVENT).setFsEvent(data.createNextEvent()).build();
+                Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, message));
+              }
+            }
+          }
+        }
+      }
+    });
+  }
+
+  public static void forceModelLoading(CompileContext context) {
+    context.getCompileScope().putUserData(BuildMain.FORCE_MODEL_LOADING_PARAMETER, Boolean.TRUE.toString());
+  }
+
+  public void clearState(Project project) {
+    myGlobals = null;
+    final String projectPath = getProjectPath(project);
+    synchronized (myProjectDataMap) {
+      final ProjectData data = myProjectDataMap.get(projectPath);
+      if (data != null) {
+        data.dropChanges();
+      }
+    }
+    scheduleAutoMake();
+  }
+
+  public boolean rescanRequired(Project project) {
+    final String projectPath = getProjectPath(project);
+    synchronized (myProjectDataMap) {
+      final ProjectData data = myProjectDataMap.get(projectPath);
+      return data == null || data.myNeedRescan;
+    }
+  }
+
+  @Nullable
+  public List<String> getFilesChangedSinceLastCompilation(Project project) {
+    String projectPath = getProjectPath(project);
+    synchronized (myProjectDataMap) {
+      ProjectData data = myProjectDataMap.get(projectPath);
+      if (data != null && !data.myNeedRescan) {
+        return new ArrayList<String>(data.myChanged);
+      }
+      return null;
+    }
+  }
+
+  @Nullable
+  private static String getProjectPath(final Project project) {
+    final String url = project.getPresentableUrl();
+    if (url == null) {
+      return null;
+    }
+    return VirtualFileManager.extractPath(url);
+  }
+
+  public void scheduleAutoMake() {
+    if (IS_UNIT_TEST_MODE || PowerSaveMode.isEnabled()) {
+      return;
+    }
+    addMakeRequest(new Runnable() {
+      @Override
+      public void run() {
+        if (!HeavyProcessLatch.INSTANCE.isRunning() && !myAutoMakeInProgress.getAndSet(true)) {
+          try {
+            ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+              @Override
+              public void run() {
+                try {
+                  runAutoMake();
+                }
+                finally {
+                  myAutoMakeInProgress.set(false);
+                }
+              }
+            });
+          }
+          catch (RejectedExecutionException ignored) {
+            // we were shut down
+            myAutoMakeInProgress.set(false);
+          }
+          catch (Throwable e) {
+            myAutoMakeInProgress.set(false);
+            throw new RuntimeException(e);
+          }
+        }
+        else {
+          addMakeRequest(this);
+        }
+      }
+    });
+  }
+
+  private void addMakeRequest(Runnable runnable) {
+    myAlarm.cancelAllRequests();
+    final int delay = Math.max(50, Registry.intValue("compiler.automake.trigger.delay", MAKE_TRIGGER_DELAY));
+    myAlarm.addRequest(runnable, delay);
+  }
+
+  private void runAutoMake() {
+    final Project[] openProjects = myProjectManager.getOpenProjects();
+    if (openProjects.length > 0) {
+      final List<RequestFuture> futures = new ArrayList<RequestFuture>();
+      for (final Project project : openProjects) {
+        if (project.isDefault() || project.isDisposed()) {
+          continue;
+        }
+        final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project);
+        if (!config.useOutOfProcessBuild() || !config.MAKE_PROJECT_ON_SAVE) {
+          continue;
+        }
+        if (!config.allowAutoMakeWhileRunningApplication()) {
+          final RunContentManager contentManager = ExecutionManager.getInstance(project).getContentManager();
+          boolean hasRunningProcesses = false;
+          for (RunContentDescriptor descriptor : contentManager.getAllDescriptors()) {
+            final ProcessHandler handler = descriptor.getProcessHandler();
+            if (handler != null && !handler.isProcessTerminated()) { // active process
+              hasRunningProcesses = true;
+              break;
+            }
+          }
+          if (hasRunningProcesses) {
+            continue;
+          }
+        }
+
+        final List<String> emptyList = Collections.emptyList();
+        final RequestFuture future = scheduleBuild(
+          project, false, true, false, CmdlineProtoUtil.createAllModulesScopes(), emptyList, Collections.<String, String>emptyMap(), new AutoMakeMessageHandler(project)
+        );
+        if (future != null) {
+          futures.add(future);
+          synchronized (myAutomakeFutures) {
+            myAutomakeFutures.put(future, project);
+          }
+        }
+      }
+      try {
+        for (RequestFuture future : futures) {
+          future.waitFor();
+        }
+      }
+      finally {
+        synchronized (myAutomakeFutures) {
+          myAutomakeFutures.keySet().removeAll(futures);
+        }
+      }
+    }
+  }
+
+  public Collection<RequestFuture> cancelAutoMakeTasks(Project project) {
+    final Collection<RequestFuture> futures = new ArrayList<RequestFuture>();
+    synchronized (myAutomakeFutures) {
+      for (Map.Entry<RequestFuture, Project> entry : myAutomakeFutures.entrySet()) {
+        if (entry.getValue().equals(project)) {
+          final RequestFuture future = entry.getKey();
+          future.cancel(false);
+          futures.add(future);
+        }
+      }
+    }
+    return futures;
+  }
+
+  @Nullable
+  public RequestFuture scheduleBuild(
+    final Project project, final boolean isRebuild, final boolean isMake,
+    final boolean onlyCheckUpToDate, final List<TargetTypeBuildScope> scopes,
+    final Collection<String> paths,
+    final Map<String, String> userData, final DefaultMessageHandler handler) {
+
+    final String projectPath = getProjectPath(project);
+    final UUID sessionId = UUID.randomUUID();
+
+    // ensure server is listening
+    if (myListenPort < 0) {
+      try {
+        synchronized (this) {
+          if (myListenPort < 0) {
+            myListenPort = startListening();
+          }
+        }
+      }
+      catch (Exception e) {
+        handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), null));
+        handler.sessionTerminated(sessionId);
+        return null;
+      }
+    }
+
+    try {
+      final RequestFuture<BuilderMessageHandler> future = new RequestFuture<BuilderMessageHandler>(handler, sessionId, new RequestFuture.CancelAction<BuilderMessageHandler>() {
+        @Override
+        public void cancel(RequestFuture<BuilderMessageHandler> future) throws Exception {
+          myMessageDispatcher.cancelSession(future.getRequestID());
+        }
+      });
+      // by using the same queue that processes events we ensure that
+      // the build will be aware of all events that have happened before this request
+      runCommand(new Runnable() {
+        @Override
+        public void run() {
+          if (future.isCancelled() || project.isDisposed()) {
+            handler.sessionTerminated(sessionId);
+            future.setDone();
+            return;
+          }
+
+          CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings globals = myGlobals;
+          if (globals == null) {
+            globals = buildGlobalSettings();
+            myGlobals = globals;
+          }
+          CmdlineRemoteProto.Message.ControllerMessage.FSEvent currentFSChanges;
+          final SequentialTaskExecutor projectTaskQueue;
+          synchronized (myProjectDataMap) {
+            ProjectData data = myProjectDataMap.get(projectPath);
+            if (data == null) {
+              data = new ProjectData(new SequentialTaskExecutor(myPooledThreadExecutor));
+              myProjectDataMap.put(projectPath, data);
+            }
+            if (isRebuild) {
+              data.dropChanges();
+            }
+            if (IS_UNIT_TEST_MODE) {
+              LOG.info("Scheduling build for " +
+                       projectPath +
+                       "; CHANGED: " +
+                       new HashSet<String>(data.myChanged) +
+                       "; DELETED: " +
+                       new HashSet<String>(data.myDeleted));
+            }
+            currentFSChanges = data.getAndResetRescanFlag() ? null : data.createNextEvent();
+            projectTaskQueue = data.taskQueue;
+          }
+
+          final CmdlineRemoteProto.Message.ControllerMessage params;
+          if (isRebuild) {
+            params = CmdlineProtoUtil.createRebuildRequest(projectPath, scopes, userData, globals);
+          }
+          else if (onlyCheckUpToDate) {
+            params = CmdlineProtoUtil.createUpToDateCheckRequest(projectPath, scopes, paths, userData, globals, currentFSChanges);
+          }
+          else {
+            params = isMake ?
+                     CmdlineProtoUtil.createMakeRequest(projectPath, scopes, userData, globals, currentFSChanges) :
+                     CmdlineProtoUtil.createForceCompileRequest(projectPath, scopes, paths, userData, globals, currentFSChanges);
+          }
+
+          myMessageDispatcher.registerBuildMessageHandler(sessionId, new BuilderMessageHandlerWrapper(handler) {
+            @Override
+            public void sessionTerminated(UUID sessionId) {
+              try {
+                super.sessionTerminated(sessionId);
+              }
+              finally {
+                future.setDone();
+              }
+            }
+          }, params);
+
+          try {
+            projectTaskQueue.submit(new Runnable() {
+              @Override
+              public void run() {
+                ExecutionException execFailure = null;
+                try {
+                  if (project.isDisposed()) {
+                    return;
+                  }
+                  myBuildsInProgress.put(projectPath, future);
+                  final OSProcessHandler processHandler = launchBuildProcess(project, myListenPort, sessionId);
+                  final StringBuilder stdErrOutput = new StringBuilder();
+                  processHandler.addProcessListener(new ProcessAdapter() {
+                    @Override
+                    public void onTextAvailable(ProcessEvent event, Key outputType) {
+                      // re-translate builder's output to idea.log
+                      final String text = event.getText();
+                      if (!StringUtil.isEmptyOrSpaces(text)) {
+                        LOG.info("BUILDER_PROCESS [" + outputType.toString() + "]: " + text.trim());
+                        if (stdErrOutput.length() < 1024 && ProcessOutputTypes.STDERR.equals(outputType)) {
+                          stdErrOutput.append(text);
+                        }
+                      }
+                    }
+                  });
+                  processHandler.startNotify();
+                  final boolean terminated = processHandler.waitFor();
+                  if (terminated) {
+                    final int exitValue = processHandler.getProcess().exitValue();
+                    if (exitValue != 0) {
+                      final StringBuilder msg = new StringBuilder();
+                      msg.append("Abnormal build process termination: ");
+                      if (stdErrOutput.length() > 0) {
+                        msg.append("\n").append(stdErrOutput);
+                      }
+                      else {
+                        msg.append("unknown error");
+                      }
+                      handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(msg.toString(), null));
+                    }
+                  }
+                  else {
+                    handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure("Disconnected from build process", null));
+                  }
+                }
+                catch (ExecutionException e) {
+                  execFailure = e;
+                }
+                finally {
+                  myBuildsInProgress.remove(projectPath);
+                  if (myMessageDispatcher.getAssociatedChannel(sessionId) == null) {
+                    // either the connection has never been established (process not started or execution failed), or no messages were sent from the launched process.
+                    // in this case the session cannot be unregistered by the message dispatcher
+                    final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
+                    if (unregistered != null) {
+                      if (execFailure != null) {
+                        unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(execFailure.getMessage(), execFailure));
+                      }
+                      unregistered.sessionTerminated(sessionId);
+                    }
+                  }
+                }
+              }
+            });
+          }
+          catch (Throwable e) {
+            final BuilderMessageHandler unregistered = myMessageDispatcher.unregisterBuildMessageHandler(sessionId);
+            if (unregistered != null) {
+              unregistered.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
+              unregistered.sessionTerminated(sessionId);
+            }
+          }
+        }
+      });
+
+      return future;
+    }
+    catch (Throwable e) {
+      handler.handleFailure(sessionId, CmdlineProtoUtil.createFailure(e.getMessage(), e));
+      handler.sessionTerminated(sessionId);
+    }
+
+    return null;
+  }
+
+  @Override
+  public void initComponent() {
+  }
+
+  @Override
+  public void disposeComponent() {
+    stopListening();
+  }
+
+  @NotNull
+  @Override
+  public String getComponentName() {
+    return "com.intellij.compiler.server.BuildManager";
+  }
+
+  private static CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings buildGlobalSettings() {
+    final Map<String, String> data = new HashMap<String, String>();
+
+    for (Map.Entry<String, String> entry : PathMacrosImpl.getGlobalSystemMacros().entrySet()) {
+      data.put(entry.getKey(), FileUtil.toSystemIndependentName(entry.getValue()));
+    }
+
+    final PathMacros pathVars = PathMacros.getInstance();
+    for (String name : pathVars.getAllMacroNames()) {
+      final String path = pathVars.getValue(name);
+      if (path != null) {
+        data.put(name, FileUtil.toSystemIndependentName(path));
+      }
+    }
+
+    final CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.Builder cmdBuilder =
+      CmdlineRemoteProto.Message.ControllerMessage.GlobalSettings.newBuilder();
+
+    cmdBuilder.setGlobalOptionsPath(PathManager.getOptionsPath());
+
+    if (!data.isEmpty()) {
+      for (Map.Entry<String, String> entry : data.entrySet()) {
+        final String var = entry.getKey();
+        final String value = entry.getValue();
+        if (var != null && value != null) {
+          cmdBuilder.addPathVariable(CmdlineProtoUtil.createPair(var, value));
+        }
+      }
+    }
+
+    return cmdBuilder.build();
+  }
+
+  private OSProcessHandler launchBuildProcess(Project project, final int port, final UUID sessionId) throws ExecutionException {
+    // choosing sdk with which the build process should be run
+    Sdk projectJdk = null;
+    JavaSdkVersion sdkVersion = null;
+    int sdkMinorVersion = 0;
+
+    final Set<Sdk> candidates = new HashSet<Sdk>();
+    for (Module module : ModuleManager.getInstance(project).getModules()) {
+      final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+      if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
+        candidates.add(sdk);
+      }
+    }
+    // now select the latest version from the sdks that are used in the project, but not older than the internal sdk version
+    for (Sdk candidate : candidates) {
+      final String vs = candidate.getVersionString();
+      if (vs != null) {
+        final JavaSdkVersion candidateVersion = ((JavaSdk)candidate.getSdkType()).getVersion(vs);
+        if (candidateVersion != null) {
+          final int candidateMinorVersion = getMinorVersion(vs);
+          if (projectJdk == null) {
+            sdkVersion = candidateVersion;
+            sdkMinorVersion = candidateMinorVersion;
+            projectJdk = candidate;
+          }
+          else {
+            final int result = candidateVersion.compareTo(sdkVersion);
+            if (result > 0 || (result == 0 && candidateMinorVersion > sdkMinorVersion)) {
+              sdkVersion = candidateVersion;
+              sdkMinorVersion = candidateMinorVersion;
+              projectJdk = candidate;
+            }
+          }
+        }
+      }
+    }
+
+    final Sdk internalJdk = JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
+    if (projectJdk == null || sdkVersion == null || !sdkVersion.isAtLeast(JavaSdkVersion.JDK_1_6)) {
+      projectJdk = internalJdk;
+    }
+
+    // validate tools.jar presence
+    final String compilerPath;
+    if (projectJdk.equals(internalJdk)) {
+      final JavaCompiler systemCompiler = ToolProvider.getSystemJavaCompiler();
+      if (systemCompiler == null) {
+        throw new ExecutionException("No system java compiler is provided by the JRE. Make sure tools.jar is present in IntelliJ IDEA classpath.");
+      }
+      compilerPath = ClasspathBootstrap.getResourcePath(systemCompiler.getClass());
+    }
+    else {
+      compilerPath = ((JavaSdk)projectJdk.getSdkType()).getToolsPath(projectJdk);
+      if (compilerPath == null) {
+        throw new ExecutionException("Cannot determine path to 'tools.jar' library for " + projectJdk.getName() + " (" + projectJdk.getHomePath() + ")");
+      }
+    }
+
+    final CompilerWorkspaceConfiguration config = CompilerWorkspaceConfiguration.getInstance(project);
+    final GeneralCommandLine cmdLine = new GeneralCommandLine();
+    final String vmExecutablePath = ((JavaSdkType)projectJdk.getSdkType()).getVMExecutablePath(projectJdk);
+    cmdLine.setExePath(vmExecutablePath);
+    //cmdLine.addParameter("-XX:MaxPermSize=150m");
+    //cmdLine.addParameter("-XX:ReservedCodeCacheSize=64m");
+    int heapSize = config.COMPILER_PROCESS_HEAP_SIZE;
+
+    // todo: remove when old make implementation is removed
+    if (heapSize == CompilerWorkspaceConfiguration.DEFAULT_COMPILE_PROCESS_HEAP_SIZE) {
+      // check if javac is set to use larger heap, and if so, use it.
+      heapSize = Math.max(heapSize, JavacConfiguration.getOptions(project, JavacConfiguration.class).MAXIMUM_HEAP_SIZE);
+    }
+
+    cmdLine.addParameter("-Xmx" + heapSize + "m");
+
+    if (SystemInfo.isMac && sdkVersion != null && JavaSdkVersion.JDK_1_6.equals(sdkVersion) && Registry.is("compiler.process.32bit.vm.on.mac")) {
+      // unfortunately -d32 is supported on jdk 1.6 only
+      cmdLine.addParameter("-d32");
+    }
+
+    cmdLine.addParameter("-Djava.awt.headless=true");
+    if (IS_UNIT_TEST_MODE) {
+      cmdLine.addParameter("-Dtest.mode=true");
+    }
+    cmdLine.addParameter("-Djdt.compiler.useSingleThread=true"); // always run eclipse compiler in single-threaded mode
+
+    final String shouldGenerateIndex = System.getProperty(GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION);
+    if (shouldGenerateIndex != null) {
+      cmdLine.addParameter("-D"+ GlobalOptions.GENERATE_CLASSPATH_INDEX_OPTION +"=" + shouldGenerateIndex);
+    }
+    cmdLine.addParameter("-D"+ GlobalOptions.COMPILE_PARALLEL_OPTION +"=" + Boolean.toString(config.PARALLEL_COMPILATION));
+
+    boolean isProfilingMode = false;
+    final String additionalOptions = config.COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS;
+    if (!StringUtil.isEmpty(additionalOptions)) {
+      final StringTokenizer tokenizer = new StringTokenizer(additionalOptions, " ", false);
+      while (tokenizer.hasMoreTokens()) {
+        final String option = tokenizer.nextToken();
+        if ("-Dprofiling.mode=true".equals(option)) {
+          isProfilingMode = true;
+        }
+        cmdLine.addParameter(option);
+      }
+    }
+
+    // debugging
+    final int debugPort = Registry.intValue("compiler.process.debug.port");
+    if (debugPort > 0) {
+      cmdLine.addParameter("-XX:+HeapDumpOnOutOfMemoryError");
+      cmdLine.addParameter("-agentlib:jdwp=transport=dt_socket,server=y,suspend=y,address=" + debugPort);
+    }
+
+    if (Registry.is("compiler.process.use.memory.temp.cache")) {
+      cmdLine.addParameter("-D"+ GlobalOptions.USE_MEMORY_TEMP_CACHE_OPTION);
+    }
+    if (Registry.is("compiler.process.use.external.javac")) {
+      cmdLine.addParameter("-D"+ GlobalOptions.USE_EXTERNAL_JAVAC_OPTION);
+    }
+
+    // javac's VM should use the same default locale that IDEA uses in order for javac to print messages in 'correct' language
+    if (mySystemCharset != null) {
+      cmdLine.setCharset(mySystemCharset);
+      cmdLine.addParameter("-D" + CharsetToolkit.FILE_ENCODING_PROPERTY + "=" + mySystemCharset.name());
+    }
+    for (String name : new String[]{"user.language", "user.country", "user.region", PathManager.PROPERTY_HOME_PATH}) {
+      final String value = System.getProperty(name);
+      if (value != null) {
+        cmdLine.addParameter("-D" + name + "=" + value);
+      }
+    }
+
+    final File workDirectory = getBuildSystemDirectory();
+    workDirectory.mkdirs();
+    ensureLogConfigExists(workDirectory);
+
+    final List<String> cp = ClasspathBootstrap.getBuildProcessApplicationClasspath();
+    cp.add(compilerPath);
+    cp.addAll(myClasspathManager.getCompileServerPluginsClasspath(project));
+    if (isProfilingMode) {
+      cp.add(new File(workDirectory, "yjp-controller-api-redist.jar").getPath());
+      cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,sessionname=ExternalBuild");
+    }
+
+    cmdLine.addParameter("-classpath");
+    cmdLine.addParameter(classpathToString(cp));
+
+    cmdLine.addParameter(BuildMain.class.getName());
+    cmdLine.addParameter("127.0.0.1");
+    cmdLine.addParameter(Integer.toString(port));
+    cmdLine.addParameter(sessionId.toString());
+
+    cmdLine.addParameter(FileUtil.toSystemIndependentName(workDirectory.getPath()));
+
+    cmdLine.setWorkDirectory(workDirectory);
+
+    final Process process = cmdLine.createProcess();
+
+    return new OSProcessHandler(process, null, mySystemCharset) {
+      @Override
+      protected boolean shouldDestroyProcessRecursively() {
+        return true;
+      }
+    };
+  }
+
+  public File getBuildSystemDirectory() {
+    return new File(mySystemDirectory, SYSTEM_ROOT);
+  }
+
+  @Nullable
+  public File getProjectSystemDirectory(Project project) {
+    final String projectPath = getProjectPath(project);
+    return projectPath != null? Utils.getDataStorageRoot(getBuildSystemDirectory(), projectPath) : null;
+  }
+
+  private static int getMinorVersion(String vs) {
+    final int dashIndex = vs.lastIndexOf('_');
+    if (dashIndex >= 0) {
+      StringBuilder builder = new StringBuilder();
+      for (int idx = dashIndex + 1; idx < vs.length(); idx++) {
+        final char ch = vs.charAt(idx);
+        if (Character.isDigit(ch)) {
+          builder.append(ch);
+        }
+        else {
+          break;
+        }
+      }
+      if (builder.length() > 0) {
+        try {
+          return Integer.parseInt(builder.toString());
+        }
+        catch (NumberFormatException ignored) {
+        }
+      }
+    }
+    return 0;
+  }
+
+  private static void ensureLogConfigExists(File workDirectory) {
+    final File logConfig = new File(workDirectory, LOGGER_CONFIG);
+    if (!logConfig.exists()) {
+      FileUtil.createIfDoesntExist(logConfig);
+      try {
+        final InputStream in = BuildMain.class.getResourceAsStream("/" + DEFAULT_LOGGER_CONFIG);
+        if (in != null) {
+          try {
+            final FileOutputStream out = new FileOutputStream(logConfig);
+            try {
+              FileUtil.copy(in, out);
+            }
+            finally {
+              out.close();
+            }
+          }
+          finally {
+            in.close();
+          }
+        }
+      }
+      catch (IOException e) {
+        LOG.error(e);
+      }
+    }
+  }
+
+  public void stopListening() {
+    final ChannelGroupFuture closeFuture = myAllOpenChannels.close();
+    closeFuture.awaitUninterruptibly();
+  }
+
+  private int startListening() throws Exception {
+    final ChannelFactory channelFactory = new NioServerSocketChannelFactory(myPooledThreadExecutor, myPooledThreadExecutor, 1);
+    final SimpleChannelUpstreamHandler channelRegistrar = new SimpleChannelUpstreamHandler() {
+      public void channelOpen(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+        myAllOpenChannels.add(e.getChannel());
+        super.channelOpen(ctx, e);
+      }
+
+      @Override
+      public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+        myAllOpenChannels.remove(e.getChannel());
+        super.channelClosed(ctx, e);
+      }
+    };
+    ChannelPipelineFactory pipelineFactory = new ChannelPipelineFactory() {
+      public ChannelPipeline getPipeline() throws Exception {
+        return Channels.pipeline(
+          channelRegistrar,
+          new ProtobufVarint32FrameDecoder(),
+          new ProtobufDecoder(CmdlineRemoteProto.Message.getDefaultInstance()),
+          new ProtobufVarint32LengthFieldPrepender(),
+          new ProtobufEncoder(),
+          myMessageDispatcher
+        );
+      }
+    };
+    final ServerBootstrap bootstrap = new ServerBootstrap(channelFactory);
+    bootstrap.setPipelineFactory(pipelineFactory);
+    bootstrap.setOption("child.tcpNoDelay", true);
+    bootstrap.setOption("child.keepAlive", true);
+    final int listenPort = NetUtils.findAvailableSocketPort();
+    final Channel serverChannel = bootstrap.bind(new InetSocketAddress(InetAddress.getByName("127.0.0.1"), listenPort));
+    myAllOpenChannels.add(serverChannel);
+    return listenPort;
+  }
+
+  @TestOnly
+  public void stopWatchingProject(Project project) {
+    myProjectDataMap.remove(getProjectPath(project));
+  }
+
+  private static String classpathToString(List<String> cp) {
+    StringBuilder builder = new StringBuilder();
+    for (String file : cp) {
+      if (builder.length() > 0) {
+        builder.append(File.pathSeparator);
+      }
+      builder.append(FileUtil.toCanonicalPath(file));
+    }
+    return builder.toString();
+  }
+
+  private static class BuilderMessageHandlerWrapper implements BuilderMessageHandler {
+    private final DefaultMessageHandler myHandler;
+
+    public BuilderMessageHandlerWrapper(DefaultMessageHandler handler) {
+      myHandler = handler;
+    }
+
+    @Override
+    public void buildStarted(UUID sessionId) {
+      myHandler.buildStarted(sessionId);
+    }
+
+    @Override
+    public void handleBuildMessage(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage msg) {
+      myHandler.handleBuildMessage(channel, sessionId, msg);
+    }
+
+    @Override
+    public void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure) {
+      myHandler.handleFailure(sessionId, failure);
+    }
+
+    @Override
+    public void sessionTerminated(UUID sessionId) {
+      myHandler.sessionTerminated(sessionId);
+    }
+  }
+
+  private class ProjectWatcher extends ProjectManagerAdapter {
+    private final Map<Project, MessageBusConnection> myConnections = new HashMap<Project, MessageBusConnection>();
+
+    @Override
+    public void projectOpened(final Project project) {
+      final MessageBusConnection conn = project.getMessageBus().connect();
+      myConnections.put(project, conn);
+      conn.subscribe(ProjectTopics.PROJECT_ROOTS, new ModuleRootAdapter() {
+        @Override
+        public void rootsChanged(final ModuleRootEvent event) {
+          final Object source = event.getSource();
+          if (source instanceof Project) {
+            clearState((Project)source);
+          }
+        }
+      });
+      conn.subscribe(ExecutionManager.EXECUTION_TOPIC, new ExecutionAdapter() {
+        @Override
+        public void processTerminated(@NotNull RunProfile runProfile, @NotNull ProcessHandler handler) {
+          scheduleAutoMake();
+        }
+      });
+      final String projectPath = getProjectPath(project);
+      Disposer.register(project, new Disposable() {
+        @Override
+        public void dispose() {
+          myProjectDataMap.remove(projectPath);
+        }
+      });
+      scheduleAutoMake(); // run automake on project opening
+    }
+
+    @Override
+    public boolean canCloseProject(Project project) {
+      cancelAutoMakeTasks(project);
+      return super.canCloseProject(project);
+    }
+
+    @Override
+    public void projectClosing(Project project) {
+      for (RequestFuture future : cancelAutoMakeTasks(project)) {
+        future.waitFor(500, TimeUnit.MILLISECONDS);
+      }
+    }
+
+    @Override
+    public void projectClosed(Project project) {
+      myProjectDataMap.remove(getProjectPath(project));
+      final MessageBusConnection conn = myConnections.remove(project);
+      if (conn != null) {
+        conn.disconnect();
+      }
+    }
+  }
+
+  private static class ProjectData {
+    final SequentialTaskExecutor taskQueue;
+    private final Set<String> myChanged = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
+    private final Set<String> myDeleted = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
+    private long myNextEventOrdinal = 0L;
+    private boolean myNeedRescan = true;
+
+    private ProjectData(SequentialTaskExecutor taskQueue) {
+      this.taskQueue = taskQueue;
+    }
+
+    public void addChanged(Collection<String> paths) {
+      if (!myNeedRescan) {
+        myDeleted.removeAll(paths);
+        myChanged.addAll(paths);
+      }
+    }
+
+    public void addDeleted(Collection<String> paths) {
+      if (!myNeedRescan) {
+        myChanged.removeAll(paths);
+        myDeleted.addAll(paths);
+      }
+    }
+
+    public CmdlineRemoteProto.Message.ControllerMessage.FSEvent createNextEvent() {
+      final CmdlineRemoteProto.Message.ControllerMessage.FSEvent.Builder builder =
+        CmdlineRemoteProto.Message.ControllerMessage.FSEvent.newBuilder();
+      builder.setOrdinal(++myNextEventOrdinal);
+      builder.addAllChangedPaths(myChanged);
+      myChanged.clear();
+      builder.addAllDeletedPaths(myDeleted);
+      myDeleted.clear();
+      return builder.build();
+    }
+
+    public boolean getAndResetRescanFlag() {
+      final boolean rescan = myNeedRescan;
+      myNeedRescan = false;
+      return rescan;
+    }
+
+    public void dropChanges() {
+      myNeedRescan = true;
+      myNextEventOrdinal = 0L;
+      myChanged.clear();
+      myDeleted.clear();
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java
new file mode 100644
index 0000000..0c49759
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildMessageDispatcher.java
@@ -0,0 +1,195 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.util.containers.ConcurrentHashSet;
+import org.jboss.netty.channel.*;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.api.CmdlineProtoUtil;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+
+import java.util.Map;
+import java.util.Set;
+import java.util.UUID;
+import java.util.concurrent.ConcurrentHashMap;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 4/25/12
+*/
+class BuildMessageDispatcher extends SimpleChannelHandler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.BuildMessageDispatcher");
+  private final Map<UUID, SessionData> myMessageHandlers = new ConcurrentHashMap<UUID, SessionData>();
+  private final Set<UUID> myCanceledSessions = new ConcurrentHashSet<UUID>();
+
+  public void registerBuildMessageHandler(UUID sessionId,
+                                          BuilderMessageHandler handler,
+                                          CmdlineRemoteProto.Message.ControllerMessage params) {
+    myMessageHandlers.put(sessionId, new SessionData(sessionId, handler, params));
+  }
+
+  @Nullable
+  public BuilderMessageHandler unregisterBuildMessageHandler(UUID sessionId) {
+    myCanceledSessions.remove(sessionId);
+    final SessionData data = myMessageHandlers.remove(sessionId);
+    return data != null? data.handler : null;
+  }
+
+  public void cancelSession(UUID sessionId) {
+    if (myCanceledSessions.add(sessionId)) {
+      final Channel channel = getConnectedChannel(sessionId);
+      if (channel != null) {
+        Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
+      }
+    }
+  }
+
+  @Nullable
+  public Channel getConnectedChannel(final UUID sessionId) {
+    final Channel channel = getAssociatedChannel(sessionId);
+    return channel != null && channel.isConnected()? channel : null;
+  }
+
+  @Nullable
+  public Channel getAssociatedChannel(final UUID sessionId) {
+    final SessionData data = myMessageHandlers.get(sessionId);
+    return data != null? data.channel : null;
+  }
+
+
+  @Override
+  public void messageReceived(ChannelHandlerContext ctx, MessageEvent e) throws Exception {
+    final CmdlineRemoteProto.Message message = (CmdlineRemoteProto.Message)e.getMessage();
+
+    SessionData sessionData = (SessionData)ctx.getAttachment();
+
+    UUID sessionId;
+    if (sessionData == null) {
+      // this is the first message for this session, so fill session data with missing info
+      final CmdlineRemoteProto.Message.UUID id = message.getSessionId();
+      sessionId = new UUID(id.getMostSigBits(), id.getLeastSigBits());
+
+      sessionData = myMessageHandlers.get(sessionId);
+      if (sessionData != null) {
+        sessionData.channel = ctx.getChannel();
+        ctx.setAttachment(sessionData);
+      }
+      if (myCanceledSessions.contains(sessionId)) {
+        Channels.write(ctx.getChannel(), CmdlineProtoUtil.toMessage(sessionId, CmdlineProtoUtil.createCancelCommand()));
+      }
+    }
+    else {
+      sessionId = sessionData.sessionId;
+    }
+
+    final BuilderMessageHandler handler = sessionData != null? sessionData.handler : null;
+    if (handler == null) {
+      // todo
+      LOG.info("No message handler registered for session " + sessionId);
+      return;
+    }
+
+    final CmdlineRemoteProto.Message.Type messageType = message.getType();
+    switch (messageType) {
+      case FAILURE:
+        handler.handleFailure(sessionId, message.getFailure());
+        break;
+
+      case BUILDER_MESSAGE:
+        final CmdlineRemoteProto.Message.BuilderMessage builderMessage = message.getBuilderMessage();
+        final CmdlineRemoteProto.Message.BuilderMessage.Type msgType = builderMessage.getType();
+        if (msgType == CmdlineRemoteProto.Message.BuilderMessage.Type.PARAM_REQUEST) {
+          final CmdlineRemoteProto.Message.ControllerMessage params = sessionData.params;
+          if (params != null) {
+            handler.buildStarted(sessionId);
+            sessionData.params = null;
+            Channels.write(ctx.getChannel(), CmdlineProtoUtil.toMessage(sessionId, params));
+          }
+          else {
+            cancelSession(sessionId);
+          }
+        }
+        else {
+          handler.handleBuildMessage(ctx.getChannel(), sessionId, builderMessage);
+        }
+        break;
+
+      default:
+        LOG.info("Unsupported message type " + messageType);
+        break;
+    }
+  }
+
+  @Override
+  public void channelClosed(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    try {
+      super.channelClosed(ctx, e);
+    }
+    finally {
+      final SessionData sessionData = (SessionData)ctx.getAttachment();
+      if (sessionData != null) {
+        final BuilderMessageHandler handler = unregisterBuildMessageHandler(sessionData.sessionId);
+        if (handler != null) {
+          // notify the handler only if it has not been notified yet
+          handler.sessionTerminated(sessionData.sessionId);
+        }
+      }
+    }
+  }
+
+  @Override
+  public void exceptionCaught(ChannelHandlerContext ctx, ExceptionEvent e) throws Exception {
+    final Throwable cause = e.getCause();
+    if (cause != null) {
+      LOG.info(cause);
+    }
+    ctx.sendUpstream(e);
+  }
+
+  @Override
+  public void channelDisconnected(ChannelHandlerContext ctx, ChannelStateEvent e) throws Exception {
+    try {
+      super.channelDisconnected(ctx, e);
+    }
+    finally {
+      final SessionData sessionData = (SessionData)ctx.getAttachment();
+      if (sessionData != null) { // this is the context corresponding to some session
+        final Channel channel = e.getChannel();
+        ApplicationManager.getApplication().executeOnPooledThread(new Runnable() {
+          @Override
+          public void run() {
+            channel.close();
+          }
+        });
+      }
+    }
+  }
+
+  private static final class SessionData {
+    final UUID sessionId;
+    final BuilderMessageHandler handler;
+    volatile CmdlineRemoteProto.Message.ControllerMessage params;
+    volatile Channel channel;
+
+    private SessionData(UUID sessionId, BuilderMessageHandler handler, CmdlineRemoteProto.Message.ControllerMessage params) {
+      this.sessionId = sessionId;
+      this.handler = handler;
+      this.params = params;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java
new file mode 100644
index 0000000..fadf63b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuilderMessageHandler.java
@@ -0,0 +1,35 @@
+/*
+ * 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.compiler.server;
+
+import org.jboss.netty.channel.Channel;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+
+import java.util.UUID;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 4/25/12
+ */
+public interface BuilderMessageHandler {
+  void buildStarted(UUID sessionId);
+  
+  void handleBuildMessage(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage msg);
+
+  void handleFailure(UUID sessionId, CmdlineRemoteProto.Message.Failure failure);
+
+  void sessionTerminated(UUID sessionId);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPathProvider.java b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPathProvider.java
new file mode 100644
index 0000000..f4f2bb4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPathProvider.java
@@ -0,0 +1,30 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * Project-level extension points to dynamically vary classpath of external build process.
+ */
+public interface CompileServerPathProvider {
+  ExtensionPointName<CompileServerPathProvider> EP_NAME = ExtensionPointName.create("com.intellij.compileServer.pathProvider");
+
+  @NotNull List<String> getClassPath();
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java
new file mode 100644
index 0000000..2040b6c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/CompileServerPlugin.java
@@ -0,0 +1,57 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.PluginAware;
+import com.intellij.openapi.extensions.PluginDescriptor;
+import com.intellij.util.xmlb.annotations.Attribute;
+
+/**
+ * @author nik
+ */
+public class CompileServerPlugin implements PluginAware {
+  public static final ExtensionPointName<CompileServerPlugin> EP_NAME = ExtensionPointName.create("com.intellij.compileServer.plugin");
+
+  private PluginDescriptor myPluginDescriptor;
+  private String myClasspath;
+
+  /**
+   * <p>Specifies semicolon-separated list of paths which should be added to the classpath of the compile server.
+   * The paths are relative to the plugin 'lib' directory.</p>
+   *
+   * <p>In the development mode the name of each file without extension is treated as a module name and the output directory of the module
+   * is added to the classpath. If such file doesn't exists the jar is searched under 'lib' directory of the plugin sources home directory.</p>
+   */
+  @Attribute("classpath")
+  public String getClasspath() {
+    return myClasspath;
+  }
+
+  @SuppressWarnings("UnusedDeclaration")
+  public void setClasspath(String classpath) {
+    myClasspath = classpath;
+  }
+
+  public PluginDescriptor getPluginDescriptor() {
+    return myPluginDescriptor;
+  }
+
+  @Override
+  public final void setPluginDescriptor(PluginDescriptor pluginDescriptor) {
+    myPluginDescriptor = pluginDescriptor;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/CustomBuilderMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/CustomBuilderMessageHandler.java
new file mode 100644
index 0000000..74bf679
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/CustomBuilderMessageHandler.java
@@ -0,0 +1,29 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.util.messages.Topic;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface CustomBuilderMessageHandler extends EventListener {
+  Topic<CustomBuilderMessageHandler> TOPIC = Topic.create("custom builder message", CustomBuilderMessageHandler.class);
+
+  void messageReceived(String builderId, String messageType, String messageText);
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
new file mode 100644
index 0000000..add20bd
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/DefaultMessageHandler.java
@@ -0,0 +1,361 @@
+/*
+ * 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.compiler.server;
+
+import com.intellij.compiler.make.CachingSearcher;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.registry.Registry;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.cls.ClsUtil;
+import com.intellij.util.concurrency.SequentialTaskExecutor;
+import org.jboss.netty.channel.Channel;
+import org.jboss.netty.channel.Channels;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.api.CmdlineProtoUtil;
+import org.jetbrains.jps.api.CmdlineRemoteProto;
+
+import java.util.*;
+import java.util.concurrent.Executor;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 4/18/12
+ */
+public abstract class DefaultMessageHandler implements BuilderMessageHandler {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.DefaultMessageHandler");
+  private final int MAX_CONSTANT_SEARCHES = Registry.intValue("compiler.max.static.constants.searches");
+  private final Project myProject;
+  private int myConstantSearchesCount = 0;
+  private final CachingSearcher mySearcher;
+  private final SequentialTaskExecutor myTaskExecutor = new SequentialTaskExecutor(new Executor() {
+    @Override
+    public void execute(Runnable command) {
+      ApplicationManager.getApplication().executeOnPooledThread(command);
+    }
+  });
+
+  protected DefaultMessageHandler(Project project) {
+    myProject = project;
+    mySearcher = new CachingSearcher(project);
+  }
+
+  @Override
+  public void buildStarted(UUID sessionId) {
+  }
+
+  @Override
+  public final void handleBuildMessage(final Channel channel, final UUID sessionId, final CmdlineRemoteProto.Message.BuilderMessage msg) {
+    switch (msg.getType()) {
+      case BUILD_EVENT:
+        handleBuildEvent(sessionId, msg.getBuildEvent());
+        break;
+      case COMPILE_MESSAGE:
+        handleCompileMessage(sessionId, msg.getCompileMessage());
+        break;
+      case CONSTANT_SEARCH_TASK:
+        final CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task = msg.getConstantSearchTask();
+        myTaskExecutor.submit(new Runnable() {
+          @Override
+          public void run() {
+            handleConstantSearchTask(channel, sessionId, task);
+          }
+        });
+        break;
+    }
+  }
+
+  protected abstract void handleCompileMessage(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.CompileMessage message);
+
+  protected abstract void handleBuildEvent(UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.BuildEvent event);
+
+  private void handleConstantSearchTask(Channel channel, UUID sessionId, CmdlineRemoteProto.Message.BuilderMessage.ConstantSearchTask task) {
+    final String ownerClassName = task.getOwnerClassName();
+    final String fieldName = task.getFieldName();
+    final int accessFlags = task.getAccessFlags();
+    final boolean accessChanged = task.getIsAccessChanged();
+    final boolean isRemoved = task.getIsFieldRemoved();
+    final Ref<Boolean> isSuccess = Ref.create(Boolean.TRUE);
+    final Set<String> affectedPaths = Collections.synchronizedSet(new HashSet<String>()); // PsiSearchHelper runs multiple threads
+    try {
+      if (isDumbMode()) {
+        // do not wait until dumb mode finishes
+        isSuccess.set(Boolean.FALSE);
+        LOG.debug("Constant search task: cannot search in dumb mode");
+      }
+      else {
+        ApplicationManager.getApplication().runReadAction(new Runnable() {
+          public void run() {
+            try {
+              String qualifiedName = ownerClassName.replace('$', '.');
+              final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(qualifiedName, GlobalSearchScope.allScope(myProject));
+              if (isRemoved) {
+                if (classes.length > 0) {
+                  for (PsiClass aClass : classes) {
+                    final boolean success = performRemovedConstantSearch(aClass, fieldName, accessFlags, affectedPaths);
+                    if (!success) {
+                      isSuccess.set(Boolean.FALSE);
+                      break;
+                    }
+                  }
+                }
+                else {
+                  isSuccess.set(
+                    performRemovedConstantSearch(null, fieldName, accessFlags, affectedPaths)
+                  );
+                }
+              }
+              else {
+                if (classes.length > 0) {
+                  boolean foundAtLeastOne = false;
+                  for (PsiClass aClass : classes) {
+                    PsiField changedField = null;
+                    for (PsiField psiField : aClass.getFields()) {
+                      if (fieldName.equals(psiField.getName())) {
+                        changedField = psiField;
+                        break;
+                      }
+                    }
+                    if (changedField == null) {
+                      continue;
+                    }
+                    foundAtLeastOne = true;
+                    final boolean sucess = performChangedConstantSearch(aClass, changedField, accessFlags, accessChanged, affectedPaths);
+                    if (!sucess) {
+                      isSuccess.set(Boolean.FALSE);
+                      break;
+                    }
+                  }
+                  if (!foundAtLeastOne) {
+                    isSuccess.set(Boolean.FALSE);
+                    LOG.debug("Constant search task: field " + fieldName + " not found in classes " + qualifiedName);
+                  }
+                }
+                else {
+                  isSuccess.set(Boolean.FALSE);
+                  LOG.debug("Constant search task: class " + qualifiedName + " not found");
+                }
+              }
+            }
+            catch (Throwable e) {
+              isSuccess.set(Boolean.FALSE);
+              LOG.debug("Constant search task: failed with message " + e.getMessage());
+            }
+          }
+        });
+      }
+    }
+    finally {
+      final CmdlineRemoteProto.Message.ControllerMessage.ConstantSearchResult.Builder builder = CmdlineRemoteProto.Message.ControllerMessage.ConstantSearchResult.newBuilder();
+      builder.setOwnerClassName(ownerClassName);
+      builder.setFieldName(fieldName);
+      if (isSuccess.get()) {
+        builder.setIsSuccess(true);
+        builder.addAllPath(affectedPaths);
+        LOG.debug("Constant search task: " + affectedPaths.size() + " affected files found");
+      }
+      else {
+        builder.setIsSuccess(false);
+        LOG.debug("Constant search task: unsuccessful");
+      }
+      Channels.write(channel, CmdlineProtoUtil.toMessage(sessionId, CmdlineRemoteProto.Message.ControllerMessage.newBuilder().setType(
+        CmdlineRemoteProto.Message.ControllerMessage.Type.CONSTANT_SEARCH_RESULT).setConstantSearchResult(builder.build()).build()
+      ));
+    }
+  }
+
+  private boolean isDumbMode() {
+    final DumbService dumbService = DumbService.getInstance(myProject);
+    boolean isDumb = dumbService.isDumb();
+    if (isDumb) {
+      // wait some time
+      for (int idx = 0; idx < 5; idx++) {
+        try {
+          Thread.sleep(10L);
+        }
+        catch (InterruptedException ignored) {
+        }
+        isDumb = dumbService.isDumb();
+        if (!isDumb) {
+          break;
+        }
+      }
+    }
+    return isDumb;
+  }
+
+  private boolean performChangedConstantSearch(PsiClass aClass, PsiField field, int accessFlags, boolean isAccessibilityChange, Set<String> affectedPaths) {
+    if (!isAccessibilityChange && ClsUtil.isPrivate(accessFlags)) {
+      return true; // optimization: don't need to search, cause may be used only in this class
+    }
+    final Set<PsiElement> usages = new HashSet<PsiElement>();
+    try {
+      addUsages(field, usages, isAccessibilityChange);
+      for (final PsiElement usage : usages) {
+        affect(usage, affectedPaths);
+        //final PsiClass ownerClass = getOwnerClass(usage);
+        //if (ownerClass != null && !ownerClass.equals(aClass)) {
+        //  affect(ownerClass, affectedPaths);
+        //}
+        //else if (ownerClass == null) {
+        //  affect(usage, affectedPaths);
+        //}
+      }
+    }
+    catch (PsiInvalidElementAccessException e) {
+      LOG.debug("Constant search task: PIEAE thrown while searching of usages of changed constant");
+      return false;
+    }
+    catch (ProcessCanceledException e) {
+      LOG.debug("Constant search task: PCE thrown while searching of usages of changed constant");
+      return false;
+    }
+    return true;
+  }
+
+
+  private boolean performRemovedConstantSearch(@Nullable final PsiClass aClass, String fieldName, int accessFlags, final Set<String> affectedPaths) {
+    SearchScope searchScope = GlobalSearchScope.projectScope(myProject);
+    if (aClass != null && ClsUtil.isPackageLocal(accessFlags)) {
+      final PsiFile containingFile = aClass.getContainingFile();
+      if (containingFile instanceof PsiJavaFile) {
+        final String packageName = ((PsiJavaFile)containingFile).getPackageName();
+        final PsiPackage aPackage = JavaPsiFacade.getInstance(myProject).findPackage(packageName);
+        if (aPackage != null) {
+          searchScope = PackageScope.packageScope(aPackage, false);
+          searchScope = searchScope.intersectWith(aClass.getUseScope());
+        }
+      }
+    }
+    final PsiSearchHelper psiSearchHelper = PsiSearchHelper.SERVICE.getInstance(myProject);
+
+    final Ref<Boolean> result = new Ref<Boolean>(Boolean.TRUE);
+    processIdentifiers(psiSearchHelper, new PsiElementProcessor<PsiIdentifier>() {
+      @Override
+      public boolean execute(@NotNull PsiIdentifier identifier) {
+        try {
+          final PsiElement parent = identifier.getParent();
+          if (parent instanceof PsiReferenceExpression) {
+            final PsiClass ownerClass = getOwnerClass(parent);
+            if (ownerClass != null /*&& !ownerClass.equals(aClass)*/) {
+              if (ownerClass.getQualifiedName() != null) {
+                affect(ownerClass, affectedPaths);
+              }
+            }
+          }
+          return true;
+        }
+        catch (PsiInvalidElementAccessException e) {
+          result.set(Boolean.FALSE);
+          LOG.debug("Constant search task: PIEAE thrown while searching of usages of removed constant");
+          return false;
+        }
+      }
+    }, fieldName, searchScope, UsageSearchContext.IN_CODE);
+
+    return result.get();
+  }
+
+  private static void affect(PsiElement ownerClass, Set<String> affectedPaths) {
+    final PsiFile containingPsi = ownerClass.getContainingFile();
+    if (containingPsi != null) {
+      final VirtualFile vFile = containingPsi.getOriginalFile().getVirtualFile();
+      if (vFile != null) {
+        affectedPaths.add(vFile.getPath());
+      }
+    }
+  }
+
+  private static boolean processIdentifiers(PsiSearchHelper helper, @NotNull final PsiElementProcessor<PsiIdentifier> processor, @NotNull final String identifier, @NotNull SearchScope searchScope, short searchContext) {
+    TextOccurenceProcessor processor1 = new TextOccurenceProcessor() {
+      public boolean execute(PsiElement element, int offsetInElement) {
+        return !(element instanceof PsiIdentifier) || processor.execute((PsiIdentifier)element);
+      }
+    };
+    return helper.processElementsWithWord(processor1, searchScope, identifier, searchContext, true);
+  }
+
+  private void addUsages(PsiField psiField, Collection<PsiElement> usages, final boolean ignoreAccessScope) throws ProcessCanceledException {
+    final int count = myConstantSearchesCount;
+    if (count > MAX_CONSTANT_SEARCHES) {
+      throw new ProcessCanceledException();
+    }
+    Collection<PsiReference> references = mySearcher.findReferences(psiField, ignoreAccessScope)/*doFindReferences(searchHelper, psiField)*/;
+
+    myConstantSearchesCount++;
+
+    for (final PsiReference ref : references) {
+      if (!(ref instanceof PsiReferenceExpression)) {
+        continue;
+      }
+      PsiElement e = ref.getElement();
+      usages.add(e);
+      PsiField ownerField = getOwnerField(e);
+      if (ownerField != null) {
+        if (ownerField.hasModifierProperty(PsiModifier.FINAL)) {
+          PsiExpression initializer = ownerField.getInitializer();
+          if (initializer != null && PsiUtil.isConstantExpression(initializer)) {
+            // if the field depends on the compile-time-constant expression and is itself final
+            addUsages(ownerField, usages, ignoreAccessScope);
+          }
+        }
+      }
+    }
+  }
+
+  @Nullable
+  private static PsiClass getOwnerClass(PsiElement element) {
+    while (!(element instanceof PsiFile)) {
+      if (element instanceof PsiClass && element.getParent() instanceof PsiJavaFile) { // top-level class
+        final PsiClass psiClass = (PsiClass)element;
+        if (JspPsiUtil.isInJspFile(psiClass)) {
+          return null;
+        }
+        final PsiFile containingFile = psiClass.getContainingFile();
+        if (containingFile == null) {
+          return null;
+        }
+        return StdLanguages.JAVA.equals(containingFile.getLanguage())? psiClass : null;
+      }
+      element = element.getParent();
+    }
+    return null;
+  }
+
+  @Nullable
+  private static PsiField getOwnerField(PsiElement element) {
+    while (!(element instanceof PsiFile)) {
+      if (element instanceof PsiClass) {
+        break;
+      }
+      if (element instanceof PsiField) { // top-level class
+        return (PsiField)element;
+      }
+      element = element.getParent();
+    }
+    return null;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java b/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java
new file mode 100644
index 0000000..f95d151
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/compiler/server/impl/CompileServerClasspathManager.java
@@ -0,0 +1,135 @@
+/*
+ * 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.compiler.server.impl;
+
+import com.intellij.compiler.server.CompileServerPathProvider;
+import com.intellij.compiler.server.CompileServerPlugin;
+import com.intellij.ide.plugins.IdeaPluginDescriptor;
+import com.intellij.ide.plugins.PluginManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.PluginId;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PathUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class CompileServerClasspathManager {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.server.impl.CompileServerClasspathManager");
+
+  private List<String> myCompileServerPluginsClasspath;
+
+  public List<String> getCompileServerPluginsClasspath(Project project) {
+    List<String> staticClasspath = getStaticClasspath();
+    List<String> dynamicClasspath = getDynamicClasspath(project);
+
+    if (dynamicClasspath.isEmpty()) {
+      return staticClasspath;
+    }
+    else {
+      dynamicClasspath.addAll(staticClasspath);
+      return dynamicClasspath;
+    }
+  }
+
+  private List<String> getStaticClasspath() {
+    if (myCompileServerPluginsClasspath == null) {
+      myCompileServerPluginsClasspath = computeCompileServerPluginsClasspath();
+    }
+    return myCompileServerPluginsClasspath;
+  }
+
+  private static List<String> computeCompileServerPluginsClasspath() {
+    final List<String> classpath = ContainerUtil.newArrayList();
+    for (CompileServerPlugin serverPlugin : CompileServerPlugin.EP_NAME.getExtensions()) {
+      final PluginId pluginId = serverPlugin.getPluginDescriptor().getPluginId();
+      final IdeaPluginDescriptor plugin = PluginManager.getPlugin(pluginId);
+      LOG.assertTrue(plugin != null, pluginId);
+      final File baseFile = plugin.getPath();
+      if (baseFile.isFile()) {
+        classpath.add(baseFile.getPath());
+      }
+      else if (baseFile.isDirectory()) {
+        for (String relativePath : StringUtil.split(serverPlugin.getClasspath(), ";")) {
+          final File jarFile = new File(new File(baseFile, "lib"), relativePath);
+          File classesDir = new File(baseFile, "classes");
+          if (jarFile.exists()) {
+            classpath.add(jarFile.getPath());
+          }
+          else if (classesDir.isDirectory()) {
+            //'plugin run configuration': all module output are copied to 'classes' folder
+            classpath.add(classesDir.getPath());
+          }
+          else {
+            //development mode: add directory out/classes/production/<jar-name> to classpath, assuming that jar-name is equal to module name
+            final String moduleName = FileUtil.getNameWithoutExtension(PathUtil.getFileName(relativePath));
+            final File dir = new File(baseFile.getParentFile(), moduleName);
+            if (dir.exists()) {
+              classpath.add(dir.getPath());
+            }
+            else {
+              //looks like <jar-name> refers to a library, try to find it under <plugin-dir>/lib
+              File pluginDir = getPluginDir(plugin);
+              if (pluginDir != null) {
+                File libraryFile = new File(pluginDir, "lib" + File.separator + PathUtil.getFileName(relativePath));
+                if (libraryFile.exists()) {
+                  classpath.add(libraryFile.getPath());
+                }
+                else {
+                  LOG.error("Cannot add plugin '" + plugin.getName() + "' to external compiler classpath: " +
+                            "library " + libraryFile.getAbsolutePath() + " not found");
+                }
+              }
+              else {
+                LOG.error("Cannot add plugin '" + plugin.getName() + "' to external compiler classpath: home directory of plugin not found");
+              }
+            }
+          }
+        }
+      }
+    }
+    return classpath;
+  }
+
+  @Nullable
+  private static File getPluginDir(IdeaPluginDescriptor plugin) {
+    String pluginDirName = StringUtil.getShortName(plugin.getPluginId().getIdString());
+    String[] roots = {PathManager.getHomePath(), PathManager.getHomePath() + File.separator + "community"};
+    for (String root : roots) {
+      File pluginDir = new File(root, "plugins" + File.separator + pluginDirName);
+      if (pluginDir.isDirectory()) {
+        return pluginDir;
+      }
+    }
+    return null;
+  }
+
+  private static List<String> getDynamicClasspath(Project project) {
+    List<String> classpath = ContainerUtil.newArrayList();
+    for (CompileServerPathProvider provider : project.getExtensions(CompileServerPathProvider.EP_NAME)) {
+      classpath.addAll(provider.getClassPath());
+    }
+    return classpath;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java b/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java
new file mode 100644
index 0000000..8f8f4e3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/ex/CompileContextEx.java
@@ -0,0 +1,59 @@
+/*
+ * 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.openapi.compiler.ex;
+
+import com.intellij.compiler.make.DependencyCache;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessage;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Set;
+
+public interface CompileContextEx extends CompileContext {
+  DependencyCache getDependencyCache();
+
+  @Nullable
+  VirtualFile getSourceFileByOutputFile(VirtualFile outputFile);
+
+  void addMessage(CompilerMessage message);
+
+  @NotNull
+  Set<VirtualFile> getTestOutputDirectories();
+  
+  /**
+   * the same as FileIndex.isInTestSourceContent(), but takes into account generated output dirs
+   */
+  boolean isInTestSourceContent(@NotNull VirtualFile fileOrDir);
+
+  boolean isInSourceContent(@NotNull VirtualFile fileOrDir);
+
+  void addScope(CompileScope additionalScope);
+
+  long getStartCompilationStamp();
+
+  void recalculateOutputDirs();
+
+  void markGenerated(Collection<VirtualFile> files);
+
+  boolean isGenerated(VirtualFile file);
+
+  void assignModule(@NotNull VirtualFile root, @NotNull Module module, boolean isTestSource, @Nullable com.intellij.openapi.compiler.Compiler compiler);
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/BuildTarget.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/BuildTarget.java
new file mode 100644
index 0000000..27f16ad
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/BuildTarget.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class BuildTarget {
+  public static final BuildTarget DEFAULT = new BuildTarget() {
+    @NotNull
+    @Override
+    public String getId() {
+      return "<default>";
+    }
+  };
+
+  @NotNull
+  public abstract String getId();
+
+  @Override
+  public String toString() {
+    return "Build Target: " + getId();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java
new file mode 100644
index 0000000..3bd9972
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/CompileItem.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class CompileItem<Key, SourceState, OutputState> {
+  @NotNull
+  public abstract Key getKey();
+
+  public abstract boolean isSourceUpToDate(@NotNull SourceState state);
+
+  @NotNull
+  public abstract SourceState computeSourceState();
+
+
+  public abstract boolean isOutputUpToDate(@NotNull OutputState state);
+
+  @NotNull
+  public abstract OutputState computeOutputState();
+
+  public boolean isExcluded() {
+    return false;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java
new file mode 100644
index 0000000..b3d66ce
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/DummyPersistentState.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.util.io.DataExternalizer;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * @author nik
+ */
+public class DummyPersistentState {
+  public static final DummyPersistentState INSTANCE = new DummyPersistentState();
+  public static final DataExternalizer<DummyPersistentState> EXTERNALIZER = new DummyPersistentStateExternalizer();
+
+  private DummyPersistentState() {
+  }
+
+  private static class DummyPersistentStateExternalizer implements DataExternalizer<DummyPersistentState> {
+    @Override
+    public void save(DataOutput out, DummyPersistentState value) throws IOException {
+    }
+
+    @Override
+    public DummyPersistentState read(DataInput in) throws IOException {
+      return INSTANCE;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java
new file mode 100644
index 0000000..b09c8e5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompiler.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.EnumeratorStringDescriptor;
+import com.intellij.util.io.KeyDescriptor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class GenericCompiler<Key, SourceState, OutputState> implements Compiler {
+  protected static final KeyDescriptor<String> STRING_KEY_DESCRIPTOR = new EnumeratorStringDescriptor();
+  private final String myId;
+  private final int myVersion;
+  private final CompileOrderPlace myOrderPlace;
+
+  protected GenericCompiler(@NotNull String id, int version, @NotNull CompileOrderPlace orderPlace) {
+    myId = id;
+    myVersion = version;
+    myOrderPlace = orderPlace;
+  }
+
+  @NotNull
+  public abstract KeyDescriptor<Key> getItemKeyDescriptor();
+  @NotNull
+  public abstract DataExternalizer<SourceState> getSourceStateExternalizer();
+  @NotNull
+  public abstract DataExternalizer<OutputState> getOutputStateExternalizer();
+
+  @NotNull
+  public abstract GenericCompilerInstance<?, ? extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState> createInstance(@NotNull CompileContext context);
+
+  public final String getId() {
+    return myId;
+  }
+
+  public final int getVersion() {
+    return myVersion;
+  }
+
+  @Override
+  public boolean validateConfiguration(CompileScope scope) {
+    return true;
+  }
+
+  public CompileOrderPlace getOrderPlace() {
+    return myOrderPlace;
+  }
+
+  public static enum CompileOrderPlace {
+    CLASS_INSTRUMENTING, CLASS_POST_PROCESSING, PACKAGING, VALIDATING
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerCacheState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerCacheState.java
new file mode 100644
index 0000000..bfc4468
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerCacheState.java
@@ -0,0 +1,48 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class GenericCompilerCacheState<Key, SourceState, OutputState> {
+  private final Key myKey;
+  private final SourceState mySourceState;
+  private final OutputState myOutputState;
+
+  public GenericCompilerCacheState(@NotNull Key key, @NotNull SourceState sourceState, @NotNull OutputState outputState) {
+    myKey = key;
+    mySourceState = sourceState;
+    myOutputState = outputState;
+  }
+
+  @NotNull
+  public Key getKey() {
+    return myKey;
+  }
+
+  @NotNull
+  public SourceState getSourceState() {
+    return mySourceState;
+  }
+
+  @NotNull
+  public OutputState getOutputState() {
+    return myOutputState;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerInstance.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerInstance.java
new file mode 100644
index 0000000..6bb9274
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerInstance.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class GenericCompilerInstance<T extends BuildTarget, Item extends CompileItem<Key, SourceState, OutputState>, Key, SourceState, OutputState> {
+  protected final CompileContext myContext;
+
+  protected GenericCompilerInstance(CompileContext context) {
+    myContext = context;
+  }
+
+  protected Project getProject() {
+    return myContext.getProject();
+  }
+
+  @NotNull
+  public abstract List<T> getAllTargets();
+
+  @NotNull
+  public abstract List<T> getSelectedTargets();
+
+  public abstract void processObsoleteTarget(@NotNull String targetId, @NotNull List<GenericCompilerCacheState<Key, SourceState, OutputState>> obsoleteItems);
+
+
+  @NotNull
+  public abstract List<Item> getItems(@NotNull T target);
+
+  public abstract void processItems(@NotNull T target, @NotNull List<GenericCompilerProcessingItem<Item, SourceState, OutputState>> changedItems, @NotNull List<GenericCompilerCacheState<Key, SourceState, OutputState>> obsoleteItems,
+                                    @NotNull OutputConsumer<Item> consumer);
+
+  public interface OutputConsumer<Item extends CompileItem<?,?,?>> {
+    void addFileToRefresh(@NotNull File file);
+
+    void addDirectoryToRefresh(@NotNull File dir);
+
+    void addProcessedItem(@NotNull Item sourceItem);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerProcessingItem.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerProcessingItem.java
new file mode 100644
index 0000000..e62a5b3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/GenericCompilerProcessingItem.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class GenericCompilerProcessingItem<Item extends CompileItem<?, SourceState, OutputState>, SourceState, OutputState> {
+  private final Item myItem;
+  private final SourceState myCachedSourceState;
+  private final OutputState myCachedOutputState;
+
+  public GenericCompilerProcessingItem(@NotNull Item item, @Nullable SourceState cachedSourceState, @Nullable OutputState cachedOutputState) {
+    myItem = item;
+    myCachedSourceState = cachedSourceState;
+    myCachedOutputState = cachedOutputState;
+  }
+
+  @NotNull
+  public Item getItem() {
+    return myItem;
+  }
+
+  @Nullable
+  public SourceState getCachedSourceState() {
+    return myCachedSourceState;
+  }
+
+  @Nullable 
+  public OutputState getCachedOutputState() {
+    return myCachedOutputState;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileCompileItem.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileCompileItem.java
new file mode 100644
index 0000000..b1e5394
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileCompileItem.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class VirtualFileCompileItem<OutputState> extends CompileItem<String, VirtualFilePersistentState, OutputState> {
+  protected final VirtualFile myFile;
+
+  public VirtualFileCompileItem(@NotNull VirtualFile file) {
+    myFile = file;
+  }
+
+  @NotNull
+  public VirtualFile getFile() {
+    return myFile;
+  }
+
+  @NotNull
+  @Override
+  public VirtualFilePersistentState computeSourceState() {
+    return new VirtualFilePersistentState(myFile.getTimeStamp());
+  }
+
+  @Override
+  public boolean isSourceUpToDate(@NotNull VirtualFilePersistentState state) {
+    return myFile.getTimeStamp() == state.getSourceTimestamp();
+  }
+
+  @NotNull
+  @Override
+  public String getKey() {
+    return myFile.getUrl();
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java
new file mode 100644
index 0000000..e9ea970
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFilePersistentState.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.util.io.DataExternalizer;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+* @author nik
+*/
+public class VirtualFilePersistentState {
+  public static DataExternalizer<VirtualFilePersistentState> EXTERNALIZER = new VirtualFileStateExternalizer();
+  private final long mySourceTimestamp;
+
+  public VirtualFilePersistentState(long sourceTimestamp) {
+    mySourceTimestamp = sourceTimestamp;
+  }
+
+  public final long getSourceTimestamp() {
+    return mySourceTimestamp;
+  }
+
+  private static class VirtualFileStateExternalizer implements DataExternalizer<VirtualFilePersistentState> {
+    @Override
+    public void save(DataOutput out, VirtualFilePersistentState value) throws IOException {
+      out.writeLong(value.getSourceTimestamp());
+    }
+
+    @Override
+    public VirtualFilePersistentState read(DataInput in) throws IOException {
+      return new VirtualFilePersistentState(in.readLong());
+    }
+
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java
new file mode 100644
index 0000000..a22e80d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileSetState.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.IOUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class VirtualFileSetState {
+  public static final DataExternalizer<VirtualFileSetState> EXTERNALIZER = new VirtualFileWithDependenciesExternalizer();
+  private Map<String, Long> myTimestamps = new HashMap<String, Long>();
+
+  public VirtualFileSetState() {
+  }
+
+  public VirtualFileSetState(Collection<? extends VirtualFile> files) {
+    for (VirtualFile file : files) {
+      addFile(file);
+    }
+  }
+
+  public void addFile(@NotNull VirtualFile file) {
+    myTimestamps.put(file.getUrl(), file.getTimeStamp());
+  }
+
+  public boolean isUpToDate(Set<? extends VirtualFile> files) {
+    if (files.size() != myTimestamps.size()) {
+      return false;
+    }
+
+    for (VirtualFile file : files) {
+      final Long timestamp = myTimestamps.get(file.getUrl());
+      if (timestamp == null || timestamp != file.getTimeStamp()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private static class VirtualFileWithDependenciesExternalizer implements DataExternalizer<VirtualFileSetState> {
+    private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
+
+    @Override
+    public void save(DataOutput out, VirtualFileSetState value) throws IOException {
+      final Map<String, Long> dependencies = value.myTimestamps;
+      out.writeInt(dependencies.size());
+      for (Map.Entry<String, Long> entry : dependencies.entrySet()) {
+        IOUtil.writeUTFFast(myBuffer, out, entry.getKey());
+        out.writeLong(entry.getValue());
+      }
+    }
+
+    @Override
+    public VirtualFileSetState read(DataInput in) throws IOException {
+      final VirtualFileSetState state = new VirtualFileSetState();
+      int size = in.readInt();
+      while (size-- > 0) {
+        final String url = IOUtil.readUTFFast(myBuffer, in);
+        final long timestamp = in.readLong();
+        state.myTimestamps.put(url, timestamp);
+      }
+      return state;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java
new file mode 100644
index 0000000..9f4a815
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/generic/VirtualFileWithDependenciesState.java
@@ -0,0 +1,88 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler.generic;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.IOUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public class VirtualFileWithDependenciesState {
+  public static final DataExternalizer<VirtualFileWithDependenciesState> EXTERNALIZER = new VirtualFileWithDependenciesExternalizer();
+  private long mySourceTimestamp;
+  private Map<String, Long> myDependencies = new HashMap<String, Long>();
+
+  public VirtualFileWithDependenciesState(long sourceTimestamp) {
+    mySourceTimestamp = sourceTimestamp;
+  }
+
+  public void addDependency(@NotNull VirtualFile file) {
+    myDependencies.put(file.getUrl(), file.getTimeStamp());
+  }
+
+  public boolean isUpToDate(@NotNull VirtualFile sourceFile) {
+    if (sourceFile.getTimeStamp() != mySourceTimestamp) {
+      return false;
+    }
+
+    VirtualFileManager manager = VirtualFileManager.getInstance();
+    for (Map.Entry<String, Long> entry : myDependencies.entrySet()) {
+      final VirtualFile file = manager.findFileByUrl(entry.getKey());
+      if (file == null || file.getTimeStamp() != entry.getValue()) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+
+  private static class VirtualFileWithDependenciesExternalizer implements DataExternalizer<VirtualFileWithDependenciesState> {
+    private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
+
+    @Override
+    public void save(DataOutput out, VirtualFileWithDependenciesState value) throws IOException {
+      out.writeLong(value.mySourceTimestamp);
+      final Map<String, Long> dependencies = value.myDependencies;
+      out.writeInt(dependencies.size());
+      for (Map.Entry<String, Long> entry : dependencies.entrySet()) {
+        IOUtil.writeUTFFast(myBuffer, out, entry.getKey());
+        out.writeLong(entry.getValue());
+      }
+    }
+
+    @Override
+    public VirtualFileWithDependenciesState read(DataInput in) throws IOException {
+      final VirtualFileWithDependenciesState state = new VirtualFileWithDependenciesState(in.readLong());
+      int size = in.readInt();
+      while (size-- > 0) {
+        final String url = IOUtil.readUTFFast(myBuffer, in);
+        final long timestamp = in.readLong();
+        state.myDependencies.put(url, timestamp);
+      }
+      return state;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorUtil.java b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorUtil.java
new file mode 100644
index 0000000..b41b5b0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorUtil.java
@@ -0,0 +1,69 @@
+/*
+ * 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.openapi.compiler.util;
+
+import com.intellij.compiler.impl.FileSetCompileScope;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.ex.CompileContextEx;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.descriptors.ConfigFile;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author peter
+ */
+public class InspectionValidatorUtil {
+  private InspectionValidatorUtil() {
+  }
+
+  public static void addDescriptor(@NotNull final Collection<VirtualFile> result, @Nullable final ConfigFile configFile) {
+    if (configFile != null) {
+      ContainerUtil.addIfNotNull(configFile.getVirtualFile(), result);
+    }
+  }
+
+  public static void addFile(@NotNull final Collection<VirtualFile> result, @Nullable final PsiFile psiFile) {
+    if (psiFile != null) {
+      ContainerUtil.addIfNotNull(psiFile.getVirtualFile(), result);
+    }
+  }
+
+
+  public static Collection<VirtualFile> expandCompileScopeIfNeeded(final Collection<VirtualFile> result, final CompileContext context) {
+    final ProjectFileIndex index = ProjectRootManager.getInstance(context.getProject()).getFileIndex();
+    final THashSet<VirtualFile> set = new THashSet<VirtualFile>();
+    final THashSet<Module> modules = new THashSet<Module>();
+    for (VirtualFile file : result) {
+      if (index.getSourceRootForFile(file) == null) {
+        set.add(file);
+        ContainerUtil.addIfNotNull(index.getModuleForFile(file), modules);
+      }
+    }
+    if (!set.isEmpty()) {
+      ((CompileContextEx)context).addScope(new FileSetCompileScope(set, modules.toArray(new Module[modules.size()])));
+    }
+    return result;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
new file mode 100644
index 0000000..1b84ca3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/util/InspectionValidatorWrapper.java
@@ -0,0 +1,340 @@
+/*
+ * Copyright (c) 2000-2007 JetBrains s.r.o. All Rights Reserved.
+ */
+package com.intellij.openapi.compiler.util;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInsight.daemon.impl.AnnotationHolderImpl;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInspection.*;
+import com.intellij.compiler.options.ValidationConfiguration;
+import com.intellij.lang.ExternalLanguageAnnotators;
+import com.intellij.lang.StdLanguages;
+import com.intellij.lang.annotation.Annotation;
+import com.intellij.lang.annotation.AnnotationSession;
+import com.intellij.lang.annotation.ExternalAnnotator;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.ReadActionProcessor;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.hash.LinkedHashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInput;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author peter
+ */
+public class InspectionValidatorWrapper implements Validator {
+  private final InspectionValidator myValidator;
+  private final PsiManager myPsiManager;
+  private final CompilerManager myCompilerManager;
+  private final InspectionManager myInspectionManager;
+  private final InspectionProjectProfileManager myProfileManager;
+  private final PsiDocumentManager myPsiDocumentManager;
+  private static final ThreadLocal<Boolean> ourCompilationThreads = new ThreadLocal<Boolean>() {
+    protected Boolean initialValue() {
+      return Boolean.FALSE;
+    }
+  };
+
+  public InspectionValidatorWrapper(final CompilerManager compilerManager, final InspectionManager inspectionManager,
+                                    final InspectionProjectProfileManager profileManager, final PsiDocumentManager psiDocumentManager,
+                                    final PsiManager psiManager, final InspectionValidator validator) {
+    myCompilerManager = compilerManager;
+    myInspectionManager = inspectionManager;
+    myProfileManager = profileManager;
+    myPsiDocumentManager = psiDocumentManager;
+    myPsiManager = psiManager;
+    myValidator = validator;
+  }
+
+  public static boolean isCompilationThread() {
+    return ourCompilationThreads.get().booleanValue();
+  }
+
+  private class MyValidatorProcessingItem implements ProcessingItem {
+    private final VirtualFile myVirtualFile;
+    private final PsiFile myPsiFile;
+    private PsiElementsValidityState myValidityState;
+
+    public MyValidatorProcessingItem(@NotNull final PsiFile psiFile) {
+      myPsiFile = psiFile;
+      myVirtualFile = psiFile.getVirtualFile();
+    }
+
+    @NotNull
+    public VirtualFile getFile() {
+      return myVirtualFile;
+    }
+
+    @Nullable
+    public ValidityState getValidityState() {
+      if (myValidityState == null) {
+        myValidityState = computeValidityState();
+      }
+      return myValidityState;
+    }
+
+    private PsiElementsValidityState computeValidityState() {
+      final PsiElementsValidityState state = new PsiElementsValidityState();
+      for (PsiElement psiElement : myValidator.getDependencies(myPsiFile)) {
+        state.addDependency(psiElement);
+      }
+      return state;
+    }
+
+    public PsiFile getPsiFile() {
+      return myPsiFile;
+    }
+  }
+
+  @NotNull
+  public ProcessingItem[] getProcessingItems(final CompileContext context) {
+    final Project project = context.getProject();
+    if (project.isDefault() || !ValidationConfiguration.shouldValidate(this, context)) {
+      return ProcessingItem.EMPTY_ARRAY;
+    }
+    final ExcludedEntriesConfiguration excludedEntriesConfiguration = ValidationConfiguration.getExcludedEntriesConfiguration(project);
+    final List<ProcessingItem> items = new ReadAction<List<ProcessingItem>>() {
+      protected void run(final Result<List<ProcessingItem>> result) {
+        final CompileScope compileScope = context.getCompileScope();
+        if (!myValidator.isAvailableOnScope(compileScope)) return;
+
+        final ArrayList<ProcessingItem> items = new ArrayList<ProcessingItem>();
+
+        final Processor<VirtualFile> processor = new ReadActionProcessor<VirtualFile>() {
+          @Override
+          public boolean processInReadAction(VirtualFile file) {
+            if (!file.isValid()) {
+              return true;
+            }
+
+            if (myCompilerManager.isExcludedFromCompilation(file) ||
+                excludedEntriesConfiguration.isExcluded(file)) {
+              return true;
+            }
+
+            final Module module = context.getModuleByFile(file);
+            if (module != null) {
+              final PsiFile psiFile = myPsiManager.findFile(file);
+              if (psiFile != null) {
+                items.add(new MyValidatorProcessingItem(psiFile));
+              }
+            }
+            return true;
+          }
+        };
+        ContainerUtil.process(myValidator.getFilesToProcess(myPsiManager.getProject(), context), processor);
+
+        result.setResult(items);
+      }
+    }.execute().getResultObject();
+    if (items == null) return ProcessingItem.EMPTY_ARRAY;
+
+    return items.toArray(new ProcessingItem[items.size()]);
+  }
+
+  public ProcessingItem[] process(final CompileContext context, final ProcessingItem[] items) {
+    context.getProgressIndicator().setText(myValidator.getProgressIndicatorText());
+
+    final List<ProcessingItem> processedItems = new ArrayList<ProcessingItem>();
+    final List<LocalInspectionTool> inspections = new ArrayList<LocalInspectionTool>();
+    for (final Class aClass : myValidator.getInspectionToolClasses(context)) {
+      try {
+        inspections.add((LocalInspectionTool)aClass.newInstance());
+      }
+      catch (RuntimeException e) {
+        throw e;
+      }
+      catch (Exception e) {
+        throw new Error(e);
+      }
+    }
+    for (int i = 0; i < items.length; i++) {
+      final MyValidatorProcessingItem item = (MyValidatorProcessingItem)items[i];
+      context.getProgressIndicator().checkCanceled();
+      context.getProgressIndicator().setFraction((double)i / items.length);
+
+      try {
+        ourCompilationThreads.set(Boolean.TRUE);
+
+        if (checkFile(inspections, item.getPsiFile(), context)) {
+          processedItems.add(item);
+        }
+      }
+      finally {
+        ourCompilationThreads.set(Boolean.FALSE);
+      }
+    }
+
+    return processedItems.toArray(new ProcessingItem[processedItems.size()]);
+  }
+
+  private boolean checkFile(List<LocalInspectionTool> inspections, final PsiFile file, final CompileContext context) {
+    if (!checkUnderReadAction(file, context, new Computable<Map<ProblemDescriptor, HighlightDisplayLevel>>() {
+      @Override
+      public Map<ProblemDescriptor, HighlightDisplayLevel> compute() {
+        return myValidator.checkAdditionally(file);
+      }
+    })) {
+      return false;
+    }
+
+    if (!checkUnderReadAction(file, context, new Computable<Map<ProblemDescriptor, HighlightDisplayLevel>>() {
+      @Override
+      public Map<ProblemDescriptor, HighlightDisplayLevel> compute() {
+        if (file instanceof XmlFile) {
+          return runXmlFileSchemaValidation((XmlFile)file);
+        }
+        return Collections.emptyMap();
+      }
+    })) return false;
+
+
+    final InspectionProfile inspectionProfile = myProfileManager.getInspectionProfile();
+    for (final LocalInspectionTool inspectionTool : inspections) {
+      if (!checkUnderReadAction(file, context, new Computable<Map<ProblemDescriptor, HighlightDisplayLevel>>() {
+        @Override
+        public Map<ProblemDescriptor, HighlightDisplayLevel> compute() {
+          if (getHighlightDisplayLevel(inspectionTool, inspectionProfile, file) != HighlightDisplayLevel.DO_NOT_SHOW) {
+            return runInspectionTool(file, inspectionTool, getHighlightDisplayLevel(inspectionTool, inspectionProfile, file)
+            );
+          }
+          return Collections.emptyMap();
+        }
+      })) return false;
+    }
+    return true;
+  }
+
+  private boolean checkUnderReadAction(PsiFile file, CompileContext context, Computable<Map<ProblemDescriptor, HighlightDisplayLevel>> runnable) {
+    AccessToken token = ReadAction.start();
+    try {
+      if (!file.isValid()) return false;
+
+      final Document document = myPsiDocumentManager.getCachedDocument(file);
+      if (document != null && myPsiDocumentManager.isUncommited(document)) {
+        final String url = file.getViewProvider().getVirtualFile().getUrl();
+        context.addMessage(CompilerMessageCategory.WARNING, CompilerBundle.message("warning.text.file.has.been.changed"), url, -1, -1);
+        return false;
+      }
+
+      if (reportProblems(context, runnable.compute())) return false;
+    }
+    finally {
+      token.finish();
+    }
+    return true;
+  }
+
+  private boolean reportProblems(CompileContext context, Map<ProblemDescriptor, HighlightDisplayLevel> problemsMap) {
+    if (problemsMap.isEmpty()) {
+      return false;
+    }
+
+    for (Map.Entry<ProblemDescriptor, HighlightDisplayLevel> entry : problemsMap.entrySet()) {
+      ProblemDescriptor problemDescriptor = entry.getKey();
+      final PsiElement element = problemDescriptor.getPsiElement();
+      final PsiFile psiFile = element.getContainingFile();
+      if (psiFile == null) continue;
+
+      final VirtualFile virtualFile = psiFile.getVirtualFile();
+      if (virtualFile == null) continue;
+
+      final CompilerMessageCategory category = myValidator.getCategoryByHighlightDisplayLevel(entry.getValue(), virtualFile, context);
+      final Document document = myPsiDocumentManager.getDocument(psiFile);
+
+      final int offset = problemDescriptor.getStartElement().getTextOffset();
+      assert document != null;
+      final int line = document.getLineNumber(offset);
+      final int column = offset - document.getLineStartOffset(line);
+      context.addMessage(category, problemDescriptor.getDescriptionTemplate(), virtualFile.getUrl(), line + 1, column + 1);
+    }
+    return true;
+  }
+
+  private static Map<ProblemDescriptor, HighlightDisplayLevel> runInspectionTool(final PsiFile file,
+                                                                                 final LocalInspectionTool inspectionTool,
+                                                                                 final HighlightDisplayLevel level) {
+    Map<ProblemDescriptor, HighlightDisplayLevel> problemsMap = new LinkedHashMap<ProblemDescriptor, HighlightDisplayLevel>();
+    for (CommonProblemDescriptor descriptor : InspectionRunningUtil.runInspectionOnFile(file, inspectionTool)) {
+      if (descriptor instanceof ProblemDescriptor) {
+        problemsMap.put((ProblemDescriptor)descriptor, level);
+      }
+    }
+    return problemsMap;
+  }
+
+  private static HighlightDisplayLevel getHighlightDisplayLevel(final LocalInspectionTool inspectionTool,
+                                                                final InspectionProfile inspectionProfile, PsiElement file) {
+    final HighlightDisplayKey key = HighlightDisplayKey.find(inspectionTool.getShortName());
+    return inspectionProfile.isToolEnabled(key, file) ? inspectionProfile.getErrorLevel(key, file) : HighlightDisplayLevel.DO_NOT_SHOW;
+  }
+
+  private Map<ProblemDescriptor, HighlightDisplayLevel> runXmlFileSchemaValidation(@NotNull XmlFile xmlFile) {
+    final AnnotationHolderImpl holder = new AnnotationHolderImpl(new AnnotationSession(xmlFile));
+
+    final List<ExternalAnnotator> annotators = ExternalLanguageAnnotators.allForFile(StdLanguages.XML, xmlFile);
+    for (ExternalAnnotator annotator : annotators) {
+      annotator.annotate(xmlFile, holder);
+    }
+
+    if (!holder.hasAnnotations()) return Collections.emptyMap();
+
+    Map<ProblemDescriptor, HighlightDisplayLevel> problemsMap = new LinkedHashMap<ProblemDescriptor, HighlightDisplayLevel>();
+    for (final Annotation annotation : holder) {
+      final HighlightInfo info = HighlightInfo.fromAnnotation(annotation);
+      if (info.getSeverity() == HighlightSeverity.INFORMATION) continue;
+
+      final PsiElement startElement = xmlFile.findElementAt(info.startOffset);
+      final PsiElement endElement = info.startOffset == info.endOffset ? startElement : xmlFile.findElementAt(info.endOffset - 1);
+      if (startElement == null || endElement == null) continue;
+
+      final ProblemDescriptor descriptor =
+        myInspectionManager.createProblemDescriptor(startElement, endElement, info.description, ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                                    false);
+      final HighlightDisplayLevel level = info.getSeverity() == HighlightSeverity.ERROR? HighlightDisplayLevel.ERROR: HighlightDisplayLevel.WARNING;
+      problemsMap.put(descriptor, level);
+    }
+    return problemsMap;
+  }
+
+
+  @NotNull
+  public String getDescription() {
+    return myValidator.getDescription();
+  }
+
+  public boolean validateConfiguration(final CompileScope scope) {
+    return true;
+  }
+
+  public ValidityState createValidityState(final DataInput in) throws IOException {
+    return PsiElementsValidityState.load(in);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/compiler/util/PsiElementsValidityState.java b/java/compiler/impl/src/com/intellij/openapi/compiler/util/PsiElementsValidityState.java
new file mode 100644
index 0000000..ce79281
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/compiler/util/PsiElementsValidityState.java
@@ -0,0 +1,76 @@
+/*
+ * 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.openapi.compiler.util;
+
+import com.intellij.compiler.CompilerIOUtil;
+import com.intellij.openapi.compiler.ValidityState;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.util.io.IOUtil;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+import java.util.HashMap;
+import java.util.Map;
+import java.util.Set;
+
+public class PsiElementsValidityState implements ValidityState {
+  private final Map<String, Long> myDependencies = new HashMap<String, Long>();
+
+  public PsiElementsValidityState() {
+  }
+
+  public void addDependency(final String key, final Long value) {
+    myDependencies.put(key, value);
+  }
+
+  public boolean equalsTo(ValidityState otherState) {
+    return otherState instanceof PsiElementsValidityState &&
+           myDependencies.equals(((PsiElementsValidityState)otherState).myDependencies);
+  }
+
+  public void save(DataOutput out) throws IOException {
+    final Set<Map.Entry<String, Long>> entries = myDependencies.entrySet();
+    out.writeInt(entries.size());
+    for (Map.Entry<String, Long> entry : entries) {
+      IOUtil.writeString(entry.getKey(), out);
+      out.writeLong(entry.getValue().longValue());
+    }
+  }
+
+  public static PsiElementsValidityState load(DataInput input) throws IOException {
+    int size = input.readInt();
+    final PsiElementsValidityState state = new PsiElementsValidityState();
+    while (size-- > 0) {
+      final String s = CompilerIOUtil.readString(input);
+      final long timestamp = input.readLong();
+      state.addDependency(s, timestamp);
+    }
+    return state;
+  }
+
+  public void addDependency(final PsiElement element) {
+    final PsiFile psiFile = element.getContainingFile();
+    if (psiFile != null) {
+      VirtualFile file = psiFile.getVirtualFile();
+      if (file != null) {
+        addDependency(file.getUrl(), file.getTimeStamp());
+      }
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/openapi/deployment/DeploymentUtilImpl.java b/java/compiler/impl/src/com/intellij/openapi/deployment/DeploymentUtilImpl.java
new file mode 100644
index 0000000..d36d28f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/deployment/DeploymentUtilImpl.java
@@ -0,0 +1,177 @@
+/*
+ * 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.openapi.deployment;
+
+import com.intellij.compiler.impl.packagingCompiler.BuildRecipeImpl;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.util.SystemInfo;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlDocument;
+import com.intellij.psi.xml.XmlFile;
+import com.intellij.util.descriptors.ConfigFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.Set;
+
+/**
+ * @author Alexey Kudravtsev
+ */
+public class DeploymentUtilImpl extends DeploymentUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.deployment.MakeUtilImpl");
+
+  public void copyFile(@NotNull final File fromFile,
+                       @NotNull final File toFile,
+                       @NotNull CompileContext context,
+                       @Nullable Set<String> writtenPaths,
+                       @Nullable FileFilter fileFilter) throws IOException {
+    if (fileFilter != null && !fileFilter.accept(fromFile)) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Skipping " + fromFile.getAbsolutePath() + ": it wasn't accepted by filter " + fileFilter);
+      }
+      return;
+    }
+    checkPathDoNotNavigatesUpFromFile(fromFile);
+    checkPathDoNotNavigatesUpFromFile(toFile);
+    if (fromFile.isDirectory()) {
+      final File[] fromFiles = fromFile.listFiles();
+      toFile.mkdirs();
+      for (File file : fromFiles) {
+        copyFile(file, new File(toFile, file.getName()), context, writtenPaths, fileFilter);
+      }
+      return;
+    }
+    if (toFile.isDirectory()) {
+      context.addMessage(CompilerMessageCategory.ERROR,
+                         CompilerBundle.message("message.text.destination.is.directory", createCopyErrorMessage(fromFile, toFile)), null, -1, -1);
+      return;
+    }
+    if (FileUtil.filesEqual(fromFile, toFile) || writtenPaths != null && !writtenPaths.add(toFile.getPath())) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Skipping " + fromFile.getAbsolutePath() + ": " + toFile.getAbsolutePath() + " is already written");
+      }
+      return;
+    }
+    if (!FileUtil.isFilePathAcceptable(toFile, fileFilter)) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Skipping " + fromFile.getAbsolutePath() + ": " + toFile.getAbsolutePath() + " wasn't accepted by filter " + fileFilter);
+      }
+      return;
+    }
+    context.getProgressIndicator().setText("Copying files");
+    context.getProgressIndicator().setText2(fromFile.getPath());
+    try {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Copy file '" + fromFile + "' to '"+toFile+"'");
+      }
+      if (toFile.exists() && !SystemInfo.isFileSystemCaseSensitive) {
+        File canonicalFile = toFile.getCanonicalFile();
+        if (!canonicalFile.getAbsolutePath().equals(toFile.getAbsolutePath())) {
+          FileUtil.delete(toFile);
+        }
+      }
+      FileUtil.copy(fromFile, toFile);
+    }
+    catch (IOException e) {
+      context.addMessage(CompilerMessageCategory.ERROR, createCopyErrorMessage(fromFile, toFile) + ": "+e.getLocalizedMessage(), null, -1, -1);
+    }
+  }
+
+  // OS X is sensitive for that
+  private static void checkPathDoNotNavigatesUpFromFile(File file) {
+    String path = file.getPath();
+    int i = path.indexOf("..");
+    if (i != -1) {
+      String filepath = path.substring(0,i-1);
+      File filepart = new File(filepath);
+      if (filepart.exists() && !filepart.isDirectory()) {
+        LOG.error("Incorrect file path: '" + path + '\'');
+      }
+    }
+  }
+
+  private static String createCopyErrorMessage(final File fromFile, final File toFile) {
+    return CompilerBundle.message("message.text.error.copying.file.to.file", FileUtil.toSystemDependentName(fromFile.getPath()),
+                              FileUtil.toSystemDependentName(toFile.getPath()));
+  }
+
+  public final boolean addItemsRecursively(@NotNull BuildRecipe items, @NotNull File root, String outputRelativePath) {
+    if (outputRelativePath == null) outputRelativePath = "";
+    outputRelativePath = trimForwardSlashes(outputRelativePath);
+
+    items.addFileCopyInstruction(root, true, outputRelativePath);
+    return true;
+  }
+
+  public void reportDeploymentDescriptorDoesNotExists(ConfigFile descriptor, CompileContext context, Module module) {
+    final String description = ModuleType.get(module).getName() + " '" + module.getName() + '\'';
+    String descriptorPath = VfsUtil.urlToPath(descriptor.getUrl());
+    final String message =
+      CompilerBundle.message("message.text.compiling.item.deployment.descriptor.could.not.be.found", description, descriptorPath);
+    context.addMessage(CompilerMessageCategory.ERROR, message, null, -1, -1);
+  }
+
+  public void checkConfigFile(final ConfigFile descriptor, final CompileContext compileContext, final Module module) {
+    if (new File(VfsUtil.urlToPath(descriptor.getUrl())).exists()) {
+      String message = getConfigFileErrorMessage(descriptor);
+      if (message != null) {
+        final String moduleDescription = ModuleType.get(module).getName() + " '" + module.getName() + '\'';
+        compileContext.addMessage(CompilerMessageCategory.ERROR,
+                                CompilerBundle.message("message.text.compiling.module.message", moduleDescription, message),
+                                  descriptor.getUrl(), -1, -1);
+      }
+    }
+    else {
+      DeploymentUtil.getInstance().reportDeploymentDescriptorDoesNotExists(descriptor, compileContext, module);
+    }
+  }
+
+  public BuildRecipe createBuildRecipe() {
+    return new BuildRecipeImpl();
+  }
+
+  @Nullable
+  public String getConfigFileErrorMessage(final ConfigFile configFile) {
+    if (configFile.getVirtualFile() == null) {
+      String path = FileUtil.toSystemDependentName(VfsUtil.urlToPath(configFile.getUrl()));
+      return CompilerBundle.message("mesage.text.deployment.descriptor.file.not.exist", path);
+    }
+    PsiFile psiFile = configFile.getPsiFile();
+    if (psiFile == null || !psiFile.isValid()) {
+      return CompilerBundle.message("message.text.deployment.description.invalid.file");
+    }
+
+    if (psiFile instanceof XmlFile) {
+      XmlDocument document = ((XmlFile)psiFile).getDocument();
+      if (document == null || document.getRootTag() == null) {
+        return CompilerBundle.message("message.text.xml.file.invalid", FileUtil.toSystemDependentName(VfsUtil.urlToPath(configFile.getUrl())));
+      }
+    }
+    return null;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java b/java/compiler/impl/src/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java
new file mode 100644
index 0000000..c5b6c66
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/openapi/projectRoots/impl/MockJdkWrapper.java
@@ -0,0 +1,102 @@
+/*
+ * 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.
+ */
+
+/**
+ * @author cdr
+ */
+package com.intellij.openapi.projectRoots.impl;
+
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkAdditionalData;
+import com.intellij.openapi.projectRoots.SdkModificator;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.RootProvider;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * used to override JdkHome location in order to provide correct paths
+ */
+public final class MockJdkWrapper implements Sdk {
+  private final String myHomePath;
+  private final Sdk myDelegate;
+
+  public MockJdkWrapper(String homePath, @NotNull Sdk delegate) {
+    myHomePath = homePath;
+    myDelegate = delegate;
+  }
+
+  public VirtualFile getHomeDirectory() {
+    return LocalFileSystem.getInstance().findFileByIoFile(new File(getHomePath()));
+  }
+
+  public String getHomePath() {
+    final String homePath = FileUtil.toSystemDependentName(myHomePath == null ? myDelegate.getHomePath() : myHomePath);
+    return StringUtil.trimEnd(homePath, File.separator);
+  }
+
+  @NotNull
+  public SdkTypeId getSdkType() {
+    return myDelegate.getSdkType();
+  }
+
+  @NotNull
+  public String getName() {
+    return myDelegate.getName();
+  }
+
+  public String getVersionString() {
+    return myDelegate.getVersionString();
+  }
+
+  @NotNull
+  public RootProvider getRootProvider() {
+    return myDelegate.getRootProvider();
+  }
+
+  public <T> T getUserData(@NotNull Key<T> key) {
+    return myDelegate.getUserData(key);
+  }
+
+  public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
+    myDelegate.putUserData(key, value);
+  }
+
+  @NotNull
+  public Object clone() throws CloneNotSupportedException {
+    throw new CloneNotSupportedException();
+  }
+
+  public SdkAdditionalData getSdkAdditionalData() {
+    return null;
+  }
+
+  @NotNull
+  public SdkModificator getSdkModificator() {
+    return null;
+  }
+
+  public Sdk getDelegate() {
+    return myDelegate;
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java
new file mode 100644
index 0000000..5a2211b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinder.java
@@ -0,0 +1,35 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactBySourceFileFinder {
+  public static ArtifactBySourceFileFinder getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, ArtifactBySourceFileFinder.class);
+  }
+
+  public abstract Collection<? extends Artifact> findArtifacts(@NotNull VirtualFile sourceFile);
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java
new file mode 100644
index 0000000..0083ead
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactBySourceFileFinderImpl.java
@@ -0,0 +1,118 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.MultiValuesMap;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.elements.ComplexPackagingElementType;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement;
+import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactBySourceFileFinderImpl extends ArtifactBySourceFileFinder {
+  private CachedValue<MultiValuesMap<VirtualFile, Artifact>> myFile2Artifacts;
+  private final Project myProject;
+
+  public ArtifactBySourceFileFinderImpl(Project project) {
+    myProject = project;
+  }
+
+  public CachedValue<MultiValuesMap<VirtualFile, Artifact>> getFileToArtifactsMap() {
+    if (myFile2Artifacts == null) {
+      myFile2Artifacts =
+        CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<MultiValuesMap<VirtualFile, Artifact>>() {
+          public Result<MultiValuesMap<VirtualFile, Artifact>> compute() {
+            MultiValuesMap<VirtualFile, Artifact> result = computeFileToArtifactsMap();
+            List<ModificationTracker> trackers = new ArrayList<ModificationTracker>();
+            trackers.add(ArtifactManager.getInstance(myProject).getModificationTracker());
+            for (ComplexPackagingElementType<?> type : PackagingElementFactory.getInstance().getComplexElementTypes()) {
+              ContainerUtil.addIfNotNull(type.getAllSubstitutionsModificationTracker(myProject), trackers);
+            }
+            return Result.create(result, trackers.toArray(new ModificationTracker[trackers.size()]));
+          }
+        }, false);
+    }
+    return myFile2Artifacts;
+  }
+
+  private MultiValuesMap<VirtualFile, Artifact> computeFileToArtifactsMap() {
+    final MultiValuesMap<VirtualFile, Artifact> result = new MultiValuesMap<VirtualFile, Artifact>();
+    final ArtifactManager artifactManager = ArtifactManager.getInstance(myProject);
+    for (final Artifact artifact : artifactManager.getArtifacts()) {
+      final PackagingElementResolvingContext context = artifactManager.getResolvingContext();
+      ArtifactUtil.processPackagingElements(artifact, null, new PackagingElementProcessor<PackagingElement<?>>() {
+        @Override
+        public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+          if (element instanceof FileOrDirectoryCopyPackagingElement<?>) {
+            final VirtualFile root = ((FileOrDirectoryCopyPackagingElement)element).findFile();
+            if (root != null) {
+              result.put(root, artifact);
+            }
+          }
+          else if (element instanceof ModuleOutputPackagingElement) {
+            for (VirtualFile sourceRoot : ((ModuleOutputPackagingElement)element).getSourceRoots(context)) {
+              result.put(sourceRoot, artifact);
+            }
+          }
+          return true;
+        }
+      }, context, true);
+    }
+    return result;
+  }
+
+  @Override
+  public Collection<? extends Artifact> findArtifacts(@NotNull VirtualFile sourceFile) {
+    final MultiValuesMap<VirtualFile, Artifact> map = getFileToArtifactsMap().getValue();
+    if (map.isEmpty()) {
+      return Collections.emptyList();
+    }
+
+    List<Artifact> result = null;
+    VirtualFile file = sourceFile;
+    while (file != null) {
+      final Collection<Artifact> artifacts = map.get(file);
+      if (artifacts != null) {
+        if (result == null) {
+          result = new SmartList<Artifact>();
+        }
+        result.addAll(artifacts);
+      }
+      file = file.getParent();
+    }
+    return result != null ? result : Collections.<Artifact>emptyList();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java
new file mode 100644
index 0000000..65763c0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactImpl.java
@@ -0,0 +1,188 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.util.UserDataHolderBase;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.*;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import com.intellij.util.EventDispatcher;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public class ArtifactImpl extends UserDataHolderBase implements ModifiableArtifact {
+  private CompositePackagingElement<?> myRootElement;
+  private String myName;
+  private boolean myBuildOnMake;
+  private String myOutputPath;
+  private final EventDispatcher<ArtifactListener> myDispatcher;
+  private ArtifactType myArtifactType;
+  private Map<ArtifactPropertiesProvider, ArtifactProperties<?>> myProperties;
+
+  public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, @NotNull CompositePackagingElement<?> rootElement,
+                      String outputPath) {
+    this(name, artifactType, buildOnMake, rootElement, outputPath, null);
+  }
+  public ArtifactImpl(@NotNull String name, @NotNull ArtifactType artifactType, boolean buildOnMake, @NotNull CompositePackagingElement<?> rootElement,
+                      String outputPath,
+                      EventDispatcher<ArtifactListener> dispatcher) {
+    myName = name;
+    myArtifactType = artifactType;
+    myBuildOnMake = buildOnMake;
+    myRootElement = rootElement;
+    myOutputPath = outputPath;
+    myDispatcher = dispatcher;
+    myProperties = new HashMap<ArtifactPropertiesProvider, ArtifactProperties<?>>();
+    resetProperties();
+  }
+
+  private void resetProperties() {
+    myProperties.clear();
+    for (ArtifactPropertiesProvider provider : ArtifactPropertiesProvider.getProviders()) {
+      if (provider.isAvailableFor(myArtifactType)) {
+        myProperties.put(provider, provider.createProperties(myArtifactType));
+      }
+    }
+  }
+
+  @NotNull
+  public ArtifactType getArtifactType() {
+    return myArtifactType;
+  }
+
+  public String getName() {
+    return myName;
+  }
+
+  public boolean isBuildOnMake() {
+    return myBuildOnMake;
+  }
+
+  @NotNull
+  public CompositePackagingElement<?> getRootElement() {
+    return myRootElement;
+  }
+
+  public String getOutputPath() {
+    return myOutputPath;
+  }
+
+  public Collection<? extends ArtifactPropertiesProvider> getPropertiesProviders() {
+    return Collections.unmodifiableCollection(myProperties.keySet());
+  }
+
+  public ArtifactImpl createCopy(EventDispatcher<ArtifactListener> dispatcher) {
+    final ArtifactImpl artifact = new ArtifactImpl(myName, myArtifactType, myBuildOnMake, myRootElement, myOutputPath, dispatcher);
+    for (Map.Entry<ArtifactPropertiesProvider, ArtifactProperties<?>> entry : myProperties.entrySet()) {
+      final ArtifactProperties newProperties = artifact.myProperties.get(entry.getKey());
+      //noinspection unchecked
+      newProperties.loadState(entry.getValue().getState());
+    }
+    return artifact;
+  }
+
+  public void setName(@NotNull String name) {
+    String oldName = myName;
+    myName = name;
+    if (myDispatcher != null) {
+      myDispatcher.getMulticaster().artifactChanged(this, oldName);
+    }
+  }
+
+  @NonNls @Override
+  public String toString() {
+    return "artifact:" + myName;
+  }
+
+  public void setRootElement(CompositePackagingElement<?> root) {
+    myRootElement = root;
+  }
+
+  public void setProperties(ArtifactPropertiesProvider provider, ArtifactProperties<?> properties) {
+    if (properties != null) {
+      myProperties.put(provider, properties);
+    }
+    else {
+      myProperties.remove(provider);
+    }
+  }
+
+  public void setArtifactType(@NotNull ArtifactType selected) {
+    myArtifactType = selected;
+    resetProperties();
+  }
+
+  public void setBuildOnMake(boolean buildOnMake) {
+    myBuildOnMake = buildOnMake;
+  }
+
+  public void setOutputPath(String outputPath) {
+    myOutputPath = outputPath;
+  }
+
+  public ArtifactProperties<?> getProperties(@NotNull ArtifactPropertiesProvider provider) {
+    return myProperties.get(provider);
+  }
+
+  @Override
+  public VirtualFile getOutputFile() {
+    String filePath = getOutputFilePath();
+    return !StringUtil.isEmpty(filePath) ? LocalFileSystem.getInstance().findFileByPath(filePath) : null;
+  }
+
+  @Override
+  public String getOutputFilePath() {
+    if (StringUtil.isEmpty(myOutputPath)) return null;
+
+    String filePath;
+    if (myRootElement instanceof ArchivePackagingElement) {
+      filePath = myOutputPath + "/" + ((ArchivePackagingElement)myRootElement).getArchiveFileName();
+    }
+    else {
+      filePath = myOutputPath;
+    }
+    return filePath;
+  }
+
+  @Nullable
+  public String getOutputDirectoryPathToCleanOnRebuild() {
+    if (myRootElement instanceof ArchivePackagingElement || StringUtil.isEmpty(myOutputPath)) {
+      return null;
+    }
+    return myOutputPath;
+  }
+
+  public void copyFrom(ArtifactImpl modified) {
+    myName = modified.getName();
+    myOutputPath = modified.getOutputPath();
+    myBuildOnMake = modified.isBuildOnMake();
+    myRootElement = modified.getRootElement();
+    myProperties = modified.myProperties;
+    myArtifactType = modified.getArtifactType();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java
new file mode 100644
index 0000000..2b990dc
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactLoadingErrorDescription.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.module.ConfigurationErrorDescription;
+import com.intellij.openapi.module.ConfigurationErrorType;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+
+/**
+ * @author nik
+ */
+public class ArtifactLoadingErrorDescription extends ConfigurationErrorDescription {
+  private static final ConfigurationErrorType INVALID_ARTIFACT = new ConfigurationErrorType("artifact", false);
+  private final Project myProject;
+  private final InvalidArtifact myArtifact;
+
+  public ArtifactLoadingErrorDescription(Project project, InvalidArtifact artifact) {
+    super(artifact.getName(), artifact.getErrorMessage(), INVALID_ARTIFACT);
+    myProject = project;
+    myArtifact = artifact;
+  }
+
+  @Override
+  public void ignoreInvalidElement() {
+    final ModifiableArtifactModel model = ArtifactManager.getInstance(myProject).createModifiableModel();
+    model.removeArtifact(myArtifact);
+    new WriteAction() {
+      protected void run(final Result result) {
+        model.commit();
+      }
+    }.execute();
+  }
+
+  @Override
+  public String getIgnoreConfirmationMessage() {
+    return "Would you like to remove artifact '" + myArtifact.getName() + "?";
+  }
+
+  @Override
+  public boolean isValid() {
+    return ArtifactManager.getInstance(myProject).getAllArtifactsIncludingInvalid().contains(myArtifact);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
new file mode 100644
index 0000000..c3896a8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerImpl.java
@@ -0,0 +1,450 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.ProjectLoadingErrorsNotifier;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ex.ProjectRootManagerEx;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.packaging.artifacts.*;
+import com.intellij.packaging.elements.*;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.SkipDefaultValuesSerializationFilters;
+import com.intellij.util.xmlb.XmlSerializer;
+import gnu.trove.THashSet;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.serialization.artifact.ArtifactManagerState;
+import org.jetbrains.jps.model.serialization.artifact.ArtifactPropertiesState;
+import org.jetbrains.jps.model.serialization.artifact.ArtifactState;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+@State(
+    name = ArtifactManagerImpl.COMPONENT_NAME,
+    storages = {
+        @Storage( file = StoragePathMacros.PROJECT_FILE),
+        @Storage( file = StoragePathMacros.PROJECT_CONFIG_DIR + "/artifacts/", scheme = StorageScheme.DIRECTORY_BASED, stateSplitter = ArtifactManagerStateSplitter.class)
+    }
+)
+public class ArtifactManagerImpl extends ArtifactManager implements ProjectComponent, PersistentStateComponent<ArtifactManagerState> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.artifacts.ArtifactManagerImpl");
+  @NonNls public static final String COMPONENT_NAME = "ArtifactManager";
+  @NonNls public static final String PACKAGING_ELEMENT_NAME = "element";
+  @NonNls public static final String TYPE_ID_ATTRIBUTE = "id";
+  private final ArtifactManagerModel myModel;
+  private final Project myProject;
+  private final DefaultPackagingElementResolvingContext myResolvingContext;
+  private boolean myInsideCommit = false;
+  private boolean myLoaded;
+  private long myModificationCount;
+  private final ModificationTracker myModificationTracker = new ModificationTracker() {
+    public long getModificationCount() {
+      return myModificationCount;
+    }
+  };
+  private final Map<String, LocalFileSystem.WatchRequest> myWatchedOutputs = new HashMap<String, LocalFileSystem.WatchRequest>();
+
+  public ArtifactManagerImpl(Project project) {
+    myProject = project;
+    myModel = new ArtifactManagerModel();
+    myResolvingContext = new DefaultPackagingElementResolvingContext(myProject);
+    ((ArtifactPointerManagerImpl)ArtifactPointerManager.getInstance(project)).setArtifactManager(this);
+  }
+
+  @NotNull
+  public Artifact[] getArtifacts() {
+    return myModel.getArtifacts();
+  }
+
+  public Artifact findArtifact(@NotNull String name) {
+    return myModel.findArtifact(name);
+  }
+
+  @NotNull
+  public Artifact getArtifactByOriginal(@NotNull Artifact artifact) {
+    return myModel.getArtifactByOriginal(artifact);
+  }
+
+  @NotNull
+  public Artifact getOriginalArtifact(@NotNull Artifact artifact) {
+    return myModel.getOriginalArtifact(artifact);
+  }
+
+  public Collection<? extends Artifact> getArtifactsByType(@NotNull ArtifactType type) {
+    return myModel.getArtifactsByType(type);
+  }
+
+  @Override
+  public List<? extends Artifact> getAllArtifactsIncludingInvalid() {
+    return myModel.getAllArtifactsIncludingInvalid();
+  }
+
+  public ArtifactManagerState getState() {
+    final ArtifactManagerState state = new ArtifactManagerState();
+    for (Artifact artifact : getAllArtifactsIncludingInvalid()) {
+      final ArtifactState artifactState;
+      if (artifact instanceof InvalidArtifact) {
+        artifactState = ((InvalidArtifact)artifact).getState();
+      }
+      else {
+        artifactState = new ArtifactState();
+        artifactState.setBuildOnMake(artifact.isBuildOnMake());
+        artifactState.setName(artifact.getName());
+        artifactState.setOutputPath(artifact.getOutputPath());
+        artifactState.setRootElement(serializePackagingElement(artifact.getRootElement()));
+        artifactState.setArtifactType(artifact.getArtifactType().getId());
+        for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
+          final ArtifactPropertiesState propertiesState = serializeProperties(provider, artifact.getProperties(provider));
+          if (propertiesState != null) {
+            artifactState.getPropertiesList().add(propertiesState);
+          }
+        }
+        Collections.sort(artifactState.getPropertiesList(), new Comparator<ArtifactPropertiesState>() {
+          public int compare(ArtifactPropertiesState o1, ArtifactPropertiesState o2) {
+            return o1.getId().compareTo(o2.getId());
+          }
+        });
+      }
+      state.getArtifacts().add(artifactState);
+    }
+    return state;
+  }
+
+  @Nullable
+  private static <S> ArtifactPropertiesState serializeProperties(ArtifactPropertiesProvider provider, ArtifactProperties<S> properties) {
+    final ArtifactPropertiesState state = new ArtifactPropertiesState();
+    state.setId(provider.getId());
+    final Element options = new Element("options");
+    XmlSerializer.serializeInto(properties.getState(), options, new SkipDefaultValuesSerializationFilters());
+    if (options.getContent().isEmpty() && options.getAttributes().isEmpty()) return null;
+    state.setOptions(options);
+    return state;
+  }
+
+  private static Element serializePackagingElement(PackagingElement<?> packagingElement) {
+    Element element = new Element(PACKAGING_ELEMENT_NAME);
+    element.setAttribute(TYPE_ID_ATTRIBUTE, packagingElement.getType().getId());
+    final Object bean = packagingElement.getState();
+    if (bean != null) {
+      XmlSerializer.serializeInto(bean, element, new SkipDefaultValuesSerializationFilters());
+    }
+    if (packagingElement instanceof CompositePackagingElement) {
+      for (PackagingElement<?> child : ((CompositePackagingElement<?>)packagingElement).getChildren()) {
+        element.addContent(serializePackagingElement(child));
+      }
+    }
+    return element;
+  }
+
+  private <T> PackagingElement<T> deserializeElement(Element element) throws UnknownPackagingElementTypeException {
+    final String id = element.getAttributeValue(TYPE_ID_ATTRIBUTE);
+    PackagingElementType<?> type = PackagingElementFactory.getInstance().findElementType(id);
+    if (type == null) {
+      throw new UnknownPackagingElementTypeException(id);
+    }
+
+    PackagingElement<T> packagingElement = (PackagingElement<T>)type.createEmpty(myProject);
+    T state = packagingElement.getState();
+    if (state != null) {
+      XmlSerializer.deserializeInto(state, element);
+      packagingElement.loadState(state);
+    }
+    final List children = element.getChildren(PACKAGING_ELEMENT_NAME);
+    //noinspection unchecked
+    for (Element child : (List<? extends Element>)children) {
+      ((CompositePackagingElement<?>)packagingElement).addOrFindChild(deserializeElement(child));
+    }
+    return packagingElement;
+  }
+
+  public void loadState(ArtifactManagerState managerState) {
+    final List<ArtifactImpl> artifacts = new ArrayList<ArtifactImpl>();
+    for (ArtifactState state : managerState.getArtifacts()) {
+      artifacts.add(loadArtifact(state));
+    }
+
+    if (myLoaded) {
+      final ArtifactModelImpl model = new ArtifactModelImpl(this, artifacts);
+      doCommit(model);
+    }
+    else {
+      myModel.setArtifactsList(artifacts);
+      myLoaded = true;
+    }
+  }
+
+  private ArtifactImpl loadArtifact(ArtifactState state) {
+    ArtifactType type = ArtifactType.findById(state.getArtifactType());
+    if (type == null) {
+      return createInvalidArtifact(state, "Unknown artifact type: " + state.getArtifactType());
+    }
+
+    final Element element = state.getRootElement();
+    final String artifactName = state.getName();
+    final CompositePackagingElement<?> rootElement;
+    if (element != null) {
+      try {
+        rootElement = (CompositePackagingElement<?>)deserializeElement(element);
+      }
+      catch (UnknownPackagingElementTypeException e) {
+        return createInvalidArtifact(state, "Unknown element: " + e.getTypeId());
+      }
+    }
+    else {
+      rootElement = type.createRootElement(artifactName);
+    }
+
+    final ArtifactImpl artifact = new ArtifactImpl(artifactName, type, state.isBuildOnMake(), rootElement, state.getOutputPath());
+    final List<ArtifactPropertiesState> propertiesList = state.getPropertiesList();
+    for (ArtifactPropertiesState propertiesState : propertiesList) {
+      final ArtifactPropertiesProvider provider = ArtifactPropertiesProvider.findById(propertiesState.getId());
+      if (provider != null) {
+        deserializeProperties(artifact.getProperties(provider), propertiesState);
+      }
+      else {
+        return createInvalidArtifact(state, "Unknown artifact properties: " + propertiesState.getId());
+      }
+    }
+    return artifact;
+  }
+
+  private InvalidArtifact createInvalidArtifact(ArtifactState state, String errorMessage) {
+    final InvalidArtifact artifact = new InvalidArtifact(state, errorMessage);
+    ProjectLoadingErrorsNotifier.getInstance(myProject).registerError(new ArtifactLoadingErrorDescription(myProject, artifact));
+    return artifact;
+  }
+
+  private static <S> void deserializeProperties(ArtifactProperties<S> artifactProperties, ArtifactPropertiesState propertiesState) {
+    final Element options = propertiesState.getOptions();
+    if (artifactProperties == null || options == null) {
+      return;
+    }
+    final S state = artifactProperties.getState();
+    if (state != null) {
+      XmlSerializer.deserializeInto(state, options);
+      artifactProperties.loadState(state);
+    }
+  }
+
+  public void disposeComponent() {
+    LocalFileSystem.getInstance().removeWatchedRoots(myWatchedOutputs.values());
+  }
+
+  @NotNull
+  public String getComponentName() {
+    return COMPONENT_NAME;
+  }
+
+  public void initComponent() {
+    VirtualFileManager.getInstance().addVirtualFileListener(new ArtifactVirtualFileListener(myProject, this), myProject);
+    updateWatchedRoots();
+  }
+
+  private void updateWatchedRoots() {
+    Set<String> pathsToRemove = new HashSet<String>(myWatchedOutputs.keySet());
+    Set<String> toAdd = new HashSet<String>();
+    for (Artifact artifact : getArtifacts()) {
+      final String path = artifact.getOutputPath();
+      if (path != null && path.length() > 0) {
+        pathsToRemove.remove(path);
+        if (!myWatchedOutputs.containsKey(path)) {
+          toAdd.add(path);
+        }
+      }
+    }
+
+    List<LocalFileSystem.WatchRequest> requestsToRemove = new ArrayList<LocalFileSystem.WatchRequest>();
+    for (String path : pathsToRemove) {
+      final LocalFileSystem.WatchRequest request = myWatchedOutputs.remove(path);
+      ContainerUtil.addIfNotNull(request, requestsToRemove);
+    }
+
+    Set<LocalFileSystem.WatchRequest> newRequests = LocalFileSystem.getInstance().replaceWatchedRoots(requestsToRemove, toAdd, null);
+    for (LocalFileSystem.WatchRequest request : newRequests) {
+      myWatchedOutputs.put(request.getRootPath(), request);
+    }
+  }
+
+  public void projectOpened() {
+  }
+
+  public void projectClosed() {
+  }
+
+  @Override
+  public Artifact[] getSortedArtifacts() {
+    return myModel.getSortedArtifacts();
+  }
+
+  @Override
+  public ModifiableArtifactModel createModifiableModel() {
+    return new ArtifactModelImpl(this, getArtifactsList());
+  }
+
+  @Override
+  public PackagingElementResolvingContext getResolvingContext() {
+    return myResolvingContext;
+  }
+
+  public List<ArtifactImpl> getArtifactsList() {
+    return myModel.myArtifactsList;
+  }
+
+  public void commit(ArtifactModelImpl artifactModel) {
+    ApplicationManager.getApplication().assertWriteAccessAllowed();
+
+    doCommit(artifactModel);
+  }
+
+  private void doCommit(ArtifactModelImpl artifactModel) {
+    boolean hasChanges;
+    LOG.assertTrue(!myInsideCommit, "Recursive commit");
+    myInsideCommit = true;
+    try {
+
+      final List<ArtifactImpl> allArtifacts = artifactModel.getOriginalArtifacts();
+
+      final Set<ArtifactImpl> removed = new THashSet<ArtifactImpl>(myModel.myArtifactsList);
+      final List<ArtifactImpl> added = new ArrayList<ArtifactImpl>();
+      final List<Pair<ArtifactImpl, String>> changed = new ArrayList<Pair<ArtifactImpl, String>>();
+
+      for (ArtifactImpl artifact : allArtifacts) {
+        final boolean isAdded = !removed.remove(artifact);
+        final ArtifactImpl modifiableCopy = artifactModel.getModifiableCopy(artifact);
+        if (isAdded) {
+          added.add(artifact);
+        }
+        else if (modifiableCopy != null && !modifiableCopy.equals(artifact)) {
+          final String oldName = artifact.getName();
+          artifact.copyFrom(modifiableCopy);
+          changed.add(Pair.create(artifact, oldName));
+        }
+      }
+
+      myModel.setArtifactsList(allArtifacts);
+      myModificationCount++;
+      final ArtifactListener publisher = myProject.getMessageBus().syncPublisher(TOPIC);
+      hasChanges = !removed.isEmpty() || !added.isEmpty() || !changed.isEmpty();
+      ProjectRootManagerEx.getInstanceEx(myProject).mergeRootsChangesDuring(new Runnable() {
+        public void run() {
+          for (ArtifactImpl artifact : removed) {
+            publisher.artifactRemoved(artifact);
+          }
+          //it's important to send 'removed' events before 'added'. Otherwise when artifacts are reloaded from xml artifact pointers will be damaged
+          for (ArtifactImpl artifact : added) {
+            publisher.artifactAdded(artifact);
+          }
+          for (Pair<ArtifactImpl, String> pair : changed) {
+            publisher.artifactChanged(pair.getFirst(), pair.getSecond());
+          }
+        }
+      });
+    }
+    finally {
+      myInsideCommit = false;
+    }
+    updateWatchedRoots();
+    if (hasChanges) {
+      BuildManager.getInstance().clearState(myProject);
+    }
+  }
+
+  public Project getProject() {
+    return myProject;
+  }
+
+  @NotNull
+  public Artifact addArtifact(@NotNull final String name, @NotNull final ArtifactType type, final CompositePackagingElement<?> root) {
+    return new WriteAction<Artifact>() {
+      protected void run(final Result<Artifact> result) {
+        final ModifiableArtifactModel model = createModifiableModel();
+        final ModifiableArtifact artifact = model.addArtifact(name, type);
+        if (root != null) {
+          artifact.setRootElement(root);
+        }
+        model.commit();
+        result.setResult(artifact);
+      }
+    }.execute().getResultObject();
+  }
+
+  @Override
+  public void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath, @NotNull PackagingElement<?> element) {
+    addElementsToDirectory(artifact, relativePath, Collections.singletonList(element));
+  }
+
+  @Override
+  public void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath,
+                                     @NotNull Collection<? extends PackagingElement<?>> elements) {
+    final ModifiableArtifactModel model = createModifiableModel();
+    final CompositePackagingElement<?> root = model.getOrCreateModifiableArtifact(artifact).getRootElement();
+    PackagingElementFactory.getInstance().getOrCreateDirectory(root, relativePath).addOrFindChildren(elements);
+    new WriteAction() {
+      protected void run(final Result result) {
+        model.commit();
+      }
+    }.execute();
+  }
+
+  @Override
+  public ModificationTracker getModificationTracker() {
+    return myModificationTracker;
+  }
+
+  private static class ArtifactManagerModel extends ArtifactModelBase {
+    private List<ArtifactImpl> myArtifactsList = new ArrayList<ArtifactImpl>();
+    private Artifact[] mySortedArtifacts;
+
+    public void setArtifactsList(List<ArtifactImpl> artifactsList) {
+      myArtifactsList = artifactsList;
+      artifactsChanged();
+    }
+
+    @Override
+    protected void artifactsChanged() {
+      super.artifactsChanged();
+      mySortedArtifacts = null;
+    }
+
+    protected List<? extends Artifact> getArtifactsList() {
+      return myArtifactsList;
+    }
+
+    public Artifact[] getSortedArtifacts() {
+      if (mySortedArtifacts == null) {
+        mySortedArtifacts = getArtifacts().clone();
+        Arrays.sort(mySortedArtifacts, ARTIFACT_COMPARATOR);
+      }
+      return mySortedArtifacts;
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java
new file mode 100644
index 0000000..90ee240
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactManagerStateSplitter.java
@@ -0,0 +1,51 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.components.StateSplitter;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.text.UniqueNameGenerator;
+import org.jdom.Element;
+import org.jetbrains.jps.model.serialization.artifact.ArtifactState;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactManagerStateSplitter implements StateSplitter {
+  public List<Pair<Element, String>> splitState(Element e) {
+    final UniqueNameGenerator generator = new UniqueNameGenerator();
+
+    List<Pair<Element, String>> result = new ArrayList<Pair<Element, String>>();
+
+    for (Element element : JDOMUtil.getElements(e)) {
+      final String name = generator.generateUniqueName(FileUtil.sanitizeFileName(element.getAttributeValue(ArtifactState.NAME_ATTRIBUTE))) + ".xml";
+      result.add(new Pair<Element, String>(element, name));
+    }
+
+    return result;
+  }
+
+  public void mergeStatesInto(Element target, Element[] elements) {
+    for (Element e : elements) {
+      target.addContent(e);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelBase.java
new file mode 100644
index 0000000..9dbfa2a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelBase.java
@@ -0,0 +1,90 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactModel;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactModelBase implements ArtifactModel {
+  private Map<String, Artifact> myArtifactsMap;
+  private Artifact[] myArtifactsArray;
+  public static final Condition<Artifact> VALID_ARTIFACT_CONDITION = new Condition<Artifact>() {
+    @Override
+    public boolean value(Artifact artifact) {
+      return !(artifact instanceof InvalidArtifact);
+    }
+  };
+
+  protected abstract List<? extends Artifact> getArtifactsList();
+
+  @NotNull
+  public Artifact[] getArtifacts() {
+    if (myArtifactsArray == null) {
+      final List<? extends Artifact> validArtifacts = ContainerUtil.findAll(getArtifactsList(), VALID_ARTIFACT_CONDITION);
+      myArtifactsArray = validArtifacts.toArray(new Artifact[validArtifacts.size()]);
+    }
+    return myArtifactsArray;
+  }
+
+  @Override
+  public List<? extends Artifact> getAllArtifactsIncludingInvalid() {
+    return Collections.unmodifiableList(getArtifactsList());
+  }
+
+  public Artifact findArtifact(@NotNull String name) {
+    if (myArtifactsMap == null) {
+      myArtifactsMap = new HashMap<String, Artifact>();
+      for (Artifact artifact : getArtifactsList()) {
+        myArtifactsMap.put(artifact.getName(), artifact);
+      }
+    }
+    return myArtifactsMap.get(name);
+  }
+
+  @NotNull
+  public Artifact getArtifactByOriginal(@NotNull Artifact artifact) {
+    return artifact;
+  }
+
+  @NotNull
+  public Artifact getOriginalArtifact(@NotNull Artifact artifact) {
+    return artifact;
+  }
+
+  public Collection<? extends Artifact> getArtifactsByType(@NotNull ArtifactType type) {
+    final List<Artifact> result = new ArrayList<Artifact>();
+    for (Artifact artifact : getArtifacts()) {
+      if (artifact.getArtifactType().equals(type)) {
+        result.add(artifact);
+      }
+    }
+    return result;
+  }
+
+  protected void artifactsChanged() {
+    myArtifactsMap = null;
+    myArtifactsArray = null;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java
new file mode 100644
index 0000000..38f46db
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactModelImpl.java
@@ -0,0 +1,175 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.artifacts.*;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.util.EventDispatcher;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public class ArtifactModelImpl extends ArtifactModelBase implements ModifiableArtifactModel {
+  private final List<ArtifactImpl> myOriginalArtifacts;
+  private final ArtifactManagerImpl myArtifactManager;
+  private final Map<ArtifactImpl, ArtifactImpl> myArtifact2ModifiableCopy = new HashMap<ArtifactImpl, ArtifactImpl>();
+  private final Map<ArtifactImpl, ArtifactImpl> myModifiable2Original = new HashMap<ArtifactImpl, ArtifactImpl>();
+  private final EventDispatcher<ArtifactListener> myDispatcher = EventDispatcher.create(ArtifactListener.class);
+
+  public ArtifactModelImpl(ArtifactManagerImpl artifactManager, List<ArtifactImpl> originalArtifacts) {
+    myArtifactManager = artifactManager;
+    myOriginalArtifacts = new ArrayList<ArtifactImpl>(originalArtifacts);
+    addListener(new ArtifactAdapter() {
+      @Override
+      public void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName) {
+        artifactsChanged();
+      }
+    });
+  }
+
+  protected List<? extends Artifact> getArtifactsList() {
+    final List<ArtifactImpl> list = new ArrayList<ArtifactImpl>();
+    for (ArtifactImpl artifact : myOriginalArtifacts) {
+      final ArtifactImpl copy = myArtifact2ModifiableCopy.get(artifact);
+      if (copy != null) {
+        list.add(copy);
+      }
+      else {
+        list.add(artifact);
+      }
+    }
+    return list;
+  }
+
+  @NotNull
+  public ModifiableArtifact addArtifact(@NotNull final String name, @NotNull ArtifactType artifactType) {
+    return addArtifact(name, artifactType, artifactType.createRootElement(name));
+  }
+
+  @NotNull
+  public ModifiableArtifact addArtifact(@NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement<?> rootElement) {
+    final String uniqueName = generateUniqueName(name);
+    final String outputPath = ArtifactUtil.getDefaultArtifactOutputPath(uniqueName, myArtifactManager.getProject());
+    final ArtifactImpl artifact = new ArtifactImpl(uniqueName, artifactType, false, rootElement, outputPath, myDispatcher);
+    myOriginalArtifacts.add(artifact);
+    myArtifact2ModifiableCopy.put(artifact, artifact);
+    myModifiable2Original.put(artifact, artifact);
+
+    artifactsChanged();
+    myDispatcher.getMulticaster().artifactAdded(artifact);
+    return artifact;
+  }
+
+  private String generateUniqueName(String baseName) {
+    String name = baseName;
+    int i = 2;
+    while (true) {
+      if (findArtifact(name) == null) {
+        return name;
+      }
+      name = baseName + i++;
+    }
+  }
+
+  public void addListener(@NotNull ArtifactListener listener) {
+    myDispatcher.addListener(listener);
+  }
+
+  public void removeListener(@NotNull ArtifactListener listener) {
+    myDispatcher.addListener(listener);
+  }
+
+  public void removeArtifact(@NotNull Artifact artifact) {
+    final ArtifactImpl artifactImpl = (ArtifactImpl)artifact;
+    ArtifactImpl original = myModifiable2Original.remove(artifactImpl);
+    if (original != null) {
+      myOriginalArtifacts.remove(original);
+    }
+    else {
+      original = artifactImpl;
+    }
+    myArtifact2ModifiableCopy.remove(original);
+    myOriginalArtifacts.remove(original);
+    artifactsChanged();
+    myDispatcher.getMulticaster().artifactRemoved(original);
+  }
+
+  @NotNull
+  public ModifiableArtifact getOrCreateModifiableArtifact(@NotNull Artifact artifact) {
+    final ArtifactImpl artifactImpl = (ArtifactImpl)artifact;
+    if (myModifiable2Original.containsKey(artifactImpl)) {
+      return artifactImpl;
+    }
+
+    ArtifactImpl modifiableCopy = myArtifact2ModifiableCopy.get(artifactImpl);
+    if (modifiableCopy == null) {
+      modifiableCopy = artifactImpl.createCopy(myDispatcher);
+      myDispatcher.getMulticaster().artifactChanged(modifiableCopy, artifact.getName());
+      myArtifact2ModifiableCopy.put(artifactImpl, modifiableCopy);
+      myModifiable2Original.put(modifiableCopy, artifactImpl);
+      artifactsChanged();
+    }
+    return modifiableCopy;
+  }
+
+  @NotNull
+  public Artifact getOriginalArtifact(@NotNull Artifact artifact) {
+    final ArtifactImpl original = myModifiable2Original.get(artifact);
+    return original != null ? original : artifact;
+  }
+
+  @NotNull
+  public ArtifactImpl getArtifactByOriginal(@NotNull Artifact artifact) {
+    final ArtifactImpl artifactImpl = (ArtifactImpl)artifact;
+    final ArtifactImpl copy = myArtifact2ModifiableCopy.get(artifactImpl);
+    return copy != null ? copy : artifactImpl;
+  }
+
+  public boolean isModified() {
+    return !myOriginalArtifacts.equals(myArtifactManager.getArtifactsList()) || !myArtifact2ModifiableCopy.isEmpty();
+  }
+
+  public void commit() {
+    myArtifactManager.commit(this);
+  }
+
+  public void dispose() {
+    List<Artifact> artifacts = new ArrayList<Artifact>();
+    for (ArtifactImpl artifact : myModifiable2Original.keySet()) {
+      if (myModifiable2Original.get(artifact).equals(artifact)) {
+        artifacts.add(artifact);
+      }
+    }
+    ((ArtifactPointerManagerImpl)ArtifactPointerManager.getInstance(myArtifactManager.getProject())).disposePointers(artifacts);
+  }
+
+  @Nullable
+  public ArtifactImpl getModifiableCopy(Artifact artifact) {
+    //noinspection SuspiciousMethodCalls
+    return myArtifact2ModifiableCopy.get(artifact);
+  }
+
+  public List<ArtifactImpl> getOriginalArtifacts() {
+    return myOriginalArtifacts;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerImpl.java
new file mode 100644
index 0000000..b2b60bb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerImpl.java
@@ -0,0 +1,70 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactModel;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArtifactPointerImpl implements ArtifactPointer {
+  private String myName;
+  private Artifact myArtifact;
+
+  public ArtifactPointerImpl(@NotNull String name) {
+    myName = name;
+  }
+
+  public ArtifactPointerImpl(@NotNull Artifact artifact) {
+    myArtifact = artifact;
+    myName = artifact.getName();
+  }
+
+  @NotNull
+  public String getArtifactName() {
+    return myName;
+  }
+
+  public Artifact getArtifact() {
+    return myArtifact;
+  }
+
+  @NotNull
+  public String getArtifactName(@NotNull ArtifactModel artifactModel) {
+    if (myArtifact != null) {
+      return artifactModel.getArtifactByOriginal(myArtifact).getName();
+    }
+    return myName;
+  }
+
+  public Artifact findArtifact(@NotNull ArtifactModel artifactModel) {
+    if (myArtifact != null) {
+      return artifactModel.getArtifactByOriginal(myArtifact);
+    }
+    return artifactModel.findArtifact(myName);
+  }
+
+  void setArtifact(Artifact artifact) {
+    myArtifact = artifact;
+  }
+
+  void setName(String name) {
+    myName = name;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerManagerImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerManagerImpl.java
new file mode 100644
index 0000000..cc9d5db
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactPointerManagerImpl.java
@@ -0,0 +1,117 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.*;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public class ArtifactPointerManagerImpl extends ArtifactPointerManager {
+  private final Map<String, ArtifactPointerImpl> myUnresolvedPointers = new HashMap<String, ArtifactPointerImpl>();
+  private final Map<Artifact, ArtifactPointerImpl> myPointers = new HashMap<Artifact, ArtifactPointerImpl>();
+  private ArtifactManager myArtifactManager;
+
+  public ArtifactPointerManagerImpl(Project project) {
+    project.getMessageBus().connect().subscribe(ArtifactManager.TOPIC, new ArtifactAdapter() {
+      @Override
+      public void artifactRemoved(@NotNull Artifact artifact) {
+        disposePointer(artifact);
+      }
+
+      @Override
+      public void artifactAdded(@NotNull Artifact artifact) {
+        final ArtifactPointerImpl pointer = myPointers.get(artifact);
+        if (pointer != null) {
+          pointer.setName(artifact.getName());
+        }
+        
+        final ArtifactPointerImpl unresolved = myUnresolvedPointers.remove(artifact.getName());
+        if (unresolved != null) {
+          unresolved.setArtifact(artifact);
+          if (pointer == null) {
+            myPointers.put(artifact, unresolved);
+          }
+        }
+      }
+
+      @Override
+      public void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName) {
+        artifactAdded(artifact);
+      }
+    });
+  }
+
+  public void setArtifactManager(ArtifactManager artifactManager) {
+    myArtifactManager = artifactManager;
+  }
+
+  private void disposePointer(Artifact artifact) {
+    final ArtifactPointerImpl pointer = myPointers.remove(artifact);
+    if (pointer != null) {
+      pointer.setArtifact(null);
+      myUnresolvedPointers.put(pointer.getArtifactName(), pointer);
+    }
+  }
+
+  public ArtifactPointer createPointer(@NotNull String name) {
+    if (myArtifactManager != null) {
+      final Artifact artifact = myArtifactManager.findArtifact(name);
+      if (artifact != null) {
+        return createPointer(artifact);
+      }
+    }
+
+    ArtifactPointerImpl pointer = myUnresolvedPointers.get(name);
+    if (pointer == null) {
+      pointer = new ArtifactPointerImpl(name);
+      myUnresolvedPointers.put(name, pointer);
+    }
+    return pointer;
+  }
+
+  public ArtifactPointer createPointer(@NotNull Artifact artifact) {
+    ArtifactPointerImpl pointer = myPointers.get(artifact);
+    if (pointer == null) {
+      pointer = myUnresolvedPointers.get(artifact.getName());
+      if (pointer != null) {
+        pointer.setArtifact(artifact);
+      }
+      else {
+        pointer = new ArtifactPointerImpl(artifact);
+      }
+      myPointers.put(artifact, pointer);
+    }
+    return pointer;
+  }
+
+  @Override
+  public ArtifactPointer createPointer(@NotNull Artifact artifact, @NotNull ArtifactModel artifactModel) {
+    return createPointer(artifactModel.getOriginalArtifact(artifact));
+  }
+
+  public void disposePointers(List<Artifact> artifacts) {
+    for (Artifact artifact : artifacts) {
+      disposePointer(artifact);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtil.java
new file mode 100644
index 0000000..b3fe783
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtil.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactSortingUtil {
+  public static ArtifactSortingUtil getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, ArtifactSortingUtil.class);
+  }
+
+  public abstract Map<String, String> getArtifactToSelfIncludingNameMap();
+
+  public abstract List<String> getArtifactsSortedByInclusion();
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtilImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtilImpl.java
new file mode 100644
index 0000000..e06f9de
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactSortingUtilImpl.java
@@ -0,0 +1,176 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ArtifactElementType;
+import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.graph.CachingSemiGraph;
+import com.intellij.util.graph.DFSTBuilder;
+import com.intellij.util.graph.GraphGenerator;
+import gnu.trove.TIntArrayList;
+import gnu.trove.TIntProcedure;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactSortingUtilImpl extends ArtifactSortingUtil {
+  private final Project myProject;
+  private CachedValue<Map<String, String>> myArtifactToSelfIncludingName;
+  private CachedValue<List<String>> mySortedArtifacts;
+
+  public ArtifactSortingUtilImpl(Project project) {
+    myProject = project;
+  }
+
+  @Override
+  public Map<String, String> getArtifactToSelfIncludingNameMap() {
+    if (myArtifactToSelfIncludingName == null) {
+      myArtifactToSelfIncludingName = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<Map<String, String>>() {
+        public Result<Map<String, String>> compute() {
+          return Result.create(computeArtifactToSelfIncludingNameMap(), ArtifactManager.getInstance(myProject).getModificationTracker());
+        }
+      }, false);
+    }
+    return myArtifactToSelfIncludingName.getValue();
+  }
+
+  @Override
+  public List<String> getArtifactsSortedByInclusion() {
+    if (mySortedArtifacts == null) {
+      mySortedArtifacts = CachedValuesManager.getManager(myProject).createCachedValue(new CachedValueProvider<List<String>>() {
+          @Override
+          public Result<List<String>> compute() {
+            return Result.create(doGetSortedArtifacts(), ArtifactManager.getInstance(myProject).getModificationTracker());
+          }
+        }, false);
+    }
+    return mySortedArtifacts.getValue();
+  }
+
+  private List<String> doGetSortedArtifacts() {
+    GraphGenerator<String> graph = createArtifactsGraph();
+    DFSTBuilder<String> builder = new DFSTBuilder<String>(graph);
+    builder.buildDFST();
+    List<String> names = new ArrayList<String>();
+    names.addAll(graph.getNodes());
+    Collections.sort(names, builder.comparator());
+    return names;
+  }
+
+  private Map<String, String> computeArtifactToSelfIncludingNameMap() {
+    final Map<String, String> result = new HashMap<String, String>();
+    final GraphGenerator<String> graph = createArtifactsGraph();
+    for (String artifactName : graph.getNodes()) {
+      final Iterator<String> in = graph.getIn(artifactName);
+      while (in.hasNext()) {
+        String next = in.next();
+        if (next.equals(artifactName)) {
+          result.put(artifactName, artifactName);
+          break;
+        }
+      }
+    }
+
+    final DFSTBuilder<String> builder = new DFSTBuilder<String>(graph);
+    builder.buildDFST();
+    if (builder.isAcyclic() && result.isEmpty()) return Collections.emptyMap();
+
+    final TIntArrayList sccs = builder.getSCCs();
+    sccs.forEach(new TIntProcedure() {
+      int myTNumber = 0;
+      public boolean execute(int size) {
+        if (size > 1) {
+          for (int j = 0; j < size; j++) {
+            final String artifactName = builder.getNodeByTNumber(myTNumber + j);
+            result.put(artifactName, artifactName);
+          }
+        }
+        myTNumber += size;
+        return true;
+      }
+    });
+
+    for (int i = 0; i < graph.getNodes().size(); i++) {
+      final String artifactName = builder.getNodeByTNumber(i);
+      if (!result.containsKey(artifactName)) {
+        final Iterator<String> in = graph.getIn(artifactName);
+        while (in.hasNext()) {
+          final String name = result.get(in.next());
+          if (name != null) {
+            result.put(artifactName, name);
+          }
+        }
+      }
+    }
+
+    return result;
+  }
+
+  private GraphGenerator<String> createArtifactsGraph() {
+    final ArtifactManager artifactManager = ArtifactManager.getInstance(myProject);
+    return GraphGenerator.create(CachingSemiGraph.create(new ArtifactsGraph(artifactManager)));
+  }
+
+  private class ArtifactsGraph implements GraphGenerator.SemiGraph<String> {
+    private final ArtifactManager myArtifactManager;
+    private final Set<String> myArtifactNames;
+
+    public ArtifactsGraph(ArtifactManager artifactManager) {
+      myArtifactManager = artifactManager;
+      myArtifactNames = new LinkedHashSet<String>();
+      for (Artifact artifact : myArtifactManager.getSortedArtifacts()) {
+        myArtifactNames.add(artifact.getName());
+      }
+    }
+
+    @Override
+    public Collection<String> getNodes() {
+      return myArtifactNames;
+    }
+
+    @Override
+    public Iterator<String> getIn(String name) {
+      final Set<String> included = new LinkedHashSet<String>();
+      final PackagingElementResolvingContext context = myArtifactManager.getResolvingContext();
+      final Artifact artifact = context.getArtifactModel().findArtifact(name);
+      if (artifact != null) {
+        ArtifactUtil.processPackagingElements(artifact, ArtifactElementType.ARTIFACT_ELEMENT_TYPE, new PackagingElementProcessor<ArtifactPackagingElement>() {
+          @Override
+          public boolean process(@NotNull ArtifactPackagingElement element,
+                                 @NotNull PackagingElementPath path) {
+            final String artifactName = element.getArtifactName();
+            if (myArtifactNames.contains(artifactName)) {
+              included.add(artifactName);
+            }
+            return true;
+          }
+        }, context, false);
+      }
+      return included.iterator();
+    }
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java
new file mode 100644
index 0000000..0a272e8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactUtil.java
@@ -0,0 +1,565 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerProjectExtension;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ArtifactProperties;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.elements.*;
+import com.intellij.util.PathUtil;
+import com.intellij.util.Processor;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FList;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactUtil {
+  private ArtifactUtil() {
+  }
+
+  public static CompositePackagingElement<?> copyFromRoot(@NotNull CompositePackagingElement<?> oldRoot, @NotNull Project project) {
+    final CompositePackagingElement<?> newRoot = (CompositePackagingElement<?>)copyElement(oldRoot, project);
+    copyChildren(oldRoot, newRoot, project);
+    return newRoot;
+  }
+
+
+  public static void copyChildren(CompositePackagingElement<?> oldParent, CompositePackagingElement<?> newParent, @NotNull Project project) {
+    for (PackagingElement<?> child : oldParent.getChildren()) {
+      newParent.addOrFindChild(copyWithChildren(child, project));
+    }
+  }
+
+  @NotNull
+  public static <S> PackagingElement<S> copyWithChildren(@NotNull PackagingElement<S> element, @NotNull Project project) {
+    final PackagingElement<S> copy = copyElement(element, project);
+    if (element instanceof CompositePackagingElement<?>) {
+      copyChildren((CompositePackagingElement<?>)element, (CompositePackagingElement<?>)copy, project);
+    }
+    return copy;
+  }
+
+  @NotNull
+  private static <S> PackagingElement<S> copyElement(@NotNull PackagingElement<S> element, @NotNull Project project) {
+    //noinspection unchecked
+    final PackagingElement<S> copy = (PackagingElement<S>)element.getType().createEmpty(project);
+    copy.loadState(element.getState());
+    return copy;
+  }
+
+  public static <E extends PackagingElement<?>> boolean processPackagingElements(@NotNull Artifact artifact, @Nullable PackagingElementType<E> type,
+                                                                                 @NotNull final Processor<? super E> processor,
+                                                                                 final @NotNull PackagingElementResolvingContext resolvingContext,
+                                                                                 final boolean processSubstitutions) {
+    return processPackagingElements(artifact, type, new PackagingElementProcessor<E>() {
+      @Override
+      public boolean process(@NotNull E e, @NotNull PackagingElementPath path) {
+        return processor.process(e);
+      }
+    }, resolvingContext, processSubstitutions);
+  }
+
+  public static <E extends PackagingElement<?>> boolean processPackagingElements(@NotNull Artifact artifact, @Nullable PackagingElementType<E> type,
+                                                                                 @NotNull PackagingElementProcessor<? super E> processor,
+                                                                                 final @NotNull PackagingElementResolvingContext resolvingContext,
+                                                                                 final boolean processSubstitutions) {
+    return processPackagingElements(artifact.getRootElement(), type, processor, resolvingContext, processSubstitutions, artifact.getArtifactType());
+  }
+
+  public static <E extends PackagingElement<?>> boolean processPackagingElements(final PackagingElement<?> rootElement, @Nullable PackagingElementType<E> type,
+                                                                                 @NotNull PackagingElementProcessor<? super E> processor,
+                                                                                 final @NotNull PackagingElementResolvingContext resolvingContext,
+                                                                                 final boolean processSubstitutions,
+                                                                                 final ArtifactType artifactType) {
+    return processElementRecursively(rootElement, type, processor, resolvingContext, processSubstitutions, artifactType,
+                          PackagingElementPath.EMPTY, new HashSet<PackagingElement<?>>());
+  }
+
+  private static <E extends PackagingElement<?>> boolean processElementsRecursively(final List<? extends PackagingElement<?>> elements,
+                                                                         @Nullable PackagingElementType<E> type,
+                                                                         @NotNull PackagingElementProcessor<? super E> processor,
+                                                                         final @NotNull PackagingElementResolvingContext resolvingContext,
+                                                                         final boolean processSubstitutions, ArtifactType artifactType,
+                                                                         @NotNull PackagingElementPath path,
+                                                                         Set<PackagingElement<?>> processed) {
+    for (PackagingElement<?> element : elements) {
+      if (!processElementRecursively(element, type, processor, resolvingContext, processSubstitutions, artifactType, path, processed)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  private static <E extends PackagingElement<?>> boolean processElementRecursively(@NotNull PackagingElement<?> element, @Nullable PackagingElementType<E> type,
+                                                                         @NotNull PackagingElementProcessor<? super E> processor,
+                                                                         @NotNull PackagingElementResolvingContext resolvingContext,
+                                                                         final boolean processSubstitutions,
+                                                                         ArtifactType artifactType,
+                                                                         @NotNull PackagingElementPath path, Set<PackagingElement<?>> processed) {
+    if (!processor.shouldProcess(element) || !processed.add(element)) {
+      return true;
+    }
+    if (type == null || element.getType().equals(type)) {
+      if (!processor.process((E)element, path)) {
+        return false;
+      }
+    }
+    if (element instanceof CompositePackagingElement<?>) {
+      final CompositePackagingElement<?> composite = (CompositePackagingElement<?>)element;
+      return processElementsRecursively(composite.getChildren(), type, processor, resolvingContext, processSubstitutions, artifactType,
+                             path.appendComposite(composite), processed);
+    }
+    else if (element instanceof ComplexPackagingElement<?> && processSubstitutions) {
+      final ComplexPackagingElement<?> complexElement = (ComplexPackagingElement<?>)element;
+      if (processor.shouldProcessSubstitution(complexElement)) {
+        final List<? extends PackagingElement<?>> substitution = complexElement.getSubstitution(resolvingContext, artifactType);
+        if (substitution != null) {
+          return processElementsRecursively(substitution, type, processor, resolvingContext, processSubstitutions, artifactType,
+                                 path.appendComplex(complexElement), processed);
+        }
+      }
+    }
+    return true;
+  }
+
+  public static void removeDuplicates(@NotNull CompositePackagingElement<?> parent) {
+    List<PackagingElement<?>> prevChildren = new ArrayList<PackagingElement<?>>();
+
+    List<PackagingElement<?>> toRemove = new ArrayList<PackagingElement<?>>();
+    for (PackagingElement<?> child : parent.getChildren()) {
+      if (child instanceof CompositePackagingElement<?>) {
+        removeDuplicates((CompositePackagingElement<?>)child);
+      }
+      boolean merged = false;
+      for (PackagingElement<?> prevChild : prevChildren) {
+        if (child.isEqualTo(prevChild)) {
+          if (child instanceof CompositePackagingElement<?>) {
+            for (PackagingElement<?> childElement : ((CompositePackagingElement<?>)child).getChildren()) {
+              ((CompositePackagingElement<?>)prevChild).addOrFindChild(childElement);
+            }
+          }
+          merged = true;
+          break;
+        }
+      }
+      if (merged) {
+        toRemove.add(child);
+      }
+      else {
+        prevChildren.add(child);
+      }
+    }
+
+    for (PackagingElement<?> child : toRemove) {
+      parent.removeChild(child);
+    }
+  }
+
+  public static <S> void copyProperties(ArtifactProperties<?> from, ArtifactProperties<S> to) {
+    //noinspection unchecked
+    to.loadState((S)from.getState());
+  }
+
+  @Nullable
+  public static String getDefaultArtifactOutputPath(@NotNull String artifactName, final @NotNull Project project) {
+    final CompilerProjectExtension extension = CompilerProjectExtension.getInstance(project);
+    if (extension == null) return null;
+    String outputUrl = extension.getCompilerOutputUrl();
+    if (outputUrl == null || outputUrl.length() == 0) {
+      final VirtualFile baseDir = project.getBaseDir();
+      if (baseDir == null) return null;
+      outputUrl = baseDir.getUrl() + "/out";
+    }
+    return VfsUtil.urlToPath(outputUrl) + "/artifacts/" + FileUtil.sanitizeFileName(artifactName);
+  }
+
+  public static <E extends PackagingElement<?>> boolean processElementsWithSubstitutions(@NotNull List<? extends PackagingElement<?>> elements,
+                                        @NotNull PackagingElementResolvingContext context,
+                                        @NotNull ArtifactType artifactType,
+                                        @NotNull PackagingElementPath parentPath,
+                                        @NotNull PackagingElementProcessor<E> processor) {
+    return processElementsWithSubstitutions(elements, context, artifactType, parentPath, processor, new HashSet<PackagingElement<?>>());
+  }
+
+  private static <E extends PackagingElement<?>> boolean processElementsWithSubstitutions(@NotNull List<? extends PackagingElement<?>> elements,
+                                                                                         @NotNull PackagingElementResolvingContext context,
+                                                                                         @NotNull ArtifactType artifactType,
+                                                                                         @NotNull PackagingElementPath parentPath,
+                                                                                         @NotNull PackagingElementProcessor<E> processor,
+                                                                                         final Set<PackagingElement<?>> processed) {
+    for (PackagingElement<?> element : elements) {
+      if (!processed.add(element)) {
+        continue;
+      }
+
+      if (element instanceof ComplexPackagingElement<?> && processor.shouldProcessSubstitution((ComplexPackagingElement)element)) {
+        final ComplexPackagingElement<?> complexElement = (ComplexPackagingElement<?>)element;
+        final List<? extends PackagingElement<?>> substitution = complexElement.getSubstitution(context, artifactType);
+        if (substitution != null &&
+            !processElementsWithSubstitutions(substitution, context, artifactType, parentPath.appendComplex(complexElement), processor, processed)) {
+          return false;
+        }
+      }
+      else if (!processor.process((E)element, parentPath)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static List<PackagingElement<?>> findByRelativePath(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath,
+                                                             @NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType) {
+    final List<PackagingElement<?>> result = new ArrayList<PackagingElement<?>>();
+    processElementsByRelativePath(parent, relativePath, context, artifactType, PackagingElementPath.EMPTY, new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> packagingElement, @NotNull PackagingElementPath path) {
+        result.add(packagingElement);
+        return true;
+      }
+    });
+    return result;
+  }
+
+  public static boolean processElementsByRelativePath(@NotNull final CompositePackagingElement<?> parent, @NotNull String relativePath,
+                                                       @NotNull final PackagingElementResolvingContext context, @NotNull final ArtifactType artifactType,
+                                                       @NotNull PackagingElementPath parentPath,
+                                                       @NotNull final PackagingElementProcessor<PackagingElement<?>> processor) {
+    relativePath = StringUtil.trimStart(relativePath, "/");
+    if (relativePath.length() == 0) {
+      return true;
+    }
+
+    int i = relativePath.indexOf('/');
+    final String firstName = i != -1 ? relativePath.substring(0, i) : relativePath;
+    final String tail = i != -1 ? relativePath.substring(i+1) : "";
+
+    return processElementsWithSubstitutions(parent.getChildren(), context, artifactType, parentPath.appendComposite(parent), new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+        boolean process = false;
+        if (element instanceof CompositePackagingElement && firstName.equals(((CompositePackagingElement<?>)element).getName())) {
+          process = true;
+        }
+        else if (element instanceof FileCopyPackagingElement) {
+          final FileCopyPackagingElement fileCopy = (FileCopyPackagingElement)element;
+          if (firstName.equals(fileCopy.getOutputFileName())) {
+            process = true;
+          }
+        }
+        
+        if (process) {
+          if (tail.length() == 0) {
+            if (!processor.process(element, path)) return false;
+          }
+          else if (element instanceof CompositePackagingElement<?>) {
+            return processElementsByRelativePath((CompositePackagingElement)element, tail, context, artifactType, path, processor);
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  public static boolean processDirectoryChildren(@NotNull CompositePackagingElement<?> parent,
+                                                 @NotNull PackagingElementPath pathToParent,
+                                                 @NotNull String relativePath,
+                                                 @NotNull final PackagingElementResolvingContext context,
+                                                 @NotNull final ArtifactType artifactType,
+                                                 @NotNull final PackagingElementProcessor<PackagingElement<?>> processor) {
+    return processElementsByRelativePath(parent, relativePath, context, artifactType, pathToParent, new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+        if (element instanceof DirectoryPackagingElement) {
+          final List<PackagingElement<?>> children = ((DirectoryPackagingElement)element).getChildren();
+          if (!processElementsWithSubstitutions(children, context, artifactType, path.appendComposite((DirectoryPackagingElement)element), processor)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  public static void processFileOrDirectoryCopyElements(Artifact artifact,
+                                                         PackagingElementProcessor<FileOrDirectoryCopyPackagingElement<?>> processor,
+                                                         PackagingElementResolvingContext context,
+                                                         boolean processSubstitutions) {
+    processPackagingElements(artifact, PackagingElementFactoryImpl.FILE_COPY_ELEMENT_TYPE, processor, context, processSubstitutions);
+    processPackagingElements(artifact, PackagingElementFactoryImpl.DIRECTORY_COPY_ELEMENT_TYPE, processor, context, processSubstitutions);
+    processPackagingElements(artifact, PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE, processor, context, processSubstitutions);
+  }
+
+  public static Collection<Trinity<Artifact, PackagingElementPath, String>> findContainingArtifactsWithOutputPaths(@NotNull final VirtualFile file,
+                                                                                                                   @NotNull Project project,
+                                                                                                                   final Artifact[] artifacts) {
+    final boolean isResourceFile = CompilerConfiguration.getInstance(project).isResourceFile(file);
+    final List<Trinity<Artifact, PackagingElementPath, String>> result = new ArrayList<Trinity<Artifact, PackagingElementPath, String>>();
+    final PackagingElementResolvingContext context = ArtifactManager.getInstance(project).getResolvingContext();
+    for (final Artifact artifact : artifacts) {
+      processPackagingElements(artifact, null, new PackagingElementProcessor<PackagingElement<?>>() {
+        @Override
+        public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+          if (element instanceof FileOrDirectoryCopyPackagingElement<?>) {
+            final VirtualFile root = ((FileOrDirectoryCopyPackagingElement)element).findFile();
+            if (root != null && VfsUtil.isAncestor(root, file, false)) {
+              final String relativePath;
+              if (root.equals(file) && element instanceof FileCopyPackagingElement) {
+                relativePath = ((FileCopyPackagingElement)element).getOutputFileName();
+              }
+              else {
+                relativePath = VfsUtilCore.getRelativePath(file, root, '/');
+              }
+              result.add(Trinity.create(artifact, path, relativePath));
+              return false;
+            }
+          }
+          else if (isResourceFile && element instanceof ModuleOutputPackagingElement) {
+            final String relativePath = getRelativePathInSources(file, (ModuleOutputPackagingElement)element, context);
+            if (relativePath != null) {
+              result.add(Trinity.create(artifact, path, relativePath));
+              return false;
+            }
+          }
+          return true;
+        }
+      }, context, true);
+    }
+    return result;
+  }
+
+  @Nullable
+  private static String getRelativePathInSources(@NotNull VirtualFile file, final @NotNull ModuleOutputPackagingElement moduleElement,
+                                                @NotNull PackagingElementResolvingContext context) {
+    for (VirtualFile sourceRoot : moduleElement.getSourceRoots(context)) {
+      if (VfsUtil.isAncestor(sourceRoot, file, true)) {
+        return VfsUtilCore.getRelativePath(file, sourceRoot, '/');
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  public static VirtualFile findSourceFileByOutputPath(Artifact artifact, String outputPath, PackagingElementResolvingContext context) {
+    final List<VirtualFile> files = findSourceFilesByOutputPath(artifact.getRootElement(), outputPath, context, artifact.getArtifactType());
+    return files.isEmpty() ? null : files.get(0);
+  }
+
+  @Nullable
+  public static VirtualFile findSourceFileByOutputPath(CompositePackagingElement<?> parent, String outputPath,
+                                                 PackagingElementResolvingContext context, ArtifactType artifactType) {
+    final List<VirtualFile> files = findSourceFilesByOutputPath(parent, outputPath, context, artifactType);
+    return files.isEmpty() ? null : files.get(0);
+  }
+
+  public static List<VirtualFile> findSourceFilesByOutputPath(CompositePackagingElement<?> parent, final String outputPath,
+                                                              final PackagingElementResolvingContext context, final ArtifactType artifactType) {
+    final String path = StringUtil.trimStart(outputPath, "/");
+    if (path.length() == 0) {
+      return Collections.emptyList();
+    }
+
+    int i = path.indexOf('/');
+    final String firstName = i != -1 ? path.substring(0, i) : path;
+    final String tail = i != -1 ? path.substring(i+1) : "";
+
+    final List<VirtualFile> result = new SmartList<VirtualFile>();
+    processElementsWithSubstitutions(parent.getChildren(), context, artifactType, PackagingElementPath.EMPTY, new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath elementPath) {
+        //todo[nik] replace by method findSourceFile() in PackagingElement
+        if (element instanceof CompositePackagingElement) {
+          final CompositePackagingElement<?> compositeElement = (CompositePackagingElement<?>)element;
+          if (firstName.equals(compositeElement.getName())) {
+            result.addAll(findSourceFilesByOutputPath(compositeElement, tail, context, artifactType));
+          }
+        }
+        else if (element instanceof FileCopyPackagingElement) {
+          final FileCopyPackagingElement fileCopyElement = (FileCopyPackagingElement)element;
+          if (firstName.equals(fileCopyElement.getOutputFileName()) && tail.length() == 0) {
+            ContainerUtil.addIfNotNull(fileCopyElement.findFile(), result);
+          }
+        }
+        else if (element instanceof DirectoryCopyPackagingElement || element instanceof ExtractedDirectoryPackagingElement) {
+          final VirtualFile sourceRoot = ((FileOrDirectoryCopyPackagingElement<?>)element).findFile();
+          if (sourceRoot != null) {
+            ContainerUtil.addIfNotNull(sourceRoot.findFileByRelativePath(path), result);
+          }
+        }
+        else if (element instanceof ModuleOutputPackagingElement) {
+          final CompilerConfiguration compilerConfiguration = CompilerConfiguration.getInstance(context.getProject());
+          for (VirtualFile sourceRoot : ((ModuleOutputPackagingElement)element).getSourceRoots(context)) {
+            final VirtualFile sourceFile = sourceRoot.findFileByRelativePath(path);
+            if (sourceFile != null && compilerConfiguration.isResourceFile(sourceFile)) {
+              result.add(sourceFile);
+            }
+          }
+        }
+        return true;
+      }
+    });
+
+    return result;
+  }
+
+  public static boolean processParents(@NotNull Artifact artifact,
+                                       @NotNull PackagingElementResolvingContext context,
+                                       @NotNull ParentElementProcessor processor,
+                                       int maxLevel) {
+    return processParents(artifact, context, processor, FList.<Pair<Artifact, CompositePackagingElement<?>>>emptyList(), maxLevel,
+                          new HashSet<Artifact>());
+  }
+
+  private static boolean processParents(@NotNull final Artifact artifact, @NotNull final PackagingElementResolvingContext context,
+                                        @NotNull final ParentElementProcessor processor, FList<Pair<Artifact, CompositePackagingElement<?>>> pathToElement,
+                                        final int maxLevel, final Set<Artifact> processed) {
+    if (!processed.add(artifact)) return true;
+
+    final FList<Pair<Artifact, CompositePackagingElement<?>>> pathFromRoot;
+    final CompositePackagingElement<?> rootElement = artifact.getRootElement();
+    if (rootElement instanceof ArtifactRootElement<?>) {
+      pathFromRoot = pathToElement;
+    }
+    else {
+      if (!processor.process(rootElement, pathToElement, artifact)) {
+        return false;
+      }
+      pathFromRoot = pathToElement.prepend(new Pair<Artifact, CompositePackagingElement<?>>(artifact, rootElement));
+    }
+    if (pathFromRoot.size() > maxLevel) return true;
+
+    for (final Artifact anArtifact : context.getArtifactModel().getArtifacts()) {
+      if (processed.contains(anArtifact)) continue;
+
+      final PackagingElementProcessor<ArtifactPackagingElement> elementProcessor =
+          new PackagingElementProcessor<ArtifactPackagingElement>() {
+            @Override
+            public boolean shouldProcessSubstitution(ComplexPackagingElement<?> element) {
+              return !(element instanceof ArtifactPackagingElement);
+            }
+
+            @Override
+            public boolean process(@NotNull ArtifactPackagingElement element, @NotNull PackagingElementPath path) {
+              if (artifact.getName().equals(element.getArtifactName())) {
+                FList<Pair<Artifact, CompositePackagingElement<?>>> currentPath = pathFromRoot;
+                final List<CompositePackagingElement<?>> parents = path.getParents();
+                for (int i = 0, parentsSize = parents.size(); i < parentsSize - 1; i++) {
+                  CompositePackagingElement<?> parent = parents.get(i);
+                  if (!processor.process(parent, currentPath, anArtifact)) {
+                    return false;
+                  }
+                  currentPath = currentPath.prepend(new Pair<Artifact, CompositePackagingElement<?>>(anArtifact, parent));
+                  if (currentPath.size() > maxLevel) {
+                    return true;
+                  }
+                }
+
+                if (!parents.isEmpty()) {
+                  CompositePackagingElement<?> lastParent = parents.get(parents.size() - 1);
+                  if (lastParent instanceof ArtifactRootElement<?> && !processor.process(lastParent, currentPath, anArtifact)) {
+                    return false;
+                  }
+                }
+                return processParents(anArtifact, context, processor, currentPath, maxLevel, processed);
+              }
+              return true;
+            }
+          };
+      if (!processPackagingElements(anArtifact, ArtifactElementType.ARTIFACT_ELEMENT_TYPE, elementProcessor, context, true)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public static boolean isArchiveName(String name) {
+    return name.length() >= 4 && name.charAt(name.length() - 4) == '.' && StringUtil.endsWithIgnoreCase(name, "ar");
+  }
+
+  public static void removeChildrenRecursively(@NotNull CompositePackagingElement<?> element, @NotNull Condition<PackagingElement<?>> condition) {
+    List<PackagingElement<?>> toRemove = new ArrayList<PackagingElement<?>>();
+    for (PackagingElement<?> child : element.getChildren()) {
+      if (child instanceof CompositePackagingElement<?>) {
+        final CompositePackagingElement<?> compositeChild = (CompositePackagingElement<?>)child;
+        removeChildrenRecursively(compositeChild, condition);
+        if (compositeChild.getChildren().isEmpty()) {
+          toRemove.add(child);
+        }
+      }
+      else if (condition.value(child)) {
+        toRemove.add(child);
+      }
+    }
+
+    element.removeChildren(toRemove);
+  }
+
+  public static boolean shouldClearArtifactOutputBeforeRebuild(Artifact artifact) {
+    final String outputPath = artifact.getOutputPath();
+    return !StringUtil.isEmpty(outputPath) && artifact.getRootElement() instanceof ArtifactRootElement<?>;
+  }
+
+  public static Set<Module> getModulesIncludedInArtifacts(final @NotNull Collection<? extends Artifact> artifacts, final @NotNull Project project) {
+    final Set<Module> modules = new HashSet<Module>();
+    final PackagingElementResolvingContext resolvingContext = ArtifactManager.getInstance(project).getResolvingContext();
+    for (Artifact artifact : artifacts) {
+      processPackagingElements(artifact, null, new Processor<PackagingElement<?>>() {
+        @Override
+        public boolean process(PackagingElement<?> element) {
+          if (element instanceof ModuleOutputPackagingElement) {
+            ContainerUtil.addIfNotNull(modules, ((ModuleOutputPackagingElement)element).findModule(resolvingContext));
+          }
+          return true;
+        }
+      }, resolvingContext, true);
+    }
+    return modules;
+  }
+
+  public static List<Artifact> getArtifactWithOutputPaths(Project project) {
+    final List<Artifact> result = new ArrayList<Artifact>();
+    for (Artifact artifact : ArtifactManager.getInstance(project).getSortedArtifacts()) {
+      if (!StringUtil.isEmpty(artifact.getOutputPath())) {
+        result.add(artifact);
+      }
+    }
+    return result;
+  }
+
+  public static String suggestArtifactFileName(String artifactName) {
+    return PathUtil.suggestFileName(artifactName, true, true);
+  }
+}
+
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java
new file mode 100644
index 0000000..641bae7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ArtifactVirtualFileListener.java
@@ -0,0 +1,109 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.MultiValuesMap;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileAdapter;
+import com.intellij.openapi.vfs.VirtualFileMoveEvent;
+import com.intellij.openapi.vfs.VirtualFilePropertyEvent;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public class ArtifactVirtualFileListener extends VirtualFileAdapter {
+  private final CachedValue<MultiValuesMap<String, Artifact>> myParentPathsToArtifacts;
+  private final ArtifactManagerImpl myArtifactManager;
+
+  public ArtifactVirtualFileListener(Project project, final ArtifactManagerImpl artifactManager) {
+    myArtifactManager = artifactManager;
+    myParentPathsToArtifacts =
+      CachedValuesManager.getManager(project).createCachedValue(new CachedValueProvider<MultiValuesMap<String, Artifact>>() {
+        public Result<MultiValuesMap<String, Artifact>> compute() {
+          MultiValuesMap<String, Artifact> result = computeParentPathToArtifactMap();
+          return Result.createSingleDependency(result, artifactManager.getModificationTracker());
+        }
+      }, false);
+  }
+
+  private MultiValuesMap<String, Artifact> computeParentPathToArtifactMap() {
+    final MultiValuesMap<String, Artifact> result = new MultiValuesMap<String, Artifact>();
+    for (final Artifact artifact : myArtifactManager.getArtifacts()) {
+      ArtifactUtil.processFileOrDirectoryCopyElements(artifact, new PackagingElementProcessor<FileOrDirectoryCopyPackagingElement<?>>() {
+        @Override
+        public boolean process(@NotNull FileOrDirectoryCopyPackagingElement<?> element, @NotNull PackagingElementPath pathToElement) {
+          String path = element.getFilePath();
+          while (path.length() > 0) {
+            result.put(path, artifact);
+            path = PathUtil.getParentPath(path);
+          }
+          return true;
+        }
+      }, myArtifactManager.getResolvingContext(), false);
+    }
+    return result;
+  }
+
+
+  @Override
+  public void fileMoved(VirtualFileMoveEvent event) {
+    final String oldPath = event.getOldParent().getPath() + "/" + event.getFileName();
+    filePathChanged(oldPath, event.getNewParent().getPath() + "/" + event.getFileName());
+  }
+
+  private void filePathChanged(@NotNull final String oldPath, @NotNull final String newPath) {
+    final Collection<Artifact> artifacts = myParentPathsToArtifacts.getValue().get(oldPath);
+    if (artifacts != null) {
+      final ModifiableArtifactModel model = myArtifactManager.createModifiableModel();
+      for (Artifact artifact : artifacts) {
+        final Artifact copy = model.getOrCreateModifiableArtifact(artifact);
+        ArtifactUtil.processFileOrDirectoryCopyElements(copy, new PackagingElementProcessor<FileOrDirectoryCopyPackagingElement<?>>() {
+          @Override
+          public boolean process(@NotNull FileOrDirectoryCopyPackagingElement<?> element, @NotNull PackagingElementPath pathToElement) {
+            final String path = element.getFilePath();
+            if (FileUtil.startsWith(path, oldPath)) {
+              element.setFilePath(newPath + path.substring(oldPath.length()));
+            }
+            return true;
+          }
+        }, myArtifactManager.getResolvingContext(), false);
+      }
+      model.commit();
+    }
+  }
+
+  @Override
+  public void propertyChanged(VirtualFilePropertyEvent event) {
+    if (VirtualFile.PROP_NAME.equals(event.getPropertyName())) {
+      final VirtualFile parent = event.getParent();
+      if (parent != null) {
+        filePathChanged(parent.getPath() + "/" + event.getOldValue(), parent.getPath() + "/" + event.getNewValue());
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java
new file mode 100644
index 0000000..c80617b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultManifestFileProvider.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.ManifestFileProvider;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import com.intellij.packaging.ui.ManifestFileConfiguration;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+* @author nik
+*/
+public class DefaultManifestFileProvider implements ManifestFileProvider {
+  private final PackagingElementResolvingContext myContext;
+
+  public DefaultManifestFileProvider(PackagingElementResolvingContext context) {
+    myContext = context;
+  }
+
+  @Override
+  public List<String> getClasspathFromManifest(@NotNull CompositePackagingElement<?> archiveRoot, @NotNull ArtifactType artifactType) {
+    final VirtualFile manifestFile = ManifestFileUtil.findManifestFile(archiveRoot, myContext, artifactType);
+    if (manifestFile == null) {
+      return null;
+    }
+
+    ManifestFileConfiguration configuration = ManifestFileUtil.createManifestFileConfiguration(manifestFile);
+    return configuration.getClasspath();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java
new file mode 100644
index 0000000..16000b4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/DefaultPackagingElementResolvingContext.java
@@ -0,0 +1,80 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.facet.impl.DefaultFacetsProvider;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ArtifactModel;
+import com.intellij.packaging.elements.ManifestFileProvider;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+* @author nik
+*/
+public class DefaultPackagingElementResolvingContext implements PackagingElementResolvingContext {
+  private final Project myProject;
+  private final DefaultModulesProvider myModulesProvider;
+
+  public DefaultPackagingElementResolvingContext(Project project) {
+    myProject = project;
+    myModulesProvider = new DefaultModulesProvider(myProject);
+  }
+
+  @NotNull
+  public Project getProject() {
+    return myProject;
+  }
+
+  @NotNull
+  public ArtifactModel getArtifactModel() {
+    return ArtifactManager.getInstance(myProject);
+  }
+
+  @NotNull
+  public ModulesProvider getModulesProvider() {
+    return myModulesProvider;
+  }
+
+  @NotNull
+  public FacetsProvider getFacetsProvider() {
+    return DefaultFacetsProvider.INSTANCE;
+  }
+
+  public Library findLibrary(@NotNull String level, @NotNull String libraryName) {
+    return findLibrary(myProject, level, libraryName);
+  }
+
+  @NotNull
+  @Override
+  public ManifestFileProvider getManifestFileProvider() {
+    return new DefaultManifestFileProvider(this);
+  }
+
+  @Nullable
+  public static Library findLibrary(Project project, String level, String libraryName) {
+    LibraryTable table = LibraryTablesRegistrar.getInstance().getLibraryTableByLevel(level, project);
+    return table != null ? table.getLibraryByName(libraryName) : null;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java
new file mode 100644
index 0000000..c6df02e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifact.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.elements.PackagingElementFactory;
+import org.jetbrains.jps.model.serialization.artifact.ArtifactState;
+
+/**
+ * @author nik
+ */
+public class InvalidArtifact extends ArtifactImpl {
+  private ArtifactState myState;
+  private final String myErrorMessage;
+
+  public InvalidArtifact(ArtifactState state, String errorMessage) {
+    super(state.getName(), InvalidArtifactType.getInstance(), false, PackagingElementFactory.getInstance().createArtifactRootElement(), "");
+    myState = state;
+    myErrorMessage = errorMessage;
+  }
+
+  public String getErrorMessage() {
+    return myErrorMessage;
+  }
+
+  public ArtifactState getState() {
+    return myState;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java
new file mode 100644
index 0000000..30a0010
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/InvalidArtifactType.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class InvalidArtifactType extends ArtifactType {
+
+  public static InvalidArtifactType getInstance() {
+    return ServiceManager.getService(InvalidArtifactType.class);
+  }
+
+  public InvalidArtifactType() {
+    super("invalid", "Invalid");
+  }
+
+  @NotNull
+  @Override
+  public Icon getIcon() {
+    return AllIcons.FileTypes.Unknown;
+  }
+
+  @Override
+  public String getDefaultPathFor(@NotNull PackagingElementOutputKind kind) {
+    return "";
+  }
+
+  @NotNull
+  @Override
+  public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+    return PackagingElementFactory.getInstance().createArtifactRootElement();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.form b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.form
new file mode 100644
index 0000000..eed2b88
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.form
@@ -0,0 +1,112 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.packaging.impl.artifacts.JarArtifactFromModulesDialog">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="7" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="0" left="0" bottom="0" right="0"/>
+    <constraints>
+      <xy x="20" y="20" width="521" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <component id="c89c9" class="javax.swing.JLabel" binding="myMainClassLabel">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="Main &amp;Class:"/>
+        </properties>
+      </component>
+      <vspacer id="8cb38">
+        <constraints>
+          <grid row="6" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <component id="535a8" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myMainClassField">
+        <constraints>
+          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+      </component>
+      <component id="2fb86" class="javax.swing.JLabel">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <labelFor value="4853e"/>
+          <text value="&amp;Module:"/>
+        </properties>
+      </component>
+      <component id="4853e" class="javax.swing.JComboBox" binding="myModuleComboBox">
+        <constraints>
+          <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="2" anchor="8" fill="1" indent="0" use-parent-layout="false">
+            <preferred-size width="400" height="-1"/>
+          </grid>
+        </constraints>
+        <properties/>
+      </component>
+      <component id="8e551" class="javax.swing.JLabel" binding="myManifestDirLabel">
+        <constraints>
+          <grid row="3" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="&amp;Directory for META-INF/MANIFEST.MF:"/>
+        </properties>
+      </component>
+      <component id="1ea2d" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myManifestDirField">
+        <constraints>
+          <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="6" anchor="0" fill="1" indent="2" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+      </component>
+      <grid id="53c3f" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+        <margin top="0" left="0" bottom="0" right="0"/>
+        <constraints>
+          <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <clientProperties>
+          <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithIndent"/>
+        </clientProperties>
+        <border type="none" title="Jar files from libraries"/>
+        <children>
+          <component id="f9a17" class="javax.swing.JRadioButton" binding="myExtractJarsRadioButton">
+            <constraints>
+              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <selected value="true"/>
+              <text value="&amp;extract to the target jar"/>
+            </properties>
+          </component>
+          <hspacer id="90c4f">
+            <constraints>
+              <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+            </constraints>
+          </hspacer>
+          <component id="b3972" class="javax.swing.JRadioButton" binding="myCopyJarsRadioButton">
+            <constraints>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+            </constraints>
+            <properties>
+              <text value="copy &amp;to the output directory and link via manifest"/>
+            </properties>
+          </component>
+        </children>
+      </grid>
+      <component id="d5a56" class="javax.swing.JCheckBox" binding="myIncludeTestsCheckBox">
+        <constraints>
+          <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties>
+          <text value="&amp;Include tests"/>
+        </properties>
+      </component>
+    </children>
+  </grid>
+  <buttonGroups>
+    <group name="jarFiles">
+      <member id="f9a17"/>
+      <member id="b3972"/>
+    </group>
+  </buttonGroups>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.java
new file mode 100644
index 0000000..02d9e42
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactFromModulesDialog.java
@@ -0,0 +1,178 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesAlphaComparator;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import com.intellij.ui.ComboboxSpeedSearch;
+import com.intellij.ui.DocumentAdapter;
+import com.intellij.ui.ListCellRendererWrapper;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.Arrays;
+
+/**
+ * @author nik
+ */
+public class JarArtifactFromModulesDialog extends DialogWrapper {
+  private JPanel myMainPanel;
+  private TextFieldWithBrowseButton myMainClassField;
+  private JComboBox myModuleComboBox;
+  private JLabel myMainClassLabel;
+  private TextFieldWithBrowseButton myManifestDirField;
+  private JLabel myManifestDirLabel;
+  private JRadioButton myExtractJarsRadioButton;
+  private JRadioButton myCopyJarsRadioButton;
+  private JCheckBox myIncludeTestsCheckBox;
+  private PackagingElementResolvingContext myContext;
+
+  public JarArtifactFromModulesDialog(PackagingElementResolvingContext context) {
+    super(context.getProject());
+    myContext = context;
+    setTitle("Create Jar from Modules");
+    myMainClassLabel.setLabelFor(myMainClassField.getTextField());
+    myManifestDirLabel.setLabelFor(myManifestDirField.getTextField());
+
+    final Project project = myContext.getProject();
+    ManifestFileUtil.setupMainClassField(project, myMainClassField);
+    myMainClassField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      @Override
+      protected void textChanged(DocumentEvent e) {
+        updateManifestDirField();
+      }
+    });
+    final ActionListener actionListener = new ActionListener() {
+      @Override
+      public void actionPerformed(ActionEvent e) {
+        updateManifestDirField();
+      }
+    };
+    myExtractJarsRadioButton.addActionListener(actionListener);
+    myCopyJarsRadioButton.addActionListener(actionListener);
+
+    updateManifestDirField();
+    myManifestDirField.addBrowseFolderListener(null, null, project, ManifestFileUtil.createDescriptorForManifestDirectory());
+
+    setupModulesCombobox(context);
+    init();
+  }
+
+  private void setupModulesCombobox(PackagingElementResolvingContext context) {
+    final Module[] modules = context.getModulesProvider().getModules().clone();
+    Arrays.sort(modules, ModulesAlphaComparator.INSTANCE);
+    if (modules.length > 1) {
+      myModuleComboBox.addItem(null);
+    }
+    for (Module module : modules) {
+      myModuleComboBox.addItem(module);
+    }
+    myModuleComboBox.setRenderer(new ModuleListRenderer(myModuleComboBox));
+    new ComboboxSpeedSearch(myModuleComboBox) {
+      @Override
+      protected String getElementText(Object element) {
+        return element instanceof Module ? ((Module)element).getName() : "";
+      }
+    };
+  }
+
+  private void updateManifestDirField() {
+    final boolean enable = !myMainClassField.getText().isEmpty() || !myExtractJarsRadioButton.isSelected();
+    setManifestDirFieldEnabled(enable);
+    if (enable && myManifestDirField.getText().isEmpty()) {
+      final VirtualFile file = ManifestFileUtil.suggestManifestFileDirectory(myContext.getProject(), getSelectedModule());
+      if (file != null) {
+        myManifestDirField.setText(FileUtil.toSystemDependentName(file.getPath()));
+      }
+    }
+  }
+
+  @Nullable
+  private Module getSelectedModule() {
+    return (Module)myModuleComboBox.getSelectedItem();
+  }
+
+  @NotNull
+  public Module[] getSelectedModules() {
+    final Module module = getSelectedModule();
+    if (module != null) {
+      return new Module[]{module};
+    }
+    return myContext.getModulesProvider().getModules();
+  }
+
+  @NotNull
+  public String getDirectoryForManifest() {
+    return FileUtil.toSystemIndependentName(myManifestDirField.getText());
+  }
+
+  public boolean isExtractLibrariesToJar() {
+    return myExtractJarsRadioButton.isSelected();
+  }
+
+  public boolean isIncludeTests() {
+    return myIncludeTestsCheckBox.isSelected();
+  }
+
+  public String getMainClassName() {
+    return myMainClassField.getText();
+  }
+
+  private void setManifestDirFieldEnabled(boolean enabled) {
+    myManifestDirLabel.setEnabled(enabled);
+    myManifestDirField.setEnabled(enabled);
+  }
+
+  @Override
+  protected JComponent createCenterPanel() {
+    return myMainPanel;
+  }
+
+  @Override
+  protected String getHelpId() {
+    return "reference.project.structure.artifacts.jar.from.module";
+  }
+
+  private static class ModuleListRenderer extends ListCellRendererWrapper<Module> {
+    public ModuleListRenderer(JComboBox comboBox) {
+      super();
+    }
+
+    @Override
+    public void customize(JList list, Module value, int index, boolean selected, boolean hasFocus) {
+      if (value != null) {
+        setIcon(ModuleType.get(value).getIcon());
+        setText(value.getName());
+      }
+      else {
+        setText("<All Modules>");
+        setIcon(null);
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java
new file mode 100644
index 0000000..19571e4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarArtifactType.java
@@ -0,0 +1,65 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.packaging.artifacts.ArtifactTemplate;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class JarArtifactType extends ArtifactType {
+  public JarArtifactType() {
+    super("jar", "Jar");
+  }
+
+  public static JarArtifactType getInstance() {
+    return EP_NAME.findExtension(JarArtifactType.class);
+  }
+
+  @NotNull
+  @Override
+  public Icon getIcon() {
+    return AllIcons.Nodes.Artifact;
+  }
+
+  @Override
+  public String getDefaultPathFor(@NotNull PackagingElementOutputKind kind) {
+    return "/";
+  }
+
+  @NotNull
+  @Override
+  public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+    return new ArchivePackagingElement(ArtifactUtil.suggestArtifactFileName(artifactName) + ".jar");
+  }
+
+  @NotNull
+  @Override
+  public List<? extends ArtifactTemplate> getNewArtifactTemplates(@NotNull PackagingElementResolvingContext context) {
+    return Collections.singletonList(new JarFromModulesTemplate(context));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarFromModulesTemplate.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarFromModulesTemplate.java
new file mode 100644
index 0000000..308a211
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/JarFromModulesTemplate.java
@@ -0,0 +1,191 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactTemplate;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.elements.LibraryPackagingElement;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
+import com.intellij.packaging.impl.elements.TestModuleOutputElementType;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.PathUtil;
+import com.intellij.util.Processor;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class JarFromModulesTemplate extends ArtifactTemplate {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.artifacts.JarFromModulesTemplate");
+
+  private PackagingElementResolvingContext myContext;
+
+  public JarFromModulesTemplate(PackagingElementResolvingContext context) {
+    myContext = context;
+  }
+
+  @Override
+  public NewArtifactConfiguration createArtifact() {
+    JarArtifactFromModulesDialog dialog = new JarArtifactFromModulesDialog(myContext);
+    dialog.show();
+    if (!dialog.isOK()) {
+      return null;
+    }
+
+    return doCreateArtifact(dialog.getSelectedModules(), dialog.getMainClassName(), dialog.getDirectoryForManifest(),
+                            dialog.isExtractLibrariesToJar(), dialog.isIncludeTests());
+  }
+
+  @Nullable
+  public NewArtifactConfiguration doCreateArtifact(final Module[] modules, final String mainClassName,
+                                                   final String directoryForManifest,
+                                                   final boolean extractLibrariesToJar,
+                                                   final boolean includeTests) {
+    VirtualFile manifestFile = null;
+    final Project project = myContext.getProject();
+    if (mainClassName != null && !mainClassName.isEmpty() || !extractLibrariesToJar) {
+      final VirtualFile directory;
+      try {
+        directory = VfsUtil.createDirectoryIfMissing(directoryForManifest);
+      }
+      catch (IOException e) {
+        LOG.info(e);
+        Messages.showErrorDialog(project, "Cannot create directory '" + directoryForManifest + "': " + e.getMessage(),
+                                 CommonBundle.getErrorTitle());
+        return null;
+      }
+      if (directory == null) return null;
+
+      manifestFile = ManifestFileUtil.createManifestFile(directory, project);
+      if (manifestFile == null) {
+        return null;
+      }
+      ManifestFileUtil.updateManifest(manifestFile, mainClassName, null, true);
+    }
+
+    String name = modules.length == 1 ? modules[0].getName() : project.getName();
+
+    final PackagingElementFactory factory = PackagingElementFactory.getInstance();
+    final CompositePackagingElement<?> archive = factory.createArchive(ArtifactUtil.suggestArtifactFileName(name) + ".jar");
+
+    OrderEnumerator orderEnumerator = ProjectRootManager.getInstance(project).orderEntries(Arrays.asList(modules));
+
+    final Set<Library> libraries = new THashSet<Library>();
+    if (!includeTests) {
+      orderEnumerator = orderEnumerator.productionOnly();
+    }
+    final ModulesProvider modulesProvider = myContext.getModulesProvider();
+    final OrderEnumerator enumerator = orderEnumerator.using(modulesProvider).withoutSdk().runtimeOnly().recursively();
+    enumerator.forEachLibrary(new CommonProcessors.CollectProcessor<Library>(libraries));
+    enumerator.forEachModule(new Processor<Module>() {
+      @Override
+      public boolean process(Module module) {
+        if (ProductionModuleOutputElementType.ELEMENT_TYPE.isSuitableModule(modulesProvider, module)) {
+          archive.addOrFindChild(factory.createModuleOutput(module));
+        }
+        if (includeTests && TestModuleOutputElementType.ELEMENT_TYPE.isSuitableModule(modulesProvider, module)) {
+          archive.addOrFindChild(factory.createTestModuleOutput(module));
+        }
+        return true;
+      }
+    });
+
+    final JarArtifactType jarArtifactType = JarArtifactType.getInstance();
+    if (manifestFile != null && !manifestFile.equals(ManifestFileUtil.findManifestFile(archive, myContext, jarArtifactType))) {
+      archive.addFirstChild(factory.createFileCopyWithParentDirectories(manifestFile.getPath(), ManifestFileUtil.MANIFEST_DIR_NAME));
+    }
+
+    final String artifactName = name + ":jar";
+    if (extractLibrariesToJar) {
+      addExtractedLibrariesToJar(archive, factory, libraries);
+      return new NewArtifactConfiguration(archive, artifactName, jarArtifactType);
+    }
+    else {
+      final ArtifactRootElement<?> root = factory.createArtifactRootElement();
+      List<String> classpath = new ArrayList<String>();
+      root.addOrFindChild(archive);
+      addLibraries(libraries, root, archive, classpath);
+      ManifestFileUtil.updateManifest(manifestFile, mainClassName, classpath, true);
+      return new NewArtifactConfiguration(root, artifactName, PlainArtifactType.getInstance());
+    }
+  }
+
+  private void addLibraries(Set<Library> libraries, ArtifactRootElement<?> root, CompositePackagingElement<?> archive,
+                            List<String> classpath) {
+    PackagingElementFactory factory = PackagingElementFactory.getInstance();
+    for (Library library : libraries) {
+      if (LibraryPackagingElement.getKindForLibrary(library).containsDirectoriesWithClasses()) {
+        for (VirtualFile classesRoot : library.getFiles(OrderRootType.CLASSES)) {
+          if (classesRoot.isInLocalFileSystem()) {
+            archive.addOrFindChild(factory.createDirectoryCopyWithParentDirectories(classesRoot.getPath(), "/"));
+          }
+          else {
+            final PackagingElement<?> child = factory.createFileCopyWithParentDirectories(PathUtil.getLocalFile(classesRoot).getPath(), "/");
+            root.addOrFindChild(child);
+            classpath.addAll(ManifestFileUtil.getClasspathForElements(Collections.singletonList(child), myContext, PlainArtifactType.getInstance()));
+          }
+        }
+
+      }
+      else {
+        final List<? extends PackagingElement<?>> children = factory.createLibraryElements(library);
+        classpath.addAll(ManifestFileUtil.getClasspathForElements(children, myContext, PlainArtifactType.getInstance()));
+        root.addOrFindChildren(children);
+      }
+    }
+  }
+
+  private static void addExtractedLibrariesToJar(CompositePackagingElement<?> archive, PackagingElementFactory factory, Set<Library> libraries) {
+    for (Library library : libraries) {
+      if (LibraryPackagingElement.getKindForLibrary(library).containsJarFiles()) {
+        for (VirtualFile classesRoot : library.getFiles(OrderRootType.CLASSES)) {
+          if (classesRoot.isInLocalFileSystem()) {
+            archive.addOrFindChild(factory.createDirectoryCopyWithParentDirectories(classesRoot.getPath(), "/"));
+          }
+          else {
+            archive.addOrFindChild(factory.createExtractedDirectory(classesRoot));
+          }
+        }
+
+      }
+      else {
+        archive.addOrFindChildren(factory.createLibraryElements(library));
+      }
+    }
+  }
+
+  @Override
+  public String getPresentableName() {
+    return "From modules with dependencies...";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.java
new file mode 100644
index 0000000..dda0981
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementPath.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.packaging.impl.artifacts;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ComplexPackagingElement;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
+import com.intellij.util.SmartList;
+import com.intellij.util.StringBuilderSpinAllocator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class PackagingElementPath {
+  public static final PackagingElementPath EMPTY = new PackagingElementPath(null, null);
+  private final PackagingElementPath myParentPath;
+  private final PackagingElement<?> myLastElement;
+
+  private PackagingElementPath(PackagingElementPath parentPath, PackagingElement<?> lastElement) {
+    myParentPath = parentPath;
+    myLastElement = lastElement;
+  }
+
+  public PackagingElementPath appendComplex(ComplexPackagingElement<?> element) {
+    return new PackagingElementPath(this, element);
+  }
+
+  public PackagingElementPath appendComposite(CompositePackagingElement<?> element) {
+    return new PackagingElementPath(this, element);
+  }
+
+  @NotNull
+  public String getPathString() {
+    return getPathString("/");
+  }
+
+  @NotNull
+  public String getPathString(String separator) {
+    return getPathStringFrom(separator, null);
+  }
+
+  @NotNull
+  public String getPathStringFrom(String separator, @Nullable CompositePackagingElement<?> ancestor) {
+    final StringBuilder builder = StringBuilderSpinAllocator.alloc();
+    try {
+      final List<CompositePackagingElement<?>> parents = getParentsFrom(ancestor);
+      for (int i = parents.size() - 1; i >= 0; i--) {
+        builder.append(parents.get(i).getName());
+        if (i > 0) {
+          builder.append(separator);
+        }
+      }
+      return builder.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(builder);
+    }
+  }
+  
+  public List<CompositePackagingElement<?>> getParents() {
+    return getParentsFrom(null);
+  }
+
+  public List<CompositePackagingElement<?>> getParentsFrom(@Nullable CompositePackagingElement<?> ancestor) {
+    List<CompositePackagingElement<?>> result = new SmartList<CompositePackagingElement<?>>();
+    PackagingElementPath path = this;
+    while (path != EMPTY && path.myLastElement != ancestor) {
+      if (path.myLastElement instanceof CompositePackagingElement<?>) {
+        result.add((CompositePackagingElement)path.myLastElement);
+      }
+      path = path.myParentPath;
+    }
+    return result;
+  }
+
+  public List<PackagingElement<?>> getAllElements() {
+    List<PackagingElement<?>> result = new SmartList<PackagingElement<?>>();
+    PackagingElementPath path = this;
+    while (path != EMPTY) {
+      result.add(path.myLastElement);
+      path = path.myParentPath;
+    }
+    return result;
+  }
+
+  @Nullable
+  public CompositePackagingElement<?> getLastParent() {
+    PackagingElementPath path = this;
+    while (path != EMPTY) {
+      if (path.myLastElement instanceof CompositePackagingElement<?>) {
+        return (CompositePackagingElement)path.myLastElement;
+      }
+      path = path.myParentPath;
+    }
+    return null;
+  }
+
+  @Nullable
+  public Artifact findLastArtifact(PackagingElementResolvingContext context) {
+    PackagingElementPath path = this;
+    while (path != EMPTY) {
+      final PackagingElement<?> element = path.myLastElement;
+      if (element instanceof ArtifactPackagingElement) {
+        return ((ArtifactPackagingElement)element).findArtifact(context);
+      }
+      path = path.myParentPath;
+    }
+    return null;
+  }
+
+  public static PackagingElementPath createPath(@NotNull List<PackagingElement<?>> elements) {
+    PackagingElementPath path = EMPTY;
+    for (PackagingElement<?> element : elements) {
+      path = new PackagingElementPath(path, element);
+    }
+    return path;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementProcessor.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementProcessor.java
new file mode 100644
index 0000000..048217f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PackagingElementProcessor.java
@@ -0,0 +1,35 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.elements.ComplexPackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementProcessor<E extends PackagingElement<?>> {
+  public boolean shouldProcessSubstitution(ComplexPackagingElement<?> element) {
+    return true;
+  }
+
+  public boolean shouldProcess(PackagingElement<?> element) {
+    return true;
+  }
+
+  public abstract boolean process(@NotNull E element, @NotNull PackagingElementPath path);
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ParentElementProcessor.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ParentElementProcessor.java
new file mode 100644
index 0000000..6f09d18
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/ParentElementProcessor.java
@@ -0,0 +1,33 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ParentElementProcessor {
+
+  public abstract boolean process(@NotNull CompositePackagingElement<?> element, @NotNull List<Pair<Artifact,CompositePackagingElement<?>>> parents,
+                                  @NotNull Artifact artifact);
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PlainArtifactType.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PlainArtifactType.java
new file mode 100644
index 0000000..9337db5
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/PlainArtifactType.java
@@ -0,0 +1,58 @@
+/*
+ * 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.packaging.impl.artifacts;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import com.intellij.packaging.impl.elements.ArtifactRootElementImpl;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class PlainArtifactType extends ArtifactType {
+  @NonNls public static final String ID = "plain";
+
+  public static PlainArtifactType getInstance() {
+    return EP_NAME.findExtension(PlainArtifactType.class);
+  }
+
+  public PlainArtifactType() {
+    super(ID, CompilerBundle.message("artifact.type.plain"));
+  }
+
+  @NotNull
+  @Override
+  public Icon getIcon() {
+    return AllIcons.Nodes.Artifact;
+  }
+
+  @Override
+  public String getDefaultPathFor(@NotNull PackagingElementOutputKind kind) {
+    return "/";
+  }
+
+  @NotNull
+  public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+    return new ArtifactRootElementImpl();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java
new file mode 100644
index 0000000..9856fec
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/artifacts/UnknownPackagingElementTypeException.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.artifacts;
+
+/**
+ * @author nik
+ */
+class UnknownPackagingElementTypeException extends Exception {
+  private final String myTypeId;
+
+  public UnknownPackagingElementTypeException(String typeId) {
+    myTypeId = typeId;
+  }
+
+  public String getTypeId() {
+    return myTypeId;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java
new file mode 100644
index 0000000..ceb8bb4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAdditionalCompileScopeProvider.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.AdditionalCompileScopeProvider;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerFilter;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class ArtifactAdditionalCompileScopeProvider extends AdditionalCompileScopeProvider {
+  @Override
+  public CompileScope getAdditionalScope(@NotNull final CompileScope baseScope, @NotNull CompilerFilter filter, @NotNull final Project project) {
+    if (ArtifactCompileScope.getArtifacts(baseScope) != null) {
+      return null;
+    }
+    final ArtifactsCompiler compiler = ArtifactsCompiler.getInstance(project);
+    if (compiler == null || !filter.acceptCompiler(compiler)) {
+      return null;
+    }
+    return new ReadAction<CompileScope>() {
+      protected void run(final Result<CompileScope> result) {
+        final Set<Artifact> artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope, false);
+        result.setResult(ArtifactCompileScope.createScopeForModulesInArtifacts(project, artifacts));
+      } 
+    }.execute().getResultObject();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAwareCompiler.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAwareCompiler.java
new file mode 100644
index 0000000..1d10459
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactAwareCompiler.java
@@ -0,0 +1,30 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface ArtifactAwareCompiler {
+
+  boolean shouldRun(@NotNull Collection<? extends Artifact> changedArtifacts);
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTarget.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTarget.java
new file mode 100644
index 0000000..4a29afc
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTarget.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.openapi.compiler.generic.BuildTarget;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArtifactBuildTarget extends BuildTarget {
+  private Artifact myArtifact;
+
+  public ArtifactBuildTarget(Artifact artifact) {
+    myArtifact = artifact;
+  }
+
+  public Artifact getArtifact() {
+    return myArtifact;
+  }
+
+  @NotNull
+  @Override
+  public String getId() {
+    return myArtifact.getName();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java
new file mode 100644
index 0000000..c6af259
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactBuildTargetScopeProvider.java
@@ -0,0 +1,70 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.BuildTargetScopeProvider;
+import com.intellij.compiler.impl.CompileScopeUtil;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerFilter;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class ArtifactBuildTargetScopeProvider extends BuildTargetScopeProvider {
+  @NotNull
+  @Override
+  public List<TargetTypeBuildScope> getBuildTargetScopes(@NotNull final CompileScope baseScope, @NotNull CompilerFilter filter,
+                                                         @NotNull final Project project) {
+    final ArtifactsCompiler compiler = ArtifactsCompiler.getInstance(project);
+    if (compiler == null || !filter.acceptCompiler(compiler)) {
+      return Collections.emptyList();
+    }
+    final List<TargetTypeBuildScope> scopes = new ArrayList<TargetTypeBuildScope>();
+    new ReadAction() {
+      protected void run(final Result result) {
+        final Set<Artifact> artifacts = ArtifactCompileScope.getArtifactsToBuild(project, baseScope, false);
+        if (ArtifactCompileScope.getArtifacts(baseScope) == null) {
+          Set<Module> modules = ArtifactUtil.getModulesIncludedInArtifacts(artifacts, project);
+          CompileScopeUtil.addScopesForModules(modules, scopes);
+        }
+        if (!artifacts.isEmpty()) {
+          TargetTypeBuildScope.Builder builder =
+            TargetTypeBuildScope.newBuilder().setTypeId(ArtifactBuildTargetType.INSTANCE.getTypeId());
+          for (Artifact artifact : artifacts) {
+            builder.addTargetId(artifact.getName());
+          }
+          scopes.add(builder.build());
+        }
+      }
+    }.execute();
+
+    return scopes;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java
new file mode 100644
index 0000000..b434eac
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompileScope.java
@@ -0,0 +1,145 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.ModuleCompileScope;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.elements.ArtifactElementType;
+import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
+import com.intellij.packaging.impl.elements.ModuleOutputPackagingElement;
+import com.intellij.packaging.impl.elements.ProductionModuleOutputElementType;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactCompileScope {
+  private static final Key<Artifact[]> ARTIFACTS_KEY = Key.create("artifacts");
+  private static final Key<Set<Artifact>> CACHED_ARTIFACTS_KEY = Key.create("cached_artifacts");
+  private static final Key<Key<?>> ARTIFACTS_CONTENT_ID_KEY = Key.create("build_artifacts_task");
+
+  private ArtifactCompileScope() {
+  }
+
+  public static ModuleCompileScope createScopeForModulesInArtifacts(@NotNull Project project, @NotNull Collection<? extends Artifact> artifacts) {
+    final Set<Module> modules = ArtifactUtil.getModulesIncludedInArtifacts(artifacts, project);
+    return new ModuleCompileScope(project, modules.toArray(new Module[modules.size()]), true);
+  }
+
+  public static CompileScope createArtifactsScope(@NotNull Project project, @NotNull Collection<Artifact> artifacts) {
+    return createScopeWithArtifacts(createScopeForModulesInArtifacts(project, artifacts), artifacts, true);
+  }
+
+  public static CompileScope createScopeWithArtifacts(final CompileScope baseScope, @NotNull Collection<Artifact> artifacts, boolean useCustomContentId) {
+    baseScope.putUserData(ARTIFACTS_KEY, artifacts.toArray(new Artifact[artifacts.size()]));
+    if (useCustomContentId) {
+      baseScope.putUserData(CompilerManager.CONTENT_ID_KEY, ARTIFACTS_CONTENT_ID_KEY);
+    }
+    return baseScope;
+  }
+
+  public static Set<Artifact> getArtifactsToBuild(final Project project,
+                                                  final CompileScope compileScope,
+                                                  final boolean addIncludedArtifactsWithOutputPathsOnly) {
+    final Artifact[] artifactsFromScope = getArtifacts(compileScope);
+    final ArtifactManager artifactManager = ArtifactManager.getInstance(project);
+    PackagingElementResolvingContext context = artifactManager.getResolvingContext();
+    if (artifactsFromScope != null) {
+      return addIncludedArtifacts(Arrays.asList(artifactsFromScope), context, addIncludedArtifactsWithOutputPathsOnly);
+    }
+
+    final Set<Artifact> cached = compileScope.getUserData(CACHED_ARTIFACTS_KEY);
+    if (cached != null) {
+      return cached;
+    }
+
+    Set<Artifact> artifacts = new HashSet<Artifact>();
+    final Set<Module> modules = new HashSet<Module>(Arrays.asList(compileScope.getAffectedModules()));
+    final List<Module> allModules = Arrays.asList(ModuleManager.getInstance(project).getModules());
+    for (Artifact artifact : artifactManager.getArtifacts()) {
+      if (artifact.isBuildOnMake()) {
+        if (modules.containsAll(allModules)
+            || containsModuleOutput(artifact, modules, context)) {
+          artifacts.add(artifact);
+        }
+      }
+    }
+    Set<Artifact> result = addIncludedArtifacts(artifacts, context, addIncludedArtifactsWithOutputPathsOnly);
+    compileScope.putUserData(CACHED_ARTIFACTS_KEY, result);
+    return result;
+  }
+
+  @Nullable
+  public static Artifact[] getArtifacts(CompileScope compileScope) {
+    return compileScope.getUserData(ARTIFACTS_KEY);
+  }
+
+  private static boolean containsModuleOutput(Artifact artifact, final Set<Module> modules, final PackagingElementResolvingContext context) {
+    return !ArtifactUtil.processPackagingElements(artifact, ProductionModuleOutputElementType.ELEMENT_TYPE,
+                                                         new Processor<ModuleOutputPackagingElement>() {
+                                                           public boolean process(ModuleOutputPackagingElement moduleOutputPackagingElement) {
+                                                             final Module module = moduleOutputPackagingElement.findModule(context);
+                                                             return module == null || !modules.contains(module);
+                                                           }
+                                                         }, context, true);
+  }
+
+  @NotNull
+  private static Set<Artifact> addIncludedArtifacts(@NotNull Collection<Artifact> artifacts,
+                                                    @NotNull PackagingElementResolvingContext context,
+                                                    final boolean withOutputPathOnly) {
+    Set<Artifact> result = new HashSet<Artifact>();
+    for (Artifact artifact : artifacts) {
+      collectIncludedArtifacts(artifact, context, new HashSet<Artifact>(), result, withOutputPathOnly);
+    }
+    return result;
+  }
+
+  private static void collectIncludedArtifacts(Artifact artifact, final PackagingElementResolvingContext context,
+                                               final Set<Artifact> processed, final Set<Artifact> result, final boolean withOutputPathOnly) {
+    if (!processed.add(artifact)) {
+      return;
+    }
+    if (!withOutputPathOnly || !StringUtil.isEmpty(artifact.getOutputPath())) {
+      result.add(artifact);
+    }
+
+    ArtifactUtil.processPackagingElements(artifact, ArtifactElementType.ARTIFACT_ELEMENT_TYPE, new Processor<ArtifactPackagingElement>() {
+        @Override
+        public boolean process(ArtifactPackagingElement element) {
+          Artifact included = element.findArtifact(context);
+          if (included != null) {
+            collectIncludedArtifacts(included, context, processed, result, withOutputPathOnly);
+          }
+          return true;
+        }
+      }, context, false);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerCompileItem.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerCompileItem.java
new file mode 100644
index 0000000..b4e1865
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerCompileItem.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.openapi.compiler.generic.VirtualFileCompileItem;
+import com.intellij.compiler.impl.packagingCompiler.DestinationInfo;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.SmartList;
+import com.intellij.util.io.DataExternalizer;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactCompilerCompileItem extends VirtualFileCompileItem<ArtifactPackagingItemOutputState> {
+  public static final DataExternalizer<ArtifactPackagingItemOutputState> OUTPUT_EXTERNALIZER = new ArtifactPackagingItemExternalizer();
+  private final List<DestinationInfo> myDestinations = new SmartList<DestinationInfo>();
+
+  public ArtifactCompilerCompileItem(VirtualFile file) {
+    super(file);
+  }
+
+  public void addDestination(DestinationInfo info) {
+    myDestinations.add(info);
+  }
+
+  public List<DestinationInfo> getDestinations() {
+    return myDestinations;
+  }
+
+  @NotNull
+  @Override
+  public ArtifactPackagingItemOutputState computeOutputState() {
+    final SmartList<Pair<String, Long>> pairs = new SmartList<Pair<String, Long>>();
+    for (DestinationInfo destination : myDestinations) {
+      destination.update();
+      final VirtualFile outputFile = destination.getOutputFile();
+      long timestamp = outputFile != null ? outputFile.getTimeStamp() : -1;
+      pairs.add(Pair.create(destination.getOutputPath(), timestamp));
+    }
+    return new ArtifactPackagingItemOutputState(pairs);
+  }
+
+  @Override
+  public boolean isOutputUpToDate(@NotNull ArtifactPackagingItemOutputState state) {
+    final SmartList<Pair<String, Long>> cachedDestinations = state.myDestinations;
+    if (cachedDestinations.size() != myDestinations.size()) {
+      return false;
+    }
+
+    for (DestinationInfo info : myDestinations) {
+      final VirtualFile outputFile = info.getOutputFile();
+      long timestamp = outputFile != null ? outputFile.getTimeStamp() : -1;
+      final String path = info.getOutputPath();
+      boolean found = false;
+      //todo[nik] use map if list contains many items
+      for (Pair<String, Long> cachedDestination : cachedDestinations) {
+        if (cachedDestination.first.equals(path)) {
+          if (cachedDestination.second != timestamp) return false;
+          found = true;
+          break;
+        }
+      }
+      if (!found) return false;
+    }
+
+    return true;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java
new file mode 100644
index 0000000..0de7e05
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactCompilerUtil.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetManager;
+import com.intellij.facet.FacetRootsProvider;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.elements.ComplexPackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.artifacts.PackagingElementPath;
+import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
+import com.intellij.packaging.impl.elements.ArtifactPackagingElement;
+import com.intellij.packaging.impl.elements.FileOrDirectoryCopyPackagingElement;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.MultiMap;
+import gnu.trove.THashMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.api.CmdlineRemoteProto.Message.ControllerMessage.ParametersMessage.TargetTypeBuildScope;
+import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTargetType;
+
+import java.io.BufferedInputStream;
+import java.io.File;
+import java.io.IOException;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * @author nik
+ */
+public class ArtifactCompilerUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.ArtifactCompilerUtil");
+
+  private ArtifactCompilerUtil() {
+  }
+
+  @Nullable
+  public static BufferedInputStream getJarEntryInputStream(VirtualFile sourceFile, final CompileContext context) throws IOException {
+    final String fullPath = sourceFile.getPath();
+    final int jarEnd = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
+    LOG.assertTrue(jarEnd != -1, fullPath);
+    String pathInJar = fullPath.substring(jarEnd + JarFileSystem.JAR_SEPARATOR.length());
+    String jarPath = fullPath.substring(0, jarEnd);
+    final ZipFile jarFile = new ZipFile(new File(FileUtil.toSystemDependentName(jarPath)));
+    final ZipEntry entry = jarFile.getEntry(pathInJar);
+    if (entry == null) {
+      context.addMessage(CompilerMessageCategory.ERROR, "Cannot extract '" + pathInJar + "' from '" + jarFile.getName() + "': entry not found", null, -1, -1);
+      return null;
+    }
+
+    return new BufferedInputStream(jarFile.getInputStream(entry)) {
+      @Override
+      public void close() throws IOException {
+        super.close();
+        jarFile.close();
+      }
+    };
+  }
+
+  public static File getJarFile(VirtualFile jarEntry) {
+    String fullPath = jarEntry.getPath();
+    return new File(FileUtil.toSystemDependentName(fullPath.substring(fullPath.indexOf(JarFileSystem.JAR_SEPARATOR))));
+  }
+
+
+  @NotNull
+  public static Set<VirtualFile> getArtifactOutputsContainingSourceFiles(final @NotNull Project project) {
+    final List<VirtualFile> allOutputs = new ArrayList<VirtualFile>();
+    for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
+      ContainerUtil.addIfNotNull(artifact.getOutputFile(), allOutputs);
+    }
+
+    final Set<VirtualFile> roots = new HashSet<VirtualFile>();
+    final PackagingElementResolvingContext context = ArtifactManager.getInstance(project).getResolvingContext();
+    for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
+      ArtifactUtil.processPackagingElements(artifact, null, new PackagingElementProcessor<PackagingElement<?>>() {
+        @Override
+        public boolean shouldProcessSubstitution(ComplexPackagingElement<?> element) {
+          return !(element instanceof ArtifactPackagingElement);
+        }
+
+        @Override
+        public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+          if (element instanceof FileOrDirectoryCopyPackagingElement<?>) {
+            final VirtualFile file = ((FileOrDirectoryCopyPackagingElement)element).findFile();
+            if (file != null) {
+              roots.add(file);
+            }
+          }
+          return true;
+        }
+      }, context, true);
+    }
+
+    final Module[] modules = ModuleManager.getInstance(project).getModules();
+    for (Module module : modules) {
+      final Facet[] facets = FacetManager.getInstance(module).getAllFacets();
+      for (Facet facet : facets) {
+        if (facet instanceof FacetRootsProvider) {
+          roots.addAll(((FacetRootsProvider)facet).getFacetRoots());
+        }
+      }
+    }
+
+    final Set<VirtualFile> affectedOutputPaths = new HashSet<VirtualFile>();
+    for (VirtualFile output : allOutputs) {
+      for (VirtualFile root : roots) {
+        if (VfsUtilCore.isAncestor(output, root, false)) {
+          affectedOutputPaths.add(output);
+        }
+      }
+    }
+    return affectedOutputPaths;
+  }
+
+  public static boolean containsArtifacts(List<TargetTypeBuildScope> scopes) {
+    for (TargetTypeBuildScope scope : scopes) {
+      if (ArtifactBuildTargetType.INSTANCE.getTypeId().equals(scope.getTypeId())) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public static MultiMap<String, Artifact> createOutputToArtifactMap(final Project project) {
+    final MultiMap<String, Artifact> result = new MultiMap<String, Artifact>() {
+      @Override
+      protected Map<String, Collection<Artifact>> createMap() {
+        return new THashMap<String, Collection<Artifact>>(FileUtil.PATH_HASHING_STRATEGY);
+      }
+    };
+    new ReadAction() {
+      protected void run(final Result r) {
+        for (Artifact artifact : ArtifactManager.getInstance(project).getArtifacts()) {
+          String outputPath = artifact.getOutputFilePath();
+          if (!StringUtil.isEmpty(outputPath)) {
+            result.putValue(outputPath, artifact);
+          }
+        }
+      }
+    }.execute();
+
+
+    return result;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java
new file mode 100644
index 0000000..030e948
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemExternalizer.java
@@ -0,0 +1,53 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.SmartList;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.IOUtil;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+* @author nik
+*/
+public class ArtifactPackagingItemExternalizer implements DataExternalizer<ArtifactPackagingItemOutputState> {
+  private byte[] myBuffer = IOUtil.allocReadWriteUTFBuffer();
+
+  @Override
+  public void save(DataOutput out, ArtifactPackagingItemOutputState value) throws IOException {
+    out.writeInt(value.myDestinations.size());
+    for (Pair<String, Long> pair : value.myDestinations) {
+      IOUtil.writeUTFFast(myBuffer, out, pair.getFirst());
+      out.writeLong(pair.getSecond());
+    }
+  }
+
+  @Override
+  public ArtifactPackagingItemOutputState read(DataInput in) throws IOException {
+    int size = in.readInt();
+    SmartList<Pair<String, Long>> destinations = new SmartList<Pair<String, Long>>();
+    while (size-- > 0) {
+      String path = IOUtil.readUTFFast(myBuffer, in);
+      long outputTimestamp = in.readLong();
+      destinations.add(Pair.create(path, outputTimestamp));
+    }
+    return new ArtifactPackagingItemOutputState(destinations);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemOutputState.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemOutputState.java
new file mode 100644
index 0000000..29ac0ae
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactPackagingItemOutputState.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.SmartList;
+
+/**
+* @author nik
+*/
+public class ArtifactPackagingItemOutputState {
+  public final SmartList<Pair<String, Long>> myDestinations;
+
+  public ArtifactPackagingItemOutputState(SmartList<Pair<String, Long>> destinations) {
+    myDestinations = destinations;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompiler.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompiler.java
new file mode 100644
index 0000000..9875816
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompiler.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.compiler.generic.CompileItem;
+import com.intellij.openapi.compiler.generic.GenericCompiler;
+import com.intellij.openapi.compiler.generic.GenericCompilerInstance;
+import com.intellij.openapi.compiler.generic.VirtualFilePersistentState;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.util.io.DataExternalizer;
+import com.intellij.util.io.KeyDescriptor;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class ArtifactsCompiler extends GenericCompiler<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> {
+  private static final Key<Set<String>> WRITTEN_PATHS_KEY = Key.create("artifacts_written_paths");
+  private static final Key<Set<Artifact>> CHANGED_ARTIFACTS = Key.create("affected_artifacts");
+
+  public ArtifactsCompiler() {
+    super("artifacts_compiler", 0, GenericCompiler.CompileOrderPlace.PACKAGING);
+  }
+
+  @Nullable
+  public static ArtifactsCompiler getInstance(@NotNull Project project) {
+    final ArtifactsCompiler[] compilers = CompilerManager.getInstance(project).getCompilers(ArtifactsCompiler.class);
+    return compilers.length == 1 ? compilers[0] : null;
+  }
+
+  public static void addChangedArtifact(final CompileContext context, Artifact artifact) {
+    Set<Artifact> artifacts = context.getUserData(CHANGED_ARTIFACTS);
+    if (artifacts == null) {
+      artifacts = new THashSet<Artifact>();
+      context.putUserData(CHANGED_ARTIFACTS, artifacts);
+    }
+    artifacts.add(artifact);
+  }
+
+  public static void addWrittenPaths(final CompileContext context, Set<String> writtenPaths) {
+    Set<String> paths = context.getUserData(WRITTEN_PATHS_KEY);
+    if (paths == null) {
+      paths = new THashSet<String>();
+      context.putUserData(WRITTEN_PATHS_KEY, paths);
+    }
+    paths.addAll(writtenPaths);
+  }
+
+  @NotNull
+  @Override
+  public KeyDescriptor<String> getItemKeyDescriptor() {
+    return STRING_KEY_DESCRIPTOR;
+  }
+
+  @NotNull
+  @Override
+  public DataExternalizer<VirtualFilePersistentState> getSourceStateExternalizer() {
+    return VirtualFilePersistentState.EXTERNALIZER;
+  }
+
+  @NotNull
+  @Override
+  public DataExternalizer<ArtifactPackagingItemOutputState> getOutputStateExternalizer() {
+    return new ArtifactPackagingItemExternalizer();
+  }
+
+  @NotNull
+  @Override
+  public GenericCompilerInstance<ArtifactBuildTarget, ? extends CompileItem<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>, String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> createInstance(
+    @NotNull CompileContext context) {
+    return new ArtifactsCompilerInstance(context);
+  }
+
+  @NotNull
+  public String getDescription() {
+    return "Artifacts Packaging Compiler";
+  }
+
+  @Nullable
+  public static Set<Artifact> getChangedArtifacts(final CompileContext compileContext) {
+    return compileContext.getUserData(CHANGED_ARTIFACTS);
+  }
+
+  @Nullable
+  public static Set<String> getWrittenPaths(@NotNull CompileContext context) {
+    return context.getUserData(WRITTEN_PATHS_KEY);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
new file mode 100644
index 0000000..1edb774
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
@@ -0,0 +1,425 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.CompilerManagerImpl;
+import com.intellij.compiler.impl.CompilerUtil;
+import com.intellij.compiler.impl.packagingCompiler.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.compiler.generic.GenericCompilerCacheState;
+import com.intellij.openapi.compiler.generic.GenericCompilerInstance;
+import com.intellij.openapi.compiler.generic.GenericCompilerProcessingItem;
+import com.intellij.openapi.compiler.generic.VirtualFilePersistentState;
+import com.intellij.openapi.compiler.make.BuildParticipant;
+import com.intellij.openapi.compiler.make.BuildParticipantProvider;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.progress.ProcessCanceledException;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.*;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ArtifactProperties;
+import com.intellij.packaging.artifacts.ArtifactPropertiesProvider;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.ArtifactSortingUtil;
+import com.intellij.util.ThrowableRunnable;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.*;
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactsCompilerInstance extends GenericCompilerInstance<ArtifactBuildTarget, ArtifactCompilerCompileItem,
+  String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.compiler.ArtifactsCompilerInstance");
+  public static final Logger FULL_LOG = Logger.getInstance("#com.intellij.full-artifacts-compiler-log");
+  private ArtifactsProcessingItemsBuilderContext myBuilderContext;
+
+  public ArtifactsCompilerInstance(CompileContext context) {
+    super(context);
+  }
+
+  @NotNull
+  @Override
+  public List<ArtifactBuildTarget> getAllTargets() {
+    return getArtifactTargets(false);
+  }
+
+  @NotNull
+  @Override
+  public List<ArtifactBuildTarget> getSelectedTargets() {
+    return getArtifactTargets(true);
+  }
+
+  private List<ArtifactBuildTarget> getArtifactTargets(final boolean selectedOnly) {
+    final List<ArtifactBuildTarget> targets = new ArrayList<ArtifactBuildTarget>();
+    new ReadAction() {
+      protected void run(final Result result) {
+        final Set<Artifact> artifacts;
+        if (selectedOnly) {
+          artifacts = ArtifactCompileScope.getArtifactsToBuild(getProject(), myContext.getCompileScope(), true);
+        }
+        else {
+          artifacts = new HashSet<Artifact>(Arrays.asList(ArtifactManager.getInstance(getProject()).getArtifacts()));
+        }
+
+        Map<String, Artifact> artifactsMap = new HashMap<String, Artifact>();
+        for (Artifact artifact : artifacts) {
+          artifactsMap.put(artifact.getName(), artifact);
+        }
+        for (String name : ArtifactSortingUtil.getInstance(getProject()).getArtifactsSortedByInclusion()) {
+          Artifact artifact = artifactsMap.get(name);
+          if (artifact != null) {
+            targets.add(new ArtifactBuildTarget(artifact));
+          }
+        }
+
+        for (BuildParticipantProvider provider : BuildParticipantProvider.EXTENSION_POINT_NAME.getExtensions()) {
+          for (Module module : ModuleManager.getInstance(getProject()).getModules()) {
+            final Collection<? extends BuildParticipant> participants = provider.getParticipants(module);
+            for (BuildParticipant participant : participants) {
+              Artifact artifact = participant.createArtifact(myContext);
+              if (artifact != null) {
+                LOG.debug("additional artifact to build: " + artifact);
+                targets.add(new ArtifactBuildTarget(artifact));
+              }
+            }
+          }
+        }
+      }
+    }.execute();
+    return targets;
+  }
+
+  @Override
+  public void processObsoleteTarget(@NotNull String targetId,
+                                    @NotNull List<GenericCompilerCacheState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems) {
+    deleteFiles(obsoleteItems, Collections.<GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>>emptyList());
+  }
+
+  @NotNull
+  @Override
+  public List<ArtifactCompilerCompileItem> getItems(@NotNull ArtifactBuildTarget target) {
+    myBuilderContext = new ArtifactsProcessingItemsBuilderContext(myContext);
+    final Artifact artifact = target.getArtifact();
+
+    final Map<String, String> selfIncludingArtifacts = new ReadAction<Map<String, String>>() {
+      protected void run(final Result<Map<String, String>> result) {
+        result.setResult(ArtifactSortingUtil.getInstance(getProject()).getArtifactToSelfIncludingNameMap());
+      }
+    }.execute().getResultObject();
+    final String selfIncludingName = selfIncludingArtifacts.get(artifact.getName());
+    if (selfIncludingName != null) {
+      String name = selfIncludingName.equals(artifact.getName()) ? "it" : "'" + selfIncludingName + "' artifact";
+      myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot build '" + artifact.getName() + "' artifact: " + name + " includes itself in the output layout", null, -1, -1);
+      return Collections.emptyList();
+    }
+
+    final String outputPath = artifact.getOutputPath();
+    if (outputPath == null || outputPath.length() == 0) {
+      myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot build '" + artifact.getName() + "' artifact: output path is not specified",
+                      null, -1, -1);
+      return Collections.emptyList();
+    }
+
+    DumbService.getInstance(getProject()).waitForSmartMode();
+    new ReadAction() {
+      protected void run(final Result result) {
+        collectItems(artifact, outputPath);
+      }
+    }.execute();
+    return new ArrayList<ArtifactCompilerCompileItem>(myBuilderContext.getProcessingItems());
+  }
+
+  private void collectItems(@NotNull Artifact artifact, @NotNull String outputPath) {
+    final CompositePackagingElement<?> rootElement = artifact.getRootElement();
+    final VirtualFile outputFile = LocalFileSystem.getInstance().findFileByPath(outputPath);
+    final CopyToDirectoryInstructionCreator instructionCreator = new CopyToDirectoryInstructionCreator(myBuilderContext, outputPath, outputFile);
+    final PackagingElementResolvingContext resolvingContext = ArtifactManager.getInstance(getProject()).getResolvingContext();
+    FULL_LOG.debug("Collecting items for " + artifact.getName());
+    rootElement.computeIncrementalCompilerInstructions(instructionCreator, resolvingContext, myBuilderContext, artifact.getArtifactType());
+  }
+
+  private boolean doBuild(@NotNull Artifact artifact,
+                          final List<GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> changedItems,
+                          final Set<ArtifactCompilerCompileItem> processedItems,
+                          final @NotNull Set<String> writtenPaths,
+                          final Set<String> deletedJars) {
+    FULL_LOG.debug("Building " + artifact.getName());
+    final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
+
+    final DeploymentUtil deploymentUtil = DeploymentUtil.getInstance();
+    final FileFilter fileFilter = new IgnoredFileFilter();
+    final Set<JarInfo> changedJars = new THashSet<JarInfo>();
+    for (String deletedJar : deletedJars) {
+      ContainerUtil.addIfNotNull(myBuilderContext.getJarInfo(deletedJar), changedJars);
+    }
+
+    try {
+      onBuildStartedOrFinished(artifact, false);
+      if (myContext.getMessageCount(CompilerMessageCategory.ERROR) > 0) {
+        return false;
+      }
+
+      int i = 0;
+      for (final GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+        final ArtifactCompilerCompileItem sourceItem = item.getItem();
+        myContext.getProgressIndicator().checkCanceled();
+
+        final Ref<IOException> exception = Ref.create(null);
+        new ReadAction() {
+          protected void run(final Result result) {
+            final VirtualFile sourceFile = sourceItem.getFile();
+            for (DestinationInfo destination : sourceItem.getDestinations()) {
+              if (destination instanceof ExplodedDestinationInfo) {
+                final ExplodedDestinationInfo explodedDestination = (ExplodedDestinationInfo)destination;
+                File toFile = new File(FileUtil.toSystemDependentName(explodedDestination.getOutputPath()));
+                try {
+                  if (sourceFile.isInLocalFileSystem()) {
+                    final File ioFromFile = VfsUtilCore.virtualToIoFile(sourceFile);
+                    if (ioFromFile.exists()) {
+                      deploymentUtil.copyFile(ioFromFile, toFile, myContext, writtenPaths, fileFilter);
+                    }
+                    else {
+                      LOG.debug("Cannot copy " + ioFromFile.getAbsolutePath() + ": file doesn't exist");
+                    }
+                  }
+                  else {
+                    extractFile(sourceFile, toFile, writtenPaths, fileFilter);
+                  }
+                }
+                catch (IOException e) {
+                  exception.set(e);
+                  return;
+                }
+              }
+              else {
+                changedJars.add(((JarDestinationInfo)destination).getJarInfo());
+              }
+            }
+          }
+        }.execute();
+        if (exception.get() != null) {
+          throw exception.get();
+        }
+
+        myContext.getProgressIndicator().setFraction(++i * 1.0 / changedItems.size());
+        processedItems.add(sourceItem);
+        if (testMode) {
+          CompilerManagerImpl.addRecompiledPath(FileUtil.toSystemDependentName(sourceItem.getFile().getPath()));
+        }
+      }
+
+      JarsBuilder builder = new JarsBuilder(changedJars, fileFilter, myContext);
+      final boolean processed = builder.buildJars(writtenPaths);
+      if (!processed) {
+        return false;
+      }
+
+      Set<VirtualFile> recompiledSources = new HashSet<VirtualFile>();
+      for (JarInfo info : builder.getJarsToBuild()) {
+        for (Pair<String, VirtualFile> pair : info.getPackedFiles()) {
+          recompiledSources.add(pair.getSecond());
+        }
+      }
+      for (VirtualFile source : recompiledSources) {
+        ArtifactCompilerCompileItem item = myBuilderContext.getItemBySource(source);
+        LOG.assertTrue(item != null, source);
+        processedItems.add(item);
+        if (testMode) {
+          CompilerManagerImpl.addRecompiledPath(FileUtil.toSystemDependentName(item.getFile().getPath()));
+        }
+      }
+
+      onBuildStartedOrFinished(artifact, true);
+    }
+    catch (ProcessCanceledException e) {
+      throw e;
+    }
+    catch (Exception e) {
+      LOG.info(e);
+      myContext.addMessage(CompilerMessageCategory.ERROR, e.getLocalizedMessage(), null, -1, -1);
+      return false;
+    }
+    return true;
+  }
+
+  private void extractFile(VirtualFile sourceFile, File toFile, Set<String> writtenPaths, FileFilter fileFilter) throws IOException {
+    if (!writtenPaths.add(toFile.getPath())) {
+      return;
+    }
+
+    if (!FileUtil.createParentDirs(toFile)) {
+      myContext.addMessage(CompilerMessageCategory.ERROR, "Cannot create directory for '" + toFile.getAbsolutePath() + "' file", null, -1, -1);
+      return;
+    }
+
+    final BufferedInputStream input = ArtifactCompilerUtil.getJarEntryInputStream(sourceFile, myContext);
+    if (input == null) return;
+    final BufferedOutputStream output = new BufferedOutputStream(new FileOutputStream(toFile));
+    try {
+      FileUtil.copy(input, output);
+    }
+    finally {
+      input.close();
+      output.close();
+    }
+  }
+
+  private void onBuildStartedOrFinished(@NotNull Artifact artifact, final boolean finished) throws Exception {
+    for (ArtifactPropertiesProvider provider : artifact.getPropertiesProviders()) {
+      final ArtifactProperties<?> properties = artifact.getProperties(provider);
+      if (finished) {
+        properties.onBuildFinished(artifact, myContext);
+      }
+      else {
+        properties.onBuildStarted(artifact, myContext);
+      }
+    }
+  }
+
+  private static THashSet<String> createPathsHashSet() {
+    return new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
+  }
+
+  @Override
+  public void processItems(@NotNull final ArtifactBuildTarget target,
+                           @NotNull final List<GenericCompilerProcessingItem<ArtifactCompilerCompileItem,VirtualFilePersistentState,ArtifactPackagingItemOutputState>> changedItems,
+                           @NotNull List<GenericCompilerCacheState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems,
+                           @NotNull OutputConsumer<ArtifactCompilerCompileItem> consumer) {
+
+    final THashSet<String> deletedJars = deleteFiles(obsoleteItems, changedItems);
+
+    final Set<String> writtenPaths = createPathsHashSet();
+    final Ref<Boolean> built = Ref.create(false);
+    final Set<ArtifactCompilerCompileItem> processedItems = new HashSet<ArtifactCompilerCompileItem>();
+    CompilerUtil.runInContext(myContext, "Copying files", new ThrowableRunnable<RuntimeException>() {
+      public void run() throws RuntimeException {
+        built.set(doBuild(target.getArtifact(), changedItems, processedItems, writtenPaths, deletedJars));
+      }
+    });
+    if (!built.get()) {
+      return;
+    }
+
+    myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.updating.caches"));
+    myContext.getProgressIndicator().setText2("");
+    for (String path : writtenPaths) {
+      consumer.addFileToRefresh(new File(path));
+    }
+    for (ArtifactCompilerCompileItem item : processedItems) {
+      consumer.addProcessedItem(item);
+    }
+    ArtifactsCompiler.addWrittenPaths(myContext, writtenPaths);
+    ArtifactsCompiler.addChangedArtifact(myContext, target.getArtifact());
+  }
+
+  private THashSet<String> deleteFiles(List<GenericCompilerCacheState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> obsoleteItems,
+                                       List<GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState>> changedItems) {
+    myContext.getProgressIndicator().setText(CompilerBundle.message("packaging.compiler.message.deleting.outdated.files"));
+
+    final boolean testMode = ApplicationManager.getApplication().isUnitTestMode();
+    final THashSet<String> deletedJars = new THashSet<String>();
+    final THashSet<String> notDeletedJars = new THashSet<String>();
+    if (LOG.isDebugEnabled()) {
+      LOG.debug("Deleting outdated files...");
+    }
+
+    Set<String> pathToDelete = new THashSet<String>();
+    for (GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+      final ArtifactPackagingItemOutputState cached = item.getCachedOutputState();
+      if (cached != null) {
+        for (Pair<String, Long> destination : cached.myDestinations) {
+          pathToDelete.add(destination.getFirst());
+        }
+      }
+    }
+    for (GenericCompilerProcessingItem<ArtifactCompilerCompileItem, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : changedItems) {
+      for (DestinationInfo destination : item.getItem().getDestinations()) {
+        pathToDelete.remove(destination.getOutputPath());
+      }
+    }
+    for (GenericCompilerCacheState<String, VirtualFilePersistentState, ArtifactPackagingItemOutputState> item : obsoleteItems) {
+      for (Pair<String, Long> destination : item.getOutputState().myDestinations) {
+        pathToDelete.add(destination.getFirst());
+      }
+    }
+
+    int notDeletedFilesCount = 0;
+    List<File> filesToRefresh = new ArrayList<File>();
+
+    for (String fullPath : pathToDelete) {
+      int end = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
+      boolean isJar = end != -1;
+      String filePath = isJar ? fullPath.substring(0, end) : fullPath;
+      boolean deleted = false;
+      if (isJar) {
+      if (notDeletedJars.contains(filePath)) {
+        continue;
+      }
+      deleted = deletedJars.contains(filePath);
+    }
+
+      File file = new File(FileUtil.toSystemDependentName(filePath));
+      if (!deleted) {
+      filesToRefresh.add(file);
+      deleted = FileUtil.delete(file);
+    }
+
+      if (deleted) {
+      if (isJar) {
+        deletedJars.add(filePath);
+      }
+      if (testMode) {
+        CompilerManagerImpl.addDeletedPath(file.getAbsolutePath());
+      }
+    }
+    else {
+      if (isJar) {
+        notDeletedJars.add(filePath);
+      }
+      if (notDeletedFilesCount++ > 50) {
+        myContext.addMessage(CompilerMessageCategory.WARNING, "Deletion of outdated files stopped because too many files cannot be deleted", null, -1, -1);
+        break;
+      }
+      myContext.addMessage(CompilerMessageCategory.WARNING, "Cannot delete file '" + filePath + "'", null, -1, -1);
+      if (LOG.isDebugEnabled()) {
+        LOG.debug("Cannot delete file " + file);
+      }
+    }
+    }
+
+    CompilerUtil.refreshIOFiles(filesToRefresh);
+    return deletedJars;
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsProcessingItemsBuilderContext.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsProcessingItemsBuilderContext.java
new file mode 100644
index 0000000..a96663c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsProcessingItemsBuilderContext.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.packagingCompiler.DestinationInfo;
+import com.intellij.compiler.impl.packagingCompiler.ExplodedDestinationInfo;
+import com.intellij.compiler.impl.packagingCompiler.JarInfo;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.ArtifactIncrementalCompilerContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.HashMap;
+import java.util.Map;
+
+/**
+ * @author nik
+ */
+public class ArtifactsProcessingItemsBuilderContext implements ArtifactIncrementalCompilerContext {
+  protected final Map<VirtualFile, ArtifactCompilerCompileItem> myItemsBySource;
+  private final Map<String, VirtualFile> mySourceByOutput;
+  private final Map<String, JarInfo> myJarByPath;
+  private final CompileContext myCompileContext;
+  private final boolean myPrintToLog;
+
+  public ArtifactsProcessingItemsBuilderContext(CompileContext compileContext) {
+    myCompileContext = compileContext;
+    myItemsBySource = new HashMap<VirtualFile, ArtifactCompilerCompileItem>();
+    mySourceByOutput = new HashMap<String, VirtualFile>();
+    myJarByPath = new HashMap<String, JarInfo>();
+    myPrintToLog = ArtifactsCompilerInstance.FULL_LOG.isDebugEnabled();
+  }
+
+  public boolean addDestination(@NotNull VirtualFile sourceFile, @NotNull DestinationInfo destinationInfo) {
+    if (destinationInfo instanceof ExplodedDestinationInfo && sourceFile.equals(destinationInfo.getOutputFile())) {
+      return false;
+    }
+
+    if (checkOutputPath(destinationInfo.getOutputPath(), sourceFile)) {
+      if (myPrintToLog) {
+        ArtifactsCompilerInstance.FULL_LOG.debug("  " + sourceFile.getPath() + " -> " + destinationInfo);
+      }
+      getOrCreateProcessingItem(sourceFile).addDestination(destinationInfo);
+      return true;
+    }
+    return false;
+  }
+
+  public Collection<ArtifactCompilerCompileItem> getProcessingItems() {
+    return myItemsBySource.values();
+  }
+
+  public boolean checkOutputPath(final String outputPath, final VirtualFile sourceFile) {
+    VirtualFile old = mySourceByOutput.get(outputPath);
+    if (old == null) {
+      mySourceByOutput.put(outputPath, sourceFile);
+      return true;
+    }
+    //todo[nik] show warning?
+    return false;
+  }
+
+  public ArtifactCompilerCompileItem getItemBySource(VirtualFile source) {
+    return myItemsBySource.get(source);
+  }
+
+  public boolean registerJarFile(@NotNull JarInfo jarInfo, @NotNull String outputPath) {
+    if (mySourceByOutput.containsKey(outputPath) || myJarByPath.containsKey(outputPath)) {
+      return false;
+    }
+    myJarByPath.put(outputPath, jarInfo);
+    return true;
+  }
+
+  @Nullable
+  public JarInfo getJarInfo(String outputPath) {
+    return myJarByPath.get(outputPath);
+  }
+
+  @Nullable
+  public VirtualFile getSourceByOutput(String outputPath) {
+    return mySourceByOutput.get(outputPath);
+  }
+
+  public CompileContext getCompileContext() {
+    return myCompileContext;
+  }
+
+  public ArtifactCompilerCompileItem getOrCreateProcessingItem(VirtualFile sourceFile) {
+    ArtifactCompilerCompileItem item = myItemsBySource.get(sourceFile);
+    if (item == null) {
+      item = new ArtifactCompilerCompileItem(sourceFile);
+      myItemsBySource.put(sourceFile, item);
+    }
+    return item;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsWorkspaceSettings.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsWorkspaceSettings.java
new file mode 100644
index 0000000..a25f4d0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsWorkspaceSettings.java
@@ -0,0 +1,83 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.StoragePathMacros;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xmlb.annotations.AbstractCollection;
+import com.intellij.util.xmlb.annotations.Tag;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+@State(name = "ArtifactsWorkspaceSettings",
+  storages = {
+    @Storage( file = StoragePathMacros.WORKSPACE_FILE)
+  })
+public class ArtifactsWorkspaceSettings implements PersistentStateComponent<ArtifactsWorkspaceSettings.ArtifactsWorkspaceSettingsState> {
+  private ArtifactsWorkspaceSettingsState myState = new ArtifactsWorkspaceSettingsState();
+  private final Project myProject;
+
+  public ArtifactsWorkspaceSettings(Project project) {
+    myProject = project;
+  }
+
+  public static ArtifactsWorkspaceSettings getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, ArtifactsWorkspaceSettings.class);
+  }
+
+  public List<Artifact> getArtifactsToBuild() {
+    final List<Artifact> result = new ArrayList<Artifact>();
+    final ArtifactManager artifactManager = ArtifactManager.getInstance(myProject);
+    for (String name : myState.myArtifactsToBuild) {
+      ContainerUtil.addIfNotNull(artifactManager.findArtifact(name), result);
+    }
+    return result;
+  }
+
+  public void setArtifactsToBuild(@NotNull Collection<? extends Artifact> artifacts) {
+    myState.myArtifactsToBuild.clear();
+    for (Artifact artifact : artifacts) {
+      myState.myArtifactsToBuild.add(artifact.getName());
+    }
+    Collections.sort(myState.myArtifactsToBuild);
+  }
+
+  public ArtifactsWorkspaceSettingsState getState() {
+    return myState;
+  }
+
+  public void loadState(ArtifactsWorkspaceSettingsState state) {
+    myState = state;
+  }
+
+  public static class ArtifactsWorkspaceSettingsState {
+    @Tag("artifacts-to-build")
+    @AbstractCollection(surroundWithTag = false, elementTag = "artifact", elementValueAttribute = "name")
+    public List<String> myArtifactsToBuild = new ArrayList<String>();
+
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/CopyToDirectoryInstructionCreator.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/CopyToDirectoryInstructionCreator.java
new file mode 100644
index 0000000..3043468
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/CopyToDirectoryInstructionCreator.java
@@ -0,0 +1,63 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.packagingCompiler.ExplodedDestinationInfo;
+import com.intellij.compiler.impl.packagingCompiler.JarInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class CopyToDirectoryInstructionCreator extends IncrementalCompilerInstructionCreatorBase {
+  private final String myOutputPath;
+  private final @Nullable VirtualFile myOutputFile;
+
+  public CopyToDirectoryInstructionCreator(ArtifactsProcessingItemsBuilderContext context, String outputPath,
+                                           @Nullable VirtualFile outputFile) {
+    super(context);
+    myOutputPath = outputPath;
+    myOutputFile = outputFile;
+  }
+
+  public void addFileCopyInstruction(@NotNull VirtualFile file, @NotNull String outputFileName) {
+    myContext.addDestination(file, new ExplodedDestinationInfo(myOutputPath + "/" + outputFileName, outputChild(outputFileName)));
+  }
+
+  public CopyToDirectoryInstructionCreator subFolder(@NotNull String directoryName) {
+    return new CopyToDirectoryInstructionCreator(myContext, myOutputPath + "/" + directoryName, outputChild(directoryName));
+  }
+
+  public IncrementalCompilerInstructionCreator archive(@NotNull String archiveFileName) {
+    String jarOutputPath = myOutputPath + "/" + archiveFileName;
+    final JarInfo jarInfo = new JarInfo();
+    if (!myContext.registerJarFile(jarInfo, jarOutputPath)) {
+      return new SkipAllInstructionCreator(myContext);
+    }
+    VirtualFile outputFile = outputChild(archiveFileName);
+    final ExplodedDestinationInfo destination = new ExplodedDestinationInfo(jarOutputPath, outputFile);
+    jarInfo.addDestination(destination);
+    return new PackIntoArchiveInstructionCreator(myContext, jarInfo, "", destination);
+  }
+
+  @Nullable
+  private VirtualFile outputChild(String name) {
+    return myOutputFile != null ? myOutputFile.findChild(name) : null;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalCompilerInstructionCreatorBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalCompilerInstructionCreatorBase.java
new file mode 100644
index 0000000..9837b9f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/IncrementalCompilerInstructionCreatorBase.java
@@ -0,0 +1,98 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
+import com.intellij.packaging.elements.PackagingFileFilter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class IncrementalCompilerInstructionCreatorBase implements IncrementalCompilerInstructionCreator {
+  protected final ArtifactsProcessingItemsBuilderContext myContext;
+
+  public IncrementalCompilerInstructionCreatorBase(ArtifactsProcessingItemsBuilderContext context) {
+    myContext = context;
+  }
+
+  public void addDirectoryCopyInstructions(@NotNull VirtualFile directory) {
+    addDirectoryCopyInstructions(directory, null);
+  }
+
+  public void addDirectoryCopyInstructions(@NotNull VirtualFile directory, @Nullable PackagingFileFilter filter) {
+    final ProjectFileIndex index = ProjectRootManager.getInstance(myContext.getCompileContext().getProject()).getFileIndex();
+    final boolean copyExcluded = index.isIgnored(directory);
+    collectInstructionsRecursively(directory, this, filter, index, copyExcluded);
+  }
+
+  private static void collectInstructionsRecursively(VirtualFile directory,
+                                                     final IncrementalCompilerInstructionCreatorBase creator,
+                                                     @Nullable final PackagingFileFilter filter,
+                                                     final ProjectFileIndex index,
+                                                     final boolean copyExcluded) {
+    final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    VfsUtilCore.visitChildrenRecursively(directory, new VirtualFileVisitor<IncrementalCompilerInstructionCreatorBase>(VirtualFileVisitor.SKIP_ROOT) {
+      { setValueForChildren(creator); }
+
+      @Override
+      public boolean visitFile(@NotNull VirtualFile child) {
+        if (copyExcluded) {
+          if (fileTypeManager.isFileIgnored(child)) return false;
+        }
+        else {
+          if (index.isIgnored(child)) return false;
+        }
+
+        final IncrementalCompilerInstructionCreatorBase creator = getCurrentValue();
+        if (filter != null && !filter.accept(child, creator.myContext.getCompileContext())) {
+          return false;
+        }
+
+        if (!child.isDirectory()) {
+          creator.addFileCopyInstruction(child, child.getName());
+        }
+        else {
+          setValueForChildren(creator.subFolder(child.getName()));
+        }
+
+        return true;
+      }
+    });
+  }
+
+  @Override
+  public abstract IncrementalCompilerInstructionCreatorBase subFolder(@NotNull String directoryName);
+
+  public IncrementalCompilerInstructionCreator subFolderByRelativePath(@NotNull String relativeDirectoryPath) {
+    final List<String> folders = StringUtil.split(relativeDirectoryPath, "/");
+    IncrementalCompilerInstructionCreator current = this;
+    for (String folder : folders) {
+      current = current.subFolder(folder);
+    }
+    return current;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/PackIntoArchiveInstructionCreator.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/PackIntoArchiveInstructionCreator.java
new file mode 100644
index 0000000..c51b8e7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/PackIntoArchiveInstructionCreator.java
@@ -0,0 +1,66 @@
+/*
+ * 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.packaging.impl.compiler;
+
+import com.intellij.compiler.impl.packagingCompiler.DestinationInfo;
+import com.intellij.compiler.impl.packagingCompiler.JarDestinationInfo;
+import com.intellij.compiler.impl.packagingCompiler.JarInfo;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class PackIntoArchiveInstructionCreator extends IncrementalCompilerInstructionCreatorBase {
+  private final DestinationInfo myJarDestination;
+  private final JarInfo myJarInfo;
+  private final String myPathInJar;
+
+  public PackIntoArchiveInstructionCreator(ArtifactsProcessingItemsBuilderContext context, JarInfo jarInfo,
+                                           String pathInJar, DestinationInfo jarDestination) {
+    super(context);
+    myJarInfo = jarInfo;
+    myPathInJar = pathInJar;
+    myJarDestination = jarDestination;
+  }
+
+  public void addFileCopyInstruction(@NotNull VirtualFile file, @NotNull String outputFileName) {
+    final String pathInJar = childPathInJar(outputFileName);
+    if (myContext.addDestination(file, new JarDestinationInfo(pathInJar, myJarInfo, myJarDestination))) {
+      myJarInfo.addContent(pathInJar, file);
+    }
+  }
+
+  private String childPathInJar(String fileName) {
+    return myPathInJar.length() == 0 ? fileName : myPathInJar + "/" + fileName;
+  }
+
+  public PackIntoArchiveInstructionCreator subFolder(@NotNull String directoryName) {
+    return new PackIntoArchiveInstructionCreator(myContext, myJarInfo, childPathInJar(directoryName), myJarDestination);
+  }
+
+  public IncrementalCompilerInstructionCreator archive(@NotNull String archiveFileName) {
+    final JarInfo jarInfo = new JarInfo();
+    final String outputPath = myJarDestination.getOutputPath() + "/" + archiveFileName;
+    if (!myContext.registerJarFile(jarInfo, outputPath)) {
+      return new SkipAllInstructionCreator(myContext);
+    }
+    final JarDestinationInfo destination = new JarDestinationInfo(childPathInJar(archiveFileName), myJarInfo, myJarDestination);
+    jarInfo.addDestination(destination);
+    return new PackIntoArchiveInstructionCreator(myContext, jarInfo, "", destination);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/SkipAllInstructionCreator.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/SkipAllInstructionCreator.java
new file mode 100644
index 0000000..b7d409f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/SkipAllInstructionCreator.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.packaging.impl.compiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.IncrementalCompilerInstructionCreator;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class SkipAllInstructionCreator extends IncrementalCompilerInstructionCreatorBase {
+  public SkipAllInstructionCreator(ArtifactsProcessingItemsBuilderContext context) {
+    super(context);
+  }
+
+  public void addFileCopyInstruction(@NotNull VirtualFile file, @NotNull String outputFileName) {
+  }
+
+  public SkipAllInstructionCreator subFolder(@NotNull String directoryName) {
+    return this;
+  }
+
+  public IncrementalCompilerInstructionCreator archive(@NotNull String archiveFileName) {
+    return this;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java
new file mode 100644
index 0000000..0dca4cb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchiveElementType.java
@@ -0,0 +1,68 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.CompositePackagingElementType;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.ui.properties.ArchiveElementPropertiesPanel;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+* @author nik
+*/
+class ArchiveElementType extends CompositePackagingElementType<ArchivePackagingElement> {
+  ArchiveElementType() {
+    super("archive", CompilerBundle.message("element.type.name.archive"));
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return PlatformIcons.JAR_ICON;
+  }
+
+  @NotNull
+  @Override
+  public ArchivePackagingElement createEmpty(@NotNull Project project) {
+    return new ArchivePackagingElement();
+  }
+
+  @Override
+  public PackagingElementPropertiesPanel createElementPropertiesPanel(@NotNull ArchivePackagingElement element,
+                                                                                               @NotNull ArtifactEditorContext context) {
+    final String name = element.getArchiveFileName();
+    if (ArtifactUtil.isArchiveName(name)) {
+      return new ArchiveElementPropertiesPanel(element, context);
+    }
+    return null;
+  }
+
+  public CompositePackagingElement<?> createComposite(CompositePackagingElement<?> parent, @Nullable String baseName, @NotNull ArtifactEditorContext context) {
+    final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, baseName != null ? baseName : "archive", ".jar");
+    final String path = Messages.showInputDialog(context.getProject(), "Enter archive name: ", "New Archive", null, initialValue, new FilePathValidator());
+    if (path == null) return null;
+    return PackagingElementFactoryImpl.createDirectoryOrArchiveWithParents(path, true);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java
new file mode 100644
index 0000000..a144df7
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArchivePackagingElement.java
@@ -0,0 +1,118 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.Tag;
+import com.intellij.compiler.ant.artifacts.ArchiveAntCopyInstructionCreator;
+import com.intellij.compiler.ant.taskdefs.Jar;
+import com.intellij.compiler.ant.taskdefs.Zip;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.ArchiveElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArchivePackagingElement extends CompositeElementWithManifest<ArchivePackagingElement> {
+  @NonNls public static final String NAME_ATTRIBUTE = "name";
+  private String myArchiveFileName;
+
+  public ArchivePackagingElement() {
+    super(PackagingElementFactoryImpl.ARCHIVE_ELEMENT_TYPE);
+  }
+
+  public ArchivePackagingElement(@NotNull String archiveFileName) {
+    super(PackagingElementFactoryImpl.ARCHIVE_ELEMENT_TYPE);
+    myArchiveFileName = archiveFileName;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new ArchiveElementPresentation(this);
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    final String tempJarProperty = generationContext.createNewTempFileProperty("temp.jar.path." + myArchiveFileName, myArchiveFileName);
+    String jarPath = BuildProperties.propertyRef(tempJarProperty);
+    final Tag jar;
+    if (myArchiveFileName.endsWith(".jar")) {
+      jar = new Jar(jarPath, "preserve", true);
+    }
+    else {
+      jar = new Zip(jarPath);
+    }
+    for (Generator generator : computeChildrenGenerators(resolvingContext, new ArchiveAntCopyInstructionCreator(""), generationContext, artifactType)) {
+      jar.add(generator);
+    }
+    generationContext.runBeforeCurrentArtifact(jar);
+    return Collections.singletonList(creator.createFileCopyInstruction(jarPath, myArchiveFileName));
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    computeChildrenInstructions(creator.archive(myArchiveFileName), resolvingContext, compilerContext, artifactType);
+  }
+
+  @Attribute(NAME_ATTRIBUTE)
+  public String getArchiveFileName() {
+    return myArchiveFileName;
+  }
+
+  @NonNls @Override
+  public String toString() {
+    return "archive:" + myArchiveFileName;
+  }
+
+  public ArchivePackagingElement getState() {
+    return this;
+  }
+
+  public void setArchiveFileName(String archiveFileName) {
+    myArchiveFileName = archiveFileName;
+  }
+
+  public String getName() {
+    return myArchiveFileName;
+  }
+
+  public void rename(@NotNull String newName) {
+    myArchiveFileName = newName;
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof ArchivePackagingElement && ((ArchivePackagingElement)element).getArchiveFileName().equals(myArchiveFileName);
+  }
+
+  public void loadState(ArchivePackagingElement state) {
+    XmlSerializerUtil.copyBean(state, this);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactElementType.java
new file mode 100644
index 0000000..ed599a8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactElementType.java
@@ -0,0 +1,107 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ArtifactPointerManager;
+import com.intellij.packaging.elements.ComplexPackagingElementType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+* @author nik
+*/
+public class ArtifactElementType extends ComplexPackagingElementType<ArtifactPackagingElement> {
+  public static final ArtifactElementType ARTIFACT_ELEMENT_TYPE = new ArtifactElementType();
+
+  ArtifactElementType() {
+    super("artifact", CompilerBundle.message("element.type.name.artifact"));
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.Nodes.Artifact;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return !getAvailableArtifacts(context, artifact, false).isEmpty();
+  }
+
+  @NotNull
+  public List<? extends ArtifactPackagingElement> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                   @NotNull CompositePackagingElement<?> parent) {
+    final Project project = context.getProject();
+    List<Artifact> artifacts = context.chooseArtifacts(getAvailableArtifacts(context, artifact, false), CompilerBundle.message("dialog.title.choose.artifacts"));
+    final List<ArtifactPackagingElement> elements = new ArrayList<ArtifactPackagingElement>();
+    for (Artifact selected : artifacts) {
+      elements.add(new ArtifactPackagingElement(project, ArtifactPointerManager.getInstance(project).createPointer(selected, context.getArtifactModel())));
+    }
+    return elements;
+  }
+
+  @NotNull
+  public static List<? extends Artifact> getAvailableArtifacts(@NotNull final ArtifactEditorContext context,
+                                                               @NotNull final Artifact artifact,
+                                                               final boolean notIncludedOnly) {
+    final Set<Artifact> result = new HashSet<Artifact>(Arrays.asList(context.getArtifactModel().getArtifacts()));
+    if (notIncludedOnly) {
+      ArtifactUtil.processPackagingElements(artifact, ARTIFACT_ELEMENT_TYPE, new Processor<ArtifactPackagingElement>() {
+        public boolean process(ArtifactPackagingElement artifactPackagingElement) {
+          result.remove(artifactPackagingElement.findArtifact(context));
+          return true;
+        }
+      }, context, true);
+    }
+    result.remove(artifact);
+    final Iterator<Artifact> iterator = result.iterator();
+    while (iterator.hasNext()) {
+      Artifact another = iterator.next();
+      final boolean notContainThis =
+          ArtifactUtil.processPackagingElements(another, ARTIFACT_ELEMENT_TYPE, new Processor<ArtifactPackagingElement>() {
+            public boolean process(ArtifactPackagingElement element) {
+              return !artifact.getName().equals(element.getArtifactName());
+            }
+          }, context, true);
+      if (!notContainThis) {
+        iterator.remove();
+      }
+    }
+    final ArrayList<Artifact> list = new ArrayList<Artifact>(result);
+    Collections.sort(list, ArtifactManager.ARTIFACT_COMPARATOR);
+    return list;
+  }
+
+  @NotNull
+  public ArtifactPackagingElement createEmpty(@NotNull Project project) {
+    return new ArtifactPackagingElement(project);
+  }
+
+  @Override
+  public String getShowContentActionText() {
+    return "Show Content of Included Artifacts";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactPackagingElement.java
new file mode 100644
index 0000000..7d507b6
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactPackagingElement.java
@@ -0,0 +1,190 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import com.intellij.packaging.artifacts.ArtifactPointerManager;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.ArtifactElementPresentation;
+import com.intellij.packaging.impl.ui.DelegatedPackagingElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactPackagingElement extends ComplexPackagingElement<ArtifactPackagingElement.ArtifactPackagingElementState> {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.elements.ArtifactPackagingElement");
+  private final Project myProject;
+  private ArtifactPointer myArtifactPointer;
+  @NonNls public static final String ARTIFACT_NAME_ATTRIBUTE = "artifact-name";
+
+  public ArtifactPackagingElement(@NotNull Project project) {
+    super(ArtifactElementType.ARTIFACT_ELEMENT_TYPE);
+    myProject = project;
+  }
+
+  public ArtifactPackagingElement(@NotNull Project project, @NotNull ArtifactPointer artifactPointer) {
+    this(project);
+    myArtifactPointer = artifactPointer;
+  }
+
+  public List<? extends PackagingElement<?>> getSubstitution(@NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType) {
+    final Artifact artifact = findArtifact(context);
+    if (artifact != null) {
+      final ArtifactType type = artifact.getArtifactType();
+      List<? extends PackagingElement<?>> substitution = type.getSubstitution(artifact, context, artifactType);
+      if (substitution != null) {
+        return substitution;
+      }
+
+      final List<PackagingElement<?>> elements = new ArrayList<PackagingElement<?>>();
+      final CompositePackagingElement<?> rootElement = artifact.getRootElement();
+      if (rootElement instanceof ArtifactRootElement<?>) {
+        elements.addAll(rootElement.getChildren());
+      }
+      else {
+        elements.add(rootElement);
+      }
+      return elements;
+    }
+    return null;
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    final Artifact artifact = findArtifact(resolvingContext);
+    if (artifact != null) {
+      if (artifact.getArtifactType().getSubstitution(artifact, resolvingContext, artifactType) != null) {
+        return super.computeAntInstructions(resolvingContext, creator, generationContext, artifactType);
+      }
+      final String outputPath = BuildProperties.propertyRef(generationContext.getArtifactOutputProperty(artifact));
+      return Collections.singletonList(creator.createDirectoryContentCopyInstruction(outputPath));
+    }
+    return Collections.emptyList();
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext,
+                                                     @NotNull ArtifactType artifactType) {
+    Artifact artifact = findArtifact(resolvingContext);
+    if (artifact == null) return;
+
+    if (StringUtil.isEmpty(artifact.getOutputPath())
+        || artifact.getArtifactType().getSubstitution(artifact, resolvingContext, artifactType) != null) {
+      super.computeIncrementalCompilerInstructions(creator, resolvingContext, compilerContext, artifactType);
+      return;
+    }
+
+    VirtualFile outputFile = artifact.getOutputFile();
+    if (outputFile == null) {
+      LOG.debug("Output file for " + artifact + " not found");
+      return;
+    }
+    if (!outputFile.isValid()) {
+      LOG.debug("Output file for " + artifact + "(" + outputFile + ") is not valid");
+      return;
+    }
+
+    if (outputFile.isDirectory()) {
+      creator.addDirectoryCopyInstructions(outputFile);
+    }
+    else {
+      creator.addFileCopyInstruction(outputFile, outputFile.getName());
+    }
+  }
+
+  @Override
+  protected ArtifactType getArtifactTypeForSubstitutedElements(PackagingElementResolvingContext resolvingContext, ArtifactType artifactType) {
+    final Artifact artifact = findArtifact(resolvingContext);
+    if (artifact != null) {
+      return artifact.getArtifactType();
+    }
+    return artifactType;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new DelegatedPackagingElementPresentation(new ArtifactElementPresentation(myArtifactPointer, context));
+  }
+
+  public ArtifactPackagingElementState getState() {
+    final ArtifactPackagingElementState state = new ArtifactPackagingElementState();
+    if (myArtifactPointer != null) {
+      state.setArtifactName(myArtifactPointer.getArtifactName());
+    }
+    return state;
+  }
+
+  public void loadState(ArtifactPackagingElementState state) {
+    final String name = state.getArtifactName();
+    myArtifactPointer = name != null ? ArtifactPointerManager.getInstance(myProject).createPointer(name) : null;
+  }
+
+  @Override
+  public String toString() {
+    return "artifact:" + getArtifactName();
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof ArtifactPackagingElement && myArtifactPointer != null
+           && myArtifactPointer.equals(((ArtifactPackagingElement)element).myArtifactPointer);
+  }
+
+  @Nullable
+  public Artifact findArtifact(@NotNull PackagingElementResolvingContext context) {
+    return myArtifactPointer != null ? myArtifactPointer.findArtifact(context.getArtifactModel()) : null;
+  }
+
+  @Nullable
+  public String getArtifactName() {
+    return myArtifactPointer != null ? myArtifactPointer.getArtifactName() : null;
+  }
+
+
+  public static class ArtifactPackagingElementState {
+    private String myArtifactName;
+
+    @Attribute(ARTIFACT_NAME_ATTRIBUTE)
+    public String getArtifactName() {
+      return myArtifactName;
+    }
+
+    public void setArtifactName(String artifactName) {
+      myArtifactName = artifactName;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactRootElementImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactRootElementImpl.java
new file mode 100644
index 0000000..5fcba6f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ArtifactRootElementImpl.java
@@ -0,0 +1,96 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactRootElementImpl extends ArtifactRootElement<Object> {
+  public ArtifactRootElementImpl() {
+    super(PackagingElementFactoryImpl.ARTIFACT_ROOT_ELEMENT_TYPE);
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new PackagingElementPresentation() {
+      @Override
+      public String getPresentableName() {
+        return CompilerBundle.message("packaging.element.text.output.root");
+      }
+
+      @Override
+      public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes,
+                         SimpleTextAttributes commentAttributes) {
+        presentationData.setIcon(AllIcons.Nodes.Artifact);
+        presentationData.addText(getPresentableName(), mainAttributes);
+      }
+
+      @Override
+      public int getWeight() {
+        return 0;
+      }
+    };
+  }
+
+  public Object getState() {
+    return null;
+  }
+
+  public void loadState(Object state) {
+  }
+
+  @Override
+  public boolean canBeRenamed() {
+    return false;
+  }
+
+  public void rename(@NotNull String newName) {
+  }
+
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    return computeChildrenGenerators(resolvingContext, creator, generationContext, artifactType);
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    computeChildrenInstructions(creator, resolvingContext, compilerContext, artifactType);
+  }
+
+  public String getName() {
+    return "";
+  }
+
+  @Override
+  public String toString() {
+    return "<root>";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/CompositeElementWithManifest.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/CompositeElementWithManifest.java
new file mode 100644
index 0000000..fcaf889
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/CompositeElementWithManifest.java
@@ -0,0 +1,28 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+
+/**
+ * @author nik
+ */
+public abstract class CompositeElementWithManifest<T> extends CompositePackagingElement<T> {
+  protected CompositeElementWithManifest(PackagingElementType type) {
+    super(type);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyElementType.java
new file mode 100644
index 0000000..bc7258d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyElementType.java
@@ -0,0 +1,69 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author nik
+*/
+public class DirectoryCopyElementType extends PackagingElementType<DirectoryCopyPackagingElement> {
+
+  DirectoryCopyElementType() {
+    super("dir-copy", "Directory Content");
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.Nodes.CopyOfFolder;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return true;
+  }
+
+  @NotNull
+  public List<? extends DirectoryCopyPackagingElement> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                   @NotNull CompositePackagingElement<?> parent) {
+    final FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createMultipleFoldersDescriptor();
+    final VirtualFile[] files = FileChooser.chooseFiles(descriptor, context.getProject(), null);
+    final List<DirectoryCopyPackagingElement> list = new ArrayList<DirectoryCopyPackagingElement>();
+    for (VirtualFile file : files) {
+      list.add(new DirectoryCopyPackagingElement(file.getPath()));
+    }
+    return list;
+  }
+
+  @NotNull
+  public DirectoryCopyPackagingElement createEmpty(@NotNull Project project) {
+    return new DirectoryCopyPackagingElement();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyPackagingElement.java
new file mode 100644
index 0000000..c5c10dc
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryCopyPackagingElement.java
@@ -0,0 +1,80 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.DirectoryCopyPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class DirectoryCopyPackagingElement extends FileOrDirectoryCopyPackagingElement<DirectoryCopyPackagingElement> {
+  public DirectoryCopyPackagingElement() {
+    super(PackagingElementFactoryImpl.DIRECTORY_COPY_ELEMENT_TYPE);
+  }
+
+  public DirectoryCopyPackagingElement(String directoryPath) {
+    this();
+    myFilePath = directoryPath;
+  }
+
+  @Override
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new DirectoryCopyPresentation(myFilePath);
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext,
+                                                          @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    final String path = generationContext.getSubstitutedPath(myFilePath);
+    return Collections.singletonList(creator.createDirectoryContentCopyInstruction(path));
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext,
+                                                     @NotNull ArtifactType artifactType) {
+    final VirtualFile file = findFile();
+    if (file != null && file.isValid() && file.isDirectory()) {
+      creator.addDirectoryCopyInstructions(file);
+    }
+  }
+
+  public DirectoryCopyPackagingElement getState() {
+    return this;
+  }
+
+  public void loadState(DirectoryCopyPackagingElement state) {
+    myFilePath = state.getFilePath();
+  }
+
+  @Override
+  public String toString() {
+    return "dir:" + myFilePath;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.java
new file mode 100644
index 0000000..5732faf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryElementType.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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.CompositePackagingElementType;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.ui.properties.DirectoryElementPropertiesPanel;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+* @author nik
+*/
+class DirectoryElementType extends CompositePackagingElementType<DirectoryPackagingElement> {
+
+  DirectoryElementType() {
+    super("directory", CompilerBundle.message("element.type.name.directory"));
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.Actions.NewFolder;
+  }
+
+  @NotNull
+  public DirectoryPackagingElement createEmpty(@NotNull Project project) {
+    return new DirectoryPackagingElement();
+  }
+
+  @Override
+  public PackagingElementPropertiesPanel createElementPropertiesPanel(@NotNull DirectoryPackagingElement element,
+                                                                                                 @NotNull ArtifactEditorContext context) {
+    if (ArtifactUtil.isArchiveName(element.getDirectoryName())) {
+      return new DirectoryElementPropertiesPanel(element, context);
+    }
+    return null;
+  }
+
+  public CompositePackagingElement<?> createComposite(CompositePackagingElement<?> parent, String baseName, @NotNull ArtifactEditorContext context) {
+    final String initialValue = PackagingElementFactoryImpl.suggestFileName(parent, baseName != null ? baseName : "folder", "");
+    String path = Messages.showInputDialog(context.getProject(), "Enter directory name: ", "New Directory", null, initialValue, new FilePathValidator());
+    if (path == null) return null;
+    return PackagingElementFactoryImpl.createDirectoryOrArchiveWithParents(path, false);
+  }
+
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryPackagingElement.java
new file mode 100644
index 0000000..0fd3a34
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/DirectoryPackagingElement.java
@@ -0,0 +1,109 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.DirectoryElementPresentation;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.util.xmlb.annotations.Attribute;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author nik
+ *
+ * classpath is used for exploded WAR and EJB directories under exploded EAR
+ */
+public class DirectoryPackagingElement extends CompositeElementWithManifest<DirectoryPackagingElement> {
+  @NonNls public static final String NAME_ATTRIBUTE = "name";
+  private String myDirectoryName;
+
+  public DirectoryPackagingElement() {
+    super(PackagingElementFactoryImpl.DIRECTORY_ELEMENT_TYPE);
+  }
+
+  public DirectoryPackagingElement(String directoryName) {
+    super(PackagingElementFactoryImpl.DIRECTORY_ELEMENT_TYPE);
+    myDirectoryName = directoryName;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new DirectoryElementPresentation(this); 
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+
+    final List<Generator> children = new ArrayList<Generator>();
+    final Generator command = creator.createSubFolderCommand(myDirectoryName);
+    if (command != null) {
+      children.add(command);
+    }
+    children.addAll(computeChildrenGenerators(resolvingContext, creator.subFolder(myDirectoryName), generationContext, artifactType));
+    return children;
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    computeChildrenInstructions(creator.subFolder(myDirectoryName), resolvingContext, compilerContext, artifactType);
+  }
+
+  public DirectoryPackagingElement getState() {
+    return this;
+  }
+
+  @NonNls @Override
+  public String toString() {
+    return "dir:" + myDirectoryName;
+  }
+
+  @Attribute(NAME_ATTRIBUTE)
+  public String getDirectoryName() {
+    return myDirectoryName;
+  }
+
+  public void setDirectoryName(String directoryName) {
+    myDirectoryName = directoryName;
+  }
+
+  public void rename(@NotNull String newName) {
+    myDirectoryName = newName;
+  }
+
+  public String getName() {
+    return myDirectoryName;
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof DirectoryPackagingElement && ((DirectoryPackagingElement)element).getDirectoryName().equals(myDirectoryName);
+  }
+
+  public void loadState(DirectoryPackagingElement state) {
+    XmlSerializerUtil.copyBean(state, this);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryElementType.java
new file mode 100644
index 0000000..8f487f3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryElementType.java
@@ -0,0 +1,77 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author nik
+*/
+public class ExtractedDirectoryElementType extends PackagingElementType<ExtractedDirectoryPackagingElement> {
+
+  ExtractedDirectoryElementType() {
+    super("extracted-dir", "Extracted Directory");
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.Nodes.ExtractedFolder;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return true;
+  }
+
+  @NotNull
+  public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                   @NotNull CompositePackagingElement<?> parent) {
+    final FileChooserDescriptor descriptor = new FileChooserDescriptor(false, true, true, false, true, true) {
+      @Override
+      public boolean isFileSelectable(VirtualFile file) {
+        if (file.isInLocalFileSystem() && file.isDirectory()) return false;
+        return super.isFileSelectable(file);
+      }
+    };
+    final VirtualFile[] files = FileChooser.chooseFiles(descriptor, context.getProject(), null);
+    final List<PackagingElement<?>> list = new ArrayList<PackagingElement<?>>();
+    final PackagingElementFactory factory = PackagingElementFactory.getInstance();
+    for (VirtualFile file : files) {
+      list.add(factory.createExtractedDirectory(file));
+    }
+    return list;
+  }
+
+  @NotNull
+  public ExtractedDirectoryPackagingElement createEmpty(@NotNull Project project) {
+    return new ExtractedDirectoryPackagingElement();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryPackagingElement.java
new file mode 100644
index 0000000..a0b4dda
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ExtractedDirectoryPackagingElement.java
@@ -0,0 +1,143 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.taskdefs.Include;
+import com.intellij.compiler.ant.taskdefs.Mkdir;
+import com.intellij.compiler.ant.taskdefs.PatternSet;
+import com.intellij.compiler.ant.taskdefs.Unzip;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.ExtractedDirectoryPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.PathUtil;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ExtractedDirectoryPackagingElement extends FileOrDirectoryCopyPackagingElement<ExtractedDirectoryPackagingElement> {
+  private String myPathInJar;
+
+  public ExtractedDirectoryPackagingElement() {
+    super(PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE);
+  }
+
+  public ExtractedDirectoryPackagingElement(String jarPath, String pathInJar) {
+    super(PackagingElementFactoryImpl.EXTRACTED_DIRECTORY_ELEMENT_TYPE, jarPath);
+    myPathInJar = pathInJar;
+    if (!StringUtil.startsWithChar(myPathInJar, '/')) {
+      myPathInJar = "/" + myPathInJar;
+    }
+    if (!StringUtil.endsWithChar(myPathInJar, '/')) {
+      myPathInJar += "/";
+    }
+  }
+
+  @Override
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new ExtractedDirectoryPresentation(this); 
+  }
+
+  @Override
+  public String toString() {
+    return "extracted:" + myFilePath + "!" + myPathInJar;
+  }
+
+  @Override
+  public VirtualFile findFile() {
+    final VirtualFile jarFile = super.findFile();
+    if (jarFile == null) return null;
+
+    final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jarFile);
+    if ("/".equals(myPathInJar)) return jarRoot;
+    return jarRoot != null ? jarRoot.findFileByRelativePath(myPathInJar) : null;
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext,
+                                                          @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    final String jarPath = generationContext.getSubstitutedPath(myFilePath);
+    final String pathInJar = StringUtil.trimStart(myPathInJar, "/");
+    if (pathInJar.length() == 0) {
+      return Collections.singletonList(creator.createExtractedDirectoryInstruction(jarPath));
+    }
+
+    final String archiveName = PathUtil.getFileName(myFilePath);
+    final String tempDirProperty = generationContext.createNewTempFileProperty("temp.unpacked.path." + archiveName, archiveName);
+    final String tempDirPath = BuildProperties.propertyRef(tempDirProperty);
+    generationContext.runBeforeCurrentArtifact(new Mkdir(tempDirPath));
+
+    final Unzip unzip = new Unzip(jarPath, tempDirPath);
+    final PatternSet patterns = new PatternSet(null);
+    patterns.add(new Include(pathInJar + "**"));
+    unzip.add(patterns);
+    generationContext.runBeforeCurrentArtifact(unzip);
+
+    return Collections.singletonList(creator.createDirectoryContentCopyInstruction(tempDirPath + "/" + pathInJar));
+  }
+
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext,
+                                                     @NotNull ArtifactType artifactType) {
+    final VirtualFile file = findFile();
+    if (file != null && file.isValid() && file.isDirectory()) {
+      creator.addDirectoryCopyInstructions(file);
+    }
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof ExtractedDirectoryPackagingElement && super.isEqualTo(element)
+           && Comparing.equal(myPathInJar, ((ExtractedDirectoryPackagingElement)element).getPathInJar());
+  }
+
+  @Override
+  public ExtractedDirectoryPackagingElement getState() {
+    return this;
+  }
+
+  @Override
+  public void loadState(ExtractedDirectoryPackagingElement state) {
+    myFilePath = state.getFilePath();
+    myPathInJar = state.getPathInJar();
+  }
+
+  @Attribute("path-in-jar")
+  public String getPathInJar() {
+    return myPathInJar;
+  }
+
+  public void setPathInJar(String pathInJar) {
+    myPathInJar = pathInJar;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElement.java
new file mode 100644
index 0000000..a34fdaf
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElement.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.facet.Facet;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface FacetBasedPackagingElement {
+  @Nullable
+  Facet findFacet(@NotNull PackagingElementResolvingContext context);
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
new file mode 100644
index 0000000..dc0383f
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FacetBasedPackagingElementType.java
@@ -0,0 +1,112 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.FacetTypeId;
+import com.intellij.facet.FacetTypeRegistry;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.ide.util.ChooseElementsDialog;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class FacetBasedPackagingElementType<E extends PackagingElement<?>, F extends Facet> extends PackagingElementType<E> {
+  private final FacetTypeId<F> myFacetType;
+
+  protected FacetBasedPackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName, FacetTypeId<F> facetType) {
+    super(id, presentableName);
+    myFacetType = facetType;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return !getFacets(context).isEmpty();
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
+  }
+
+  @NotNull
+  @Override
+  public List<? extends E> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact, @NotNull CompositePackagingElement<?> parent) {
+    final List<F> facets = getFacets(context);
+    ChooseFacetsDialog dialog = new ChooseFacetsDialog(context.getProject(), facets, getDialogTitle(), getDialogDescription());
+    dialog.show();
+    if (dialog.isOK()) {
+      final List<E> elements = new ArrayList<E>();
+      for (F facet : dialog.getChosenElements()) {
+        elements.add(createElement(context.getProject(), facet));
+      }
+      return elements;
+    }
+    return Collections.emptyList();
+  }
+
+  private List<F> getFacets(ArtifactEditorContext context) {
+    final Module[] modules = context.getModulesProvider().getModules();
+    final List<F> facets = new ArrayList<F>();
+    for (Module module : modules) {
+      facets.addAll(context.getFacetsProvider().getFacetsByType(module, myFacetType));
+    }
+    return facets;
+  }
+
+  protected abstract E createElement(Project project, F facet);
+
+  protected abstract String getDialogTitle();
+
+  protected abstract String getDialogDescription();
+
+  protected abstract String getItemText(F item);
+
+  @Nullable
+  protected Icon getIcon(F item) {
+    return FacetTypeRegistry.getInstance().findFacetType(myFacetType).getIcon();
+  }
+
+  private class ChooseFacetsDialog extends ChooseElementsDialog<F> {
+    private ChooseFacetsDialog(Project project, List<? extends F> items, String title, String description) {
+      super(project, items, title, description, true);
+    }
+
+    @Override
+    protected String getItemText(F item) {
+      return FacetBasedPackagingElementType.this.getItemText(item);
+    }
+
+    @Override
+    protected Icon getItemIcon(F item) {
+      return FacetBasedPackagingElementType.this.getIcon(item);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyElementType.java
new file mode 100644
index 0000000..ee3f52a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyElementType.java
@@ -0,0 +1,68 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author nik
+*/
+public class FileCopyElementType extends PackagingElementType<FileCopyPackagingElement> {
+
+  FileCopyElementType() {
+    super("file-copy", "File");
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.FileTypes.Text;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return true;
+  }
+
+  @NotNull
+  public List<? extends FileCopyPackagingElement> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                   @NotNull CompositePackagingElement<?> parent) {
+    final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, true, true, false, true);
+    final VirtualFile[] files = FileChooser.chooseFiles(descriptor, context.getProject(), null);
+    final List<FileCopyPackagingElement> list = new ArrayList<FileCopyPackagingElement>();
+    for (VirtualFile file : files) {
+      list.add(new FileCopyPackagingElement(file.getPath()));
+    }
+    return list;
+  }
+
+  @NotNull
+  public FileCopyPackagingElement createEmpty(@NotNull Project project) {
+    return new FileCopyPackagingElement();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java
new file mode 100644
index 0000000..6513c76
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileCopyPackagingElement.java
@@ -0,0 +1,141 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.impl.ui.FileCopyPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.PathUtil;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class FileCopyPackagingElement extends FileOrDirectoryCopyPackagingElement<FileCopyPackagingElement> implements RenameablePackagingElement {
+  @NonNls public static final String OUTPUT_FILE_NAME_ATTRIBUTE = "output-file-name";
+  private String myRenamedOutputFileName;
+
+  public FileCopyPackagingElement() {
+    super(PackagingElementFactoryImpl.FILE_COPY_ELEMENT_TYPE);
+  }
+
+  public FileCopyPackagingElement(String filePath) {
+    this();
+    myFilePath = filePath;
+  }
+
+  public FileCopyPackagingElement(String filePath, String outputFileName) {
+    this(filePath);
+    myRenamedOutputFileName = outputFileName;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new FileCopyPresentation(myFilePath, getOutputFileName());
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    if (isDirectory()) {
+      return Collections.emptyList();
+    }
+    final String path = generationContext.getSubstitutedPath(myFilePath);
+    return Collections.singletonList((Generator)creator.createFileCopyInstruction(path, getOutputFileName()));
+  }
+
+  public String getOutputFileName() {
+    return myRenamedOutputFileName != null ? myRenamedOutputFileName : PathUtil.getFileName(myFilePath);
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    final VirtualFile file = findFile();
+    if (file != null && file.isValid() && !file.isDirectory()) {
+      creator.addFileCopyInstruction(file, getOutputFileName());
+    }
+  }
+
+  @NonNls @Override
+  public String toString() {
+    return "file:" + myFilePath + (myRenamedOutputFileName != null ? ",rename to:" + myRenamedOutputFileName : "");
+  }
+
+  public boolean isDirectory() {
+    return new File(FileUtil.toSystemDependentName(myFilePath)).isDirectory();
+  }
+
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof FileCopyPackagingElement && super.isEqualTo(element)
+           && Comparing.equal(myRenamedOutputFileName, ((FileCopyPackagingElement)element).getRenamedOutputFileName());
+  }
+
+  public FileCopyPackagingElement getState() {
+    return this;
+  }
+
+  public void loadState(FileCopyPackagingElement state) {
+    setFilePath(state.getFilePath());
+    setRenamedOutputFileName(state.getRenamedOutputFileName());
+  }
+
+  @Nullable
+  @Attribute(OUTPUT_FILE_NAME_ATTRIBUTE)
+  public String getRenamedOutputFileName() {
+    return myRenamedOutputFileName;
+  }
+
+  public void setRenamedOutputFileName(String renamedOutputFileName) {
+    myRenamedOutputFileName = renamedOutputFileName;
+  }
+
+  public String getName() {
+    return getOutputFileName();
+  }
+
+  public boolean canBeRenamed() {
+    return !isDirectory();
+  }
+
+  public void rename(@NotNull String newName) {
+    myRenamedOutputFileName = newName.equals(PathUtil.getFileName(myFilePath)) ? null : newName;
+  }
+
+  @Nullable
+  public VirtualFile getLibraryRoot() {
+    final String url = VfsUtil.getUrlForLibraryRoot(new File(FileUtil.toSystemDependentName(getFilePath())));
+    return VirtualFileManager.getInstance().findFileByUrl(url);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileOrDirectoryCopyPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileOrDirectoryCopyPackagingElement.java
new file mode 100644
index 0000000..eca74ff
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FileOrDirectoryCopyPackagingElement.java
@@ -0,0 +1,63 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class FileOrDirectoryCopyPackagingElement<T extends FileOrDirectoryCopyPackagingElement> extends PackagingElement<T> {
+  @NonNls public static final String PATH_ATTRIBUTE = "path";
+  protected String myFilePath;
+
+  public FileOrDirectoryCopyPackagingElement(PackagingElementType type) {
+    super(type);
+  }
+
+  protected FileOrDirectoryCopyPackagingElement(PackagingElementType type, String filePath) {
+    super(type);
+    myFilePath = filePath;
+  }
+
+  @Nullable
+  public VirtualFile findFile() {
+    return LocalFileSystem.getInstance().findFileByPath(myFilePath);
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element instanceof FileOrDirectoryCopyPackagingElement &&
+           myFilePath != null &&
+           myFilePath.equals(((FileOrDirectoryCopyPackagingElement)element).getFilePath());
+  }
+
+  @Attribute(PATH_ATTRIBUTE)
+  public String getFilePath() {
+    return myFilePath;
+  }
+
+  public void setFilePath(String filePath) {
+    myFilePath = filePath;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/FilePathValidator.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FilePathValidator.java
new file mode 100644
index 0000000..c31e006
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/FilePathValidator.java
@@ -0,0 +1,45 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.ui.InputValidator;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.PathUtil;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+class FilePathValidator implements InputValidator {
+  public boolean checkInput(String inputString) {
+    final List<String> fileNames = StringUtil.split(FileUtil.toSystemIndependentName(inputString), "/");
+    if (fileNames.isEmpty()) {
+      return false;
+    }
+    for (String fileName : fileNames) {
+      if (!PathUtil.isValidFileName(fileName)) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  public boolean canClose(String inputString) {
+    return checkInput(inputString);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryElementType.java
new file mode 100644
index 0000000..591c50c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryElementType.java
@@ -0,0 +1,82 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ComplexPackagingElementType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+* @author nik
+*/
+public class LibraryElementType extends ComplexPackagingElementType<LibraryPackagingElement> {
+  public static final LibraryElementType LIBRARY_ELEMENT_TYPE = new LibraryElementType();
+
+  LibraryElementType() {
+    super("library", CompilerBundle.message("element.type.name.library.files"));
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return PlatformIcons.LIBRARY_ICON;
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return !getAllLibraries(context).isEmpty();
+  }
+
+  @NotNull
+  public List<? extends LibraryPackagingElement> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                  @NotNull CompositePackagingElement<?> parent) {
+    final List<Library> selected = context.chooseLibraries(ProjectBundle.message("dialog.title.packaging.choose.library"));
+    final List<LibraryPackagingElement> elements = new ArrayList<LibraryPackagingElement>();
+    for (Library library : selected) {
+      elements.add(new LibraryPackagingElement(library.getTable().getTableLevel(), library.getName(), null));
+    }
+    return elements;
+  }
+
+  private static List<Library> getAllLibraries(ArtifactEditorContext context) {
+    List<Library> libraries = new ArrayList<Library>();
+    ContainerUtil.addAll(libraries, LibraryTablesRegistrar.getInstance().getLibraryTable().getLibraries());
+    ContainerUtil.addAll(libraries, LibraryTablesRegistrar.getInstance().getLibraryTable(context.getProject()).getLibraries());
+    return libraries;
+  }
+
+  @NotNull
+  public LibraryPackagingElement createEmpty(@NotNull Project project) {
+    return new LibraryPackagingElement();
+  }
+
+  @Override
+  public String getShowContentActionText() {
+    return "Show Library Files";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryPackagingElement.java
new file mode 100644
index 0000000..d776410
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/LibraryPackagingElement.java
@@ -0,0 +1,181 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.ComplexPackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.ui.LibraryElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.PathUtil;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class LibraryPackagingElement extends ComplexPackagingElement<LibraryPackagingElement> {
+  @NonNls public static final String LIBRARY_NAME_ATTRIBUTE = "name";
+  @NonNls public static final String MODULE_NAME_ATTRIBUTE = "module-name";
+  @NonNls public static final String LIBRARY_LEVEL_ATTRIBUTE = "level";
+  private String myLevel;
+  private String myLibraryName;
+  private String myModuleName;
+
+  public LibraryPackagingElement() {
+    super(LibraryElementType.LIBRARY_ELEMENT_TYPE);
+  }
+
+  public LibraryPackagingElement(String level, String libraryName, String moduleName) {
+    super(LibraryElementType.LIBRARY_ELEMENT_TYPE);
+    myLevel = level;
+    myLibraryName = libraryName;
+    myModuleName = moduleName;
+  }
+
+  public List<? extends PackagingElement<?>> getSubstitution(@NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType) {
+    final Library library = findLibrary(context);
+    if (library != null) {
+      final VirtualFile[] files = library.getFiles(OrderRootType.CLASSES);
+      final List<PackagingElement<?>> elements = new ArrayList<PackagingElement<?>>();
+      for (VirtualFile file : files) {
+        final String path = FileUtil.toSystemIndependentName(PathUtil.getLocalPath(file));
+        elements.add(file.isDirectory() && file.isInLocalFileSystem() ? new DirectoryCopyPackagingElement(path) : new FileCopyPackagingElement(path));
+      }
+      return elements;
+    }
+    return null;
+  }
+
+  @NotNull
+  @Override
+  public PackagingElementOutputKind getFilesKind(PackagingElementResolvingContext context) {
+    final Library library = findLibrary(context);
+    return library != null ? getKindForLibrary(library) : PackagingElementOutputKind.OTHER;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new LibraryElementPresentation(myLibraryName, myLevel, myModuleName, findLibrary(context), context);
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    if (!(element instanceof LibraryPackagingElement)) {
+      return false;
+    }
+
+    LibraryPackagingElement packagingElement = (LibraryPackagingElement)element;
+    return myLevel != null && myLibraryName != null && myLevel.equals(packagingElement.getLevel())
+           && myLibraryName.equals(packagingElement.getLibraryName())
+           && Comparing.equal(myModuleName, packagingElement.getModuleName());
+  }
+
+  public LibraryPackagingElement getState() {
+    return this;
+  }
+
+  public void loadState(LibraryPackagingElement state) {
+    myLevel = state.getLevel();
+    myLibraryName = state.getLibraryName();
+    myModuleName = state.getModuleName();
+  }
+
+  @Attribute(LIBRARY_LEVEL_ATTRIBUTE)
+  public String getLevel() {
+    return myLevel;
+  }
+
+  public void setLevel(String level) {
+    myLevel = level;
+  }
+
+  @Attribute(LIBRARY_NAME_ATTRIBUTE)
+  public String getLibraryName() {
+    return myLibraryName;
+  }
+
+  public void setLibraryName(String libraryName) {
+    myLibraryName = libraryName;
+  }
+
+  @Attribute(MODULE_NAME_ATTRIBUTE)
+  public String getModuleName() {
+    return myModuleName;
+  }
+
+  public void setModuleName(String moduleName) {
+    myModuleName = moduleName;
+  }
+
+  @Override
+  public String toString() {
+    return "lib:" + myLibraryName + "(" + (myModuleName != null ? "module " + myModuleName: myLevel ) + ")";
+  }
+
+  @Nullable
+  public Library findLibrary(@NotNull PackagingElementResolvingContext context) {
+    if (myModuleName == null) {
+      return context.findLibrary(myLevel, myLibraryName);
+    }
+    final ModulesProvider modulesProvider = context.getModulesProvider();
+    final Module module = modulesProvider.getModule(myModuleName);
+    if (module != null) {
+      for (OrderEntry entry : modulesProvider.getRootModel(module).getOrderEntries()) {
+        if (entry instanceof LibraryOrderEntry) {
+          final LibraryOrderEntry libraryEntry = (LibraryOrderEntry)entry;
+          if (libraryEntry.isModuleLevel()) {
+            final String libraryName = libraryEntry.getLibraryName();
+            if (libraryName != null && libraryName.equals(myLibraryName)) {
+              return libraryEntry.getLibrary();
+            }
+          }
+        }
+      }
+    }
+    return null;
+  }
+
+  public static PackagingElementOutputKind getKindForLibrary(final Library library) {
+    boolean containsDirectories = false;
+    boolean containsJars = false;
+    for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) {
+      if (file.isInLocalFileSystem()) {
+        containsDirectories = true;
+      }
+      else {
+        containsJars = true;
+      }
+    }
+    return new PackagingElementOutputKind(containsDirectories, containsJars);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java
new file mode 100644
index 0000000..4aeda08
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ManifestFileUtil.java
@@ -0,0 +1,361 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.CommonBundle;
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.compiler.make.ManifestBuilder;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderEnumerator;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.artifacts.PackagingElementPath;
+import com.intellij.packaging.impl.artifacts.PackagingElementProcessor;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.ManifestFileConfiguration;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiMethodUtil;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.io.IOException;
+import java.io.InputStream;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+
+/**
+ * @author nik
+ */
+public class ManifestFileUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.ui.configuration.artifacts.ArtifactEditorContextImpl");
+  public static final String MANIFEST_PATH = JarFile.MANIFEST_NAME;
+  public static final String MANIFEST_FILE_NAME = PathUtil.getFileName(MANIFEST_PATH);
+  public static final String MANIFEST_DIR_NAME = PathUtil.getParentPath(MANIFEST_PATH);
+
+  private ManifestFileUtil() {
+  }
+
+  @Nullable
+  public static VirtualFile findManifestFile(@NotNull CompositePackagingElement<?> root, PackagingElementResolvingContext context, ArtifactType artifactType) {
+    return ArtifactUtil.findSourceFileByOutputPath(root, MANIFEST_PATH, context, artifactType);
+  }
+
+  @Nullable
+  public static VirtualFile suggestManifestFileDirectory(@NotNull CompositePackagingElement<?> root, PackagingElementResolvingContext context, ArtifactType artifactType) {
+    final VirtualFile metaInfDir = ArtifactUtil.findSourceFileByOutputPath(root, MANIFEST_DIR_NAME, context, artifactType);
+    if (metaInfDir != null) {
+      return metaInfDir;
+    }
+
+    final Ref<VirtualFile> sourceDir = Ref.create(null);
+    final Ref<VirtualFile> sourceFile = Ref.create(null);
+    ArtifactUtil.processElementsWithSubstitutions(root.getChildren(), context, artifactType, PackagingElementPath.EMPTY, new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+        if (element instanceof FileCopyPackagingElement) {
+          final VirtualFile file = ((FileCopyPackagingElement)element).findFile();
+          if (file != null) {
+            sourceFile.set(file);
+          }
+        }
+        else if (element instanceof DirectoryCopyPackagingElement) {
+          final VirtualFile file = ((DirectoryCopyPackagingElement)element).findFile();
+          if (file != null) {
+            sourceDir.set(file);
+            return false;
+          }
+        }
+        return true;
+      }
+    });
+
+    if (!sourceDir.isNull()) {
+      return sourceDir.get();
+    }
+
+
+    final Project project = context.getProject();
+    return suggestBaseDir(project, sourceFile.get());
+  }
+
+  @Nullable
+  public static VirtualFile suggestManifestFileDirectory(@NotNull Project project, @Nullable Module module) {
+    OrderEnumerator enumerator = module != null ? OrderEnumerator.orderEntries(module) : OrderEnumerator.orderEntries(project);
+    final VirtualFile[] files = enumerator.withoutDepModules().withoutLibraries().withoutSdk().productionOnly().sources().getRoots();
+    if (files.length > 0) {
+      return files[0];
+    }
+    return suggestBaseDir(project, null);
+  }
+
+
+  @Nullable
+  private static VirtualFile suggestBaseDir(@NotNull Project project, final @Nullable VirtualFile file) {
+    final VirtualFile[] contentRoots = ProjectRootManager.getInstance(project).getContentRoots();
+    if (file == null && contentRoots.length > 0) {
+      return contentRoots[0];
+    }
+
+    if (file != null) {
+      for (VirtualFile contentRoot : contentRoots) {
+        if (VfsUtil.isAncestor(contentRoot, file, false)) {
+          return contentRoot;
+        }
+      }
+    }
+
+    return project.getBaseDir();
+  }
+
+  public static Manifest readManifest(@NotNull VirtualFile manifestFile) {
+    try {
+      final InputStream inputStream = manifestFile.getInputStream();
+      final Manifest manifest;
+      try {
+        manifest = new Manifest(inputStream);
+      }
+      finally {
+        inputStream.close();
+      }
+      return manifest;
+    }
+    catch (IOException ignored) {
+      return new Manifest();
+    }
+  }
+
+  public static void updateManifest(@NotNull VirtualFile file, final @Nullable String mainClass, final @Nullable List<String> classpath, final boolean replaceValues) {
+    final Manifest manifest = readManifest(file);
+    final Attributes mainAttributes = manifest.getMainAttributes();
+
+    if (mainClass != null) {
+      mainAttributes.put(Attributes.Name.MAIN_CLASS, mainClass);
+    }
+    else if (replaceValues) {
+      mainAttributes.remove(Attributes.Name.MAIN_CLASS);
+    }
+
+    if (classpath != null && !classpath.isEmpty()) {
+      List<String> updatedClasspath;
+      if (replaceValues) {
+        updatedClasspath = classpath;
+      }
+      else {
+        updatedClasspath = new ArrayList<String>();
+        final String oldClasspath = (String)mainAttributes.get(Attributes.Name.CLASS_PATH);
+        if (!StringUtil.isEmpty(oldClasspath)) {
+          updatedClasspath.addAll(StringUtil.split(oldClasspath, " "));
+        }
+        for (String path : classpath) {
+          if (!updatedClasspath.contains(path)) {
+            updatedClasspath.add(path);
+          }
+        }
+      }
+      mainAttributes.put(Attributes.Name.CLASS_PATH, StringUtil.join(updatedClasspath, " "));
+    }
+    else if (replaceValues) {
+      mainAttributes.remove(Attributes.Name.CLASS_PATH);
+    }
+
+    ManifestBuilder.setVersionAttribute(mainAttributes);
+
+    try {
+      final OutputStream outputStream = file.getOutputStream(ManifestFileUtil.class);
+      try {
+        manifest.write(outputStream);
+      }
+      finally {
+        outputStream.close();
+      }
+    }
+    catch (IOException e) {
+      LOG.info(e);
+    }
+  }
+
+  @NotNull
+  public static ManifestFileConfiguration createManifestFileConfiguration(@NotNull VirtualFile manifestFile) {
+    final String path = manifestFile.getPath();
+    Manifest manifest = readManifest(manifestFile);
+    String mainClass = manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS);
+    final String classpathText = manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH);
+    final List<String> classpath = new ArrayList<String>();
+    if (classpathText != null) {
+      classpath.addAll(StringUtil.split(classpathText, " "));
+    }
+    return new ManifestFileConfiguration(path, classpath, mainClass, manifestFile.isWritable());
+  }
+
+  public static List<String> getClasspathForElements(List<? extends PackagingElement<?>> elements, PackagingElementResolvingContext context, final ArtifactType artifactType) {
+    final List<String> classpath = new ArrayList<String>();
+    final PackagingElementProcessor<PackagingElement<?>> processor = new PackagingElementProcessor<PackagingElement<?>>() {
+      @Override
+      public boolean process(@NotNull PackagingElement<?> element, @NotNull PackagingElementPath path) {
+        if (element instanceof FileCopyPackagingElement) {
+          final String fileName = ((FileCopyPackagingElement)element).getOutputFileName();
+          classpath.add(DeploymentUtil.appendToPath(path.getPathString(), fileName));
+        }
+        else if (element instanceof DirectoryCopyPackagingElement) {
+          classpath.add(path.getPathString());
+        }
+        else if (element instanceof ArchivePackagingElement) {
+          final String archiveName = ((ArchivePackagingElement)element).getName();
+          classpath.add(DeploymentUtil.appendToPath(path.getPathString(), archiveName));
+        }
+        return true;
+      }
+    };
+    for (PackagingElement<?> element : elements) {
+      ArtifactUtil.processPackagingElements(element, null, processor, context, true, artifactType);
+    }
+    return classpath;
+  }
+
+  @Nullable
+  public static VirtualFile showDialogAndCreateManifest(final ArtifactEditorContext context, final CompositePackagingElement<?> element) {
+    FileChooserDescriptor descriptor = createDescriptorForManifestDirectory();
+    final VirtualFile directory = suggestManifestFileDirectory(element, context, context.getArtifactType());
+    final VirtualFile file = FileChooser.chooseFile(descriptor, context.getProject(), directory);
+    if (file == null) {
+      return null;
+    }
+
+    return createManifestFile(file, context.getProject());
+  }
+
+  @Nullable
+  public static VirtualFile createManifestFile(final @NotNull VirtualFile directory, final @NotNull Project project) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
+    final Ref<IOException> exc = Ref.create(null);
+    final VirtualFile file = new WriteAction<VirtualFile>() {
+      protected void run(final Result<VirtualFile> result) {
+        VirtualFile dir = directory;
+        try {
+          if (!dir.getName().equals(MANIFEST_DIR_NAME)) {
+            dir = VfsUtil.createDirectoryIfMissing(dir, MANIFEST_DIR_NAME);
+          }
+          final VirtualFile file = dir.createChildData(this, MANIFEST_FILE_NAME);
+          final OutputStream output = file.getOutputStream(this);
+          try {
+            final Manifest manifest = new Manifest();
+            ManifestBuilder.setVersionAttribute(manifest.getMainAttributes());
+            manifest.write(output);
+          }
+          finally {
+            output.close();
+          }
+          result.setResult(file);
+        }
+        catch (IOException e) {
+          exc.set(e);
+        }
+      }
+    }.execute().getResultObject();
+
+    final IOException exception = exc.get();
+    if (exception != null) {
+      LOG.info(exception);
+      Messages.showErrorDialog(project, exception.getMessage(), CommonBundle.getErrorTitle());
+      return null;
+    }
+    return file;
+  }
+
+  public static FileChooserDescriptor createDescriptorForManifestDirectory() {
+    FileChooserDescriptor descriptor = FileChooserDescriptorFactory.createSingleFolderDescriptor();
+    descriptor.setTitle("Select Directory for META-INF/MANIFEST.MF file");
+    return descriptor;
+  }
+
+  public static void addManifestFileToLayout(final @NotNull String path, final @NotNull ArtifactEditorContext context,
+                                             final @NotNull CompositePackagingElement<?> element) {
+    context.editLayout(context.getArtifact(), new Runnable() {
+      public void run() {
+        final VirtualFile file = findManifestFile(element, context, context.getArtifactType());
+        if (file == null || !FileUtil.pathsEqual(file.getPath(), path)) {
+          PackagingElementFactory.getInstance().addFileCopy(element, MANIFEST_DIR_NAME, path, MANIFEST_FILE_NAME);
+        }
+      }
+    });
+  }
+
+  @Nullable
+  public static PsiClass selectMainClass(Project project, final @Nullable String initialClassName) {
+    final TreeClassChooserFactory chooserFactory = TreeClassChooserFactory.getInstance(project);
+    final GlobalSearchScope searchScope = GlobalSearchScope.allScope(project);
+    final PsiClass aClass = initialClassName != null ? JavaPsiFacade.getInstance(project).findClass(initialClassName, searchScope) : null;
+    final TreeClassChooser chooser =
+        chooserFactory.createWithInnerClassesScopeChooser("Select Main Class", searchScope, new MainClassFilter(), aClass);
+    chooser.showDialog();
+    return chooser.getSelected();
+  }
+
+  public static void setupMainClassField(final Project project, final TextFieldWithBrowseButton field) {
+    field.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        final PsiClass selected = selectMainClass(project, field.getText());
+        if (selected != null) {
+          field.setText(selected.getQualifiedName());
+        }
+      }
+    });
+  }
+
+  private static class MainClassFilter implements ClassFilter {
+    public boolean isAccepted(final PsiClass aClass) {
+      return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+        @Override
+        public Boolean compute() {
+          return PsiMethodUtil.MAIN_CLASS.value(aClass) && PsiMethodUtil.hasMainMethod(aClass);
+        }
+      });
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputElementTypeBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputElementTypeBase.java
new file mode 100644
index 0000000..6fed025
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputElementTypeBase.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectBundle;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ModuleOutputElementTypeBase<E extends ModuleOutputPackagingElementBase> extends PackagingElementType<E> {
+  public ModuleOutputElementTypeBase(String id, String presentableName) {
+    super(id, presentableName);
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return !getSuitableModules(context).isEmpty();
+  }
+
+  @NotNull
+  public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                       @NotNull CompositePackagingElement<?> parent) {
+    List<Module> suitableModules = getSuitableModules(context);
+    List<Module> selected = context.chooseModules(suitableModules, ProjectBundle.message("dialog.title.packaging.choose.module"));
+
+    final List<PackagingElement<?>> elements = new ArrayList<PackagingElement<?>>();
+    final ModulePointerManager pointerManager = ModulePointerManager.getInstance(context.getProject());
+    for (Module module : selected) {
+      elements.add(createElement(context.getProject(), pointerManager.create(module)));
+    }
+    return elements;
+  }
+
+  protected abstract ModuleOutputPackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer);
+
+  private List<Module> getSuitableModules(ArtifactEditorContext context) {
+    ModulesProvider modulesProvider = context.getModulesProvider();
+    ArrayList<Module> modules = new ArrayList<Module>();
+    for (Module module : modulesProvider.getModules()) {
+      if (isSuitableModule(modulesProvider, module)) {
+        modules.add(module);
+      }
+    }
+    return modules;
+  }
+
+  public abstract boolean isSuitableModule(ModulesProvider modulesProvider, Module module);
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElement.java
new file mode 100644
index 0000000..d73572d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElement.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.elements;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface ModuleOutputPackagingElement {
+  @Nullable
+  String getModuleName();
+
+  @Nullable
+  Module findModule(PackagingElementResolvingContext context);
+
+  @NotNull
+  Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context);
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElementBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElementBase.java
new file mode 100644
index 0000000..084cf6e
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ModuleOutputPackagingElementBase.java
@@ -0,0 +1,150 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.elements.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.xmlb.annotations.Attribute;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ModuleOutputPackagingElementBase extends PackagingElement<ModuleOutputPackagingElementBase.ModuleOutputPackagingElementState> implements ModuleOutputPackagingElement {
+  @NonNls public static final String MODULE_NAME_ATTRIBUTE = "name";
+  protected ModulePointer myModulePointer;
+  protected final Project myProject;
+
+  public ModuleOutputPackagingElementBase(PackagingElementType type, Project project, ModulePointer modulePointer) {
+    super(type);
+    myProject = project;
+    myModulePointer = modulePointer;
+  }
+
+  public ModuleOutputPackagingElementBase(PackagingElementType type, Project project) {
+    super(type);
+    myProject = project;
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    if (myModulePointer != null) {
+      final String moduleOutput = BuildProperties.propertyRef(getModuleOutputAntProperty(generationContext));
+      return Collections.singletonList(creator.createDirectoryContentCopyInstruction(moduleOutput));
+    }
+    return Collections.emptyList();
+  }
+
+  protected abstract String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext);
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    final Module module = findModule(resolvingContext);
+    if (module != null) {
+      final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+      if (extension != null) {
+        final VirtualFile output = getModuleOutputPath(extension);
+        if (output != null) {
+          creator.addDirectoryCopyInstructions(output, null);
+        }
+      }
+    }
+  }
+
+  @Nullable
+  protected abstract VirtualFile getModuleOutputPath(CompilerModuleExtension extension);
+
+  @NotNull
+  @Override
+  public PackagingElementOutputKind getFilesKind(PackagingElementResolvingContext context) {
+    return PackagingElementOutputKind.DIRECTORIES_WITH_CLASSES;
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return element.getClass() == getClass() && myModulePointer != null
+           && myModulePointer.equals(((ModuleOutputPackagingElementBase)element).myModulePointer);
+  }
+
+  public ModuleOutputPackagingElementState getState() {
+    final ModuleOutputPackagingElementState state = new ModuleOutputPackagingElementState();
+    if (myModulePointer != null) {
+      state.setModuleName(myModulePointer.getModuleName());
+    }
+    return state;
+  }
+
+  public void loadState(ModuleOutputPackagingElementState state) {
+    final String moduleName = state.getModuleName();
+    myModulePointer = moduleName != null ? ModulePointerManager.getInstance(myProject).create(moduleName) : null;
+  }
+
+  @Override
+  @Nullable
+  public String getModuleName() {
+    return myModulePointer != null ? myModulePointer.getModuleName() : null;
+  }
+
+  @Override
+  @Nullable
+  public Module findModule(PackagingElementResolvingContext context) {
+    if (myModulePointer != null) {
+      final Module module = myModulePointer.getModule();
+      final ModulesProvider modulesProvider = context.getModulesProvider();
+      if (module != null) {
+        if (modulesProvider instanceof DefaultModulesProvider//optimization
+           || ArrayUtil.contains(module, modulesProvider.getModules())) {
+          return module;
+        }
+      }
+      return modulesProvider.getModule(myModulePointer.getModuleName());
+    }
+    return null;
+  }
+
+  public static class ModuleOutputPackagingElementState {
+    private String myModuleName;
+
+    @Attribute(MODULE_NAME_ATTRIBUTE)
+    public String getModuleName() {
+      return myModuleName;
+    }
+
+    public void setModuleName(String moduleName) {
+      myModuleName = moduleName;
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java
new file mode 100644
index 0000000..0d1737b
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/PackagingElementFactoryImpl.java
@@ -0,0 +1,354 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModulePointerManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
+import com.intellij.openapi.roots.impl.libraries.LibraryTableImplUtil;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import com.intellij.packaging.artifacts.ArtifactPointerManager;
+import com.intellij.packaging.elements.*;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class PackagingElementFactoryImpl extends PackagingElementFactory {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.elements.PackagingElementFactoryImpl");
+  public static final PackagingElementType<DirectoryPackagingElement> DIRECTORY_ELEMENT_TYPE = new DirectoryElementType();
+  public static final PackagingElementType<ArchivePackagingElement> ARCHIVE_ELEMENT_TYPE = new ArchiveElementType();
+  public static final PackagingElementType<FileCopyPackagingElement> FILE_COPY_ELEMENT_TYPE = new FileCopyElementType();
+  public static final PackagingElementType<DirectoryCopyPackagingElement> DIRECTORY_COPY_ELEMENT_TYPE = new DirectoryCopyElementType();
+  public static final PackagingElementType<ExtractedDirectoryPackagingElement> EXTRACTED_DIRECTORY_ELEMENT_TYPE = new ExtractedDirectoryElementType();
+  public static final PackagingElementType<ArtifactRootElement<?>> ARTIFACT_ROOT_ELEMENT_TYPE = new ArtifactRootElementType();
+  private static final PackagingElementType[] STANDARD_TYPES = {
+      DIRECTORY_ELEMENT_TYPE, ARCHIVE_ELEMENT_TYPE,
+      LibraryElementType.LIBRARY_ELEMENT_TYPE, ProductionModuleOutputElementType.ELEMENT_TYPE, TestModuleOutputElementType.ELEMENT_TYPE,
+      ArtifactElementType.ARTIFACT_ELEMENT_TYPE, FILE_COPY_ELEMENT_TYPE, DIRECTORY_COPY_ELEMENT_TYPE, EXTRACTED_DIRECTORY_ELEMENT_TYPE
+  };
+
+  @NotNull
+  @Override
+  public PackagingElementType<?>[] getNonCompositeElementTypes() {
+    final List<PackagingElementType> elementTypes = new ArrayList<PackagingElementType>();
+    for (PackagingElementType elementType : getAllElementTypes()) {
+      if (!(elementType instanceof CompositePackagingElementType)) {
+        elementTypes.add(elementType);
+      }
+    }
+    return elementTypes.toArray(new PackagingElementType[elementTypes.size()]);
+  }
+
+  @Override
+  @NotNull
+  public ComplexPackagingElementType<?>[] getComplexElementTypes() {
+    List<ComplexPackagingElementType<?>> types = new ArrayList<ComplexPackagingElementType<?>>();
+    for (PackagingElementType type : getAllElementTypes()) {
+      if (type instanceof ComplexPackagingElementType) {
+        types.add((ComplexPackagingElementType)type);
+      }
+    }
+    return types.toArray(new ComplexPackagingElementType[types.size()]);
+  }
+
+  @NotNull
+  @Override
+  public CompositePackagingElementType<?>[] getCompositeElementTypes() {
+    final List<CompositePackagingElementType> elementTypes = new ArrayList<CompositePackagingElementType>();
+    for (PackagingElementType elementType : getAllElementTypes()) {
+      if (elementType instanceof CompositePackagingElementType) {
+        elementTypes.add((CompositePackagingElementType)elementType);
+      }
+    }
+    return elementTypes.toArray(new CompositePackagingElementType[elementTypes.size()]);
+  }
+
+  @Override
+  public PackagingElementType<?> findElementType(String id) {
+    for (PackagingElementType elementType : getAllElementTypes()) {
+      if (elementType.getId().equals(id)) {
+        return elementType;
+      }
+    }
+    if (id.equals(ARTIFACT_ROOT_ELEMENT_TYPE.getId())) {
+      return ARTIFACT_ROOT_ELEMENT_TYPE;
+    }
+    return null;
+  }
+
+  @NotNull
+  @Override
+  public PackagingElementType[] getAllElementTypes() {
+    final PackagingElementType[] types = Extensions.getExtensions(PackagingElementType.EP_NAME);
+    return ArrayUtil.mergeArrays(STANDARD_TYPES, types);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createArtifactElement(@NotNull Artifact artifact, @NotNull Project project) {
+    return new ArtifactPackagingElement(project, ArtifactPointerManager.getInstance(project).createPointer(artifact));
+  }
+
+  @NotNull
+  public DirectoryPackagingElement createDirectory(@NotNull @NonNls String directoryName) {
+    return new DirectoryPackagingElement(directoryName);
+  }
+
+  @NotNull
+  @Override
+  public ArtifactRootElement<?> createArtifactRootElement() {
+    return new ArtifactRootElementImpl();
+  }
+
+  @Override
+  @NotNull
+  public CompositePackagingElement<?> getOrCreateDirectory(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath) {
+    return getOrCreateDirectoryOrArchive(parent, relativePath, true);
+  }
+
+  @NotNull
+  @Override
+  public CompositePackagingElement<?> getOrCreateArchive(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath) {
+    return getOrCreateDirectoryOrArchive(parent, relativePath, false);
+  }
+
+  @Override
+  public void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath) {
+    addFileCopy(root, outputDirectoryPath, sourceFilePath, null);
+  }
+
+  @Override
+  public void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath,
+                          @Nullable String outputFileName) {
+    final String fileName = PathUtil.getFileName(sourceFilePath);
+    if (outputFileName != null && outputFileName.equals(fileName)) {
+      outputFileName = null;
+    }
+    getOrCreateDirectory(root, outputDirectoryPath).addOrFindChild(createFileCopy(sourceFilePath, outputFileName));
+  }
+
+  @NotNull
+  private CompositePackagingElement<?> getOrCreateDirectoryOrArchive(@NotNull CompositePackagingElement<?> root,
+                                                                     @NotNull @NonNls String path, final boolean directory) {
+    path = StringUtil.trimStart(StringUtil.trimEnd(path, "/"), "/");
+    if (path.length() == 0) {
+      return root;
+    }
+    int index = path.lastIndexOf('/');
+    String lastName = path.substring(index + 1);
+    String parentPath = index != -1 ? path.substring(0, index) : "";
+
+    final CompositePackagingElement<?> parent = getOrCreateDirectoryOrArchive(root, parentPath, true);
+    final CompositePackagingElement<?> last = directory ? createDirectory(lastName) : createArchive(lastName);
+    return parent.addOrFindChild(last);
+  }
+
+  @NotNull
+  public PackagingElement<?> createModuleOutput(@NotNull String moduleName, @NotNull Project project) {
+    final ModulePointer pointer = ModulePointerManager.getInstance(project).create(moduleName);
+    return new ProductionModuleOutputPackagingElement(project, pointer);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createModuleOutput(@NotNull Module module) {
+    final ModulePointer modulePointer = ModulePointerManager.getInstance(module.getProject()).create(module);
+    return new ProductionModuleOutputPackagingElement(module.getProject(), modulePointer);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createTestModuleOutput(@NotNull Module module) {
+    ModulePointer pointer = ModulePointerManager.getInstance(module.getProject()).create(module);
+    return new TestModuleOutputPackagingElement(module.getProject(), pointer);
+  }
+
+  @NotNull
+  @Override
+  public List<? extends PackagingElement<?>> createLibraryElements(@NotNull Library library) {
+    final LibraryTable table = library.getTable();
+    final String libraryName = library.getName();
+    if (table != null) {
+      return Collections.singletonList(createLibraryFiles(libraryName, table.getTableLevel(), null));
+    }
+    if (libraryName != null) {
+      final Module module = ((LibraryImpl)library).getModule();
+      if (module != null) {
+        return Collections.singletonList(createLibraryFiles(libraryName, LibraryTableImplUtil.MODULE_LEVEL, module.getName()));
+      }
+    }
+    final List<PackagingElement<?>> elements = new ArrayList<PackagingElement<?>>();
+    for (VirtualFile file : library.getFiles(OrderRootType.CLASSES)) {
+      final String path = FileUtil.toSystemIndependentName(PathUtil.getLocalPath(file));
+      elements.add(file.isDirectory() && file.isInLocalFileSystem() ? new DirectoryCopyPackagingElement(path) : new FileCopyPackagingElement(path));
+    }
+    return elements;
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createArtifactElement(@NotNull ArtifactPointer artifactPointer, @NotNull Project project) {
+    return new ArtifactPackagingElement(project, artifactPointer);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createLibraryFiles(@NotNull String libraryName, @NotNull String level, String moduleName) {
+    return new LibraryPackagingElement(level, libraryName, moduleName);
+  }
+
+  @NotNull
+  public CompositePackagingElement<?> createArchive(@NotNull @NonNls String archiveFileName) {
+    return new ArchivePackagingElement(archiveFileName);
+  }
+
+  @Nullable
+  private static PackagingElement<?> findArchiveOrDirectoryByName(@NotNull CompositePackagingElement<?> parent, @NotNull String name) {
+    for (PackagingElement<?> element : parent.getChildren()) {
+      if (element instanceof ArchivePackagingElement && ((ArchivePackagingElement)element).getArchiveFileName().equals(name) ||
+          element instanceof DirectoryPackagingElement && ((DirectoryPackagingElement)element).getDirectoryName().equals(name)) {
+        return element;
+      }
+    }
+    return null;
+  }
+
+  @NotNull
+  public static String suggestFileName(@NotNull CompositePackagingElement<?> parent, @NonNls @NotNull String prefix, @NonNls @NotNull String suffix) {
+    String name = prefix + suffix;
+    int i = 2;
+    while (findArchiveOrDirectoryByName(parent, name) != null) {
+      name = prefix + i++ + suffix;
+    }
+    return name;
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createDirectoryCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath) {
+    return createParentDirectories(relativeOutputPath, new DirectoryCopyPackagingElement(filePath));
+  }
+
+  @Override
+  @NotNull
+  public PackagingElement<?> createExtractedDirectoryWithParentDirectories(@NotNull String jarPath, @NotNull String pathInJar,
+                                                                           @NotNull String relativeOutputPath) {
+    return createParentDirectories(relativeOutputPath, new ExtractedDirectoryPackagingElement(jarPath, pathInJar));
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createExtractedDirectory(@NotNull VirtualFile jarEntry) {
+    LOG.assertTrue(jarEntry.getFileSystem() instanceof JarFileSystem, "Expected file from jar but file from " + jarEntry.getFileSystem() + " found");
+    final String fullPath = jarEntry.getPath();
+    final int jarEnd = fullPath.indexOf(JarFileSystem.JAR_SEPARATOR);
+    return new ExtractedDirectoryPackagingElement(fullPath.substring(0, jarEnd), fullPath.substring(jarEnd + 1));
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath) {
+    return createFileCopyWithParentDirectories(filePath, relativeOutputPath, null);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath,
+                                                                 @NotNull String relativeOutputPath,
+                                                                 @Nullable String outputFileName) {
+    return createParentDirectories(relativeOutputPath, createFileCopy(filePath, outputFileName));
+  }
+
+  @Override
+  public PackagingElement<?> createFileCopy(@NotNull String filePath, String outputFileName) {
+    return new FileCopyPackagingElement(filePath, outputFileName);
+  }
+
+  @NotNull
+  @Override
+  public PackagingElement<?> createParentDirectories(@NotNull String relativeOutputPath, @NotNull PackagingElement<?> element) {
+    return createParentDirectories(relativeOutputPath, Collections.singletonList(element)).get(0);
+  }
+
+  @NotNull
+  @Override
+  public List<? extends PackagingElement<?>> createParentDirectories(@NotNull String relativeOutputPath, @NotNull List<? extends PackagingElement<?>> elements) {
+    relativeOutputPath = StringUtil.trimStart(relativeOutputPath, "/");
+    if (relativeOutputPath.length() == 0) {
+      return elements;
+    }
+    int slash = relativeOutputPath.indexOf('/');
+    if (slash == -1) slash = relativeOutputPath.length();
+    String rootName = relativeOutputPath.substring(0, slash);
+    String pathTail = relativeOutputPath.substring(slash);
+    final DirectoryPackagingElement root = createDirectory(rootName);
+    final CompositePackagingElement<?> last = getOrCreateDirectory(root, pathTail);
+    last.addOrFindChildren(elements);
+    return Collections.singletonList(root);
+  }
+
+  public static CompositePackagingElement<?> createDirectoryOrArchiveWithParents(@NotNull String path, final boolean archive) {
+    path = FileUtil.toSystemIndependentName(path);
+    final String parentPath = PathUtil.getParentPath(path);
+    final String fileName = PathUtil.getFileName(path);
+    final PackagingElement<?> element = archive ? new ArchivePackagingElement(fileName) : new DirectoryPackagingElement(fileName);
+    return (CompositePackagingElement<?>)getInstance().createParentDirectories(parentPath, element);
+  }
+
+  private static class ArtifactRootElementType extends PackagingElementType<ArtifactRootElement<?>> {
+    protected ArtifactRootElementType() {
+      super("root", "");
+    }
+
+    @Override
+    public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+      return false;
+    }
+
+    @NotNull
+    public List<? extends ArtifactRootElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                   @NotNull CompositePackagingElement<?> parent) {
+      throw new UnsupportedOperationException("'create' not implemented in " + getClass().getName());
+    }
+
+    @NotNull
+    public ArtifactRootElement<?> createEmpty(@NotNull Project project) {
+      return new ArtifactRootElementImpl();
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputElementType.java
new file mode 100644
index 0000000..3ec8f0c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputElementType.java
@@ -0,0 +1,56 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+* @author nik
+*/
+public class ProductionModuleOutputElementType extends ModuleOutputElementTypeBase<ProductionModuleOutputPackagingElement> {
+  public static final ProductionModuleOutputElementType ELEMENT_TYPE = new ProductionModuleOutputElementType();
+
+  ProductionModuleOutputElementType() {
+    super("module-output", CompilerBundle.message("element.type.name.module.output"));
+  }
+
+  @NotNull
+  public ProductionModuleOutputPackagingElement createEmpty(@NotNull Project project) {
+    return new ProductionModuleOutputPackagingElement(project);
+  }
+
+  protected ModuleOutputPackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer) {
+    return new ProductionModuleOutputPackagingElement(project, pointer);
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return AllIcons.Nodes.Module;
+  }
+
+  @Override
+  public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
+    return modulesProvider.getRootModel(module).getSourceRootUrls(false).length > 0;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputPackagingElement.java
new file mode 100644
index 0000000..6ee8e8c
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/ProductionModuleOutputPackagingElement.java
@@ -0,0 +1,75 @@
+/*
+ * 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.packaging.impl.elements;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.ArtifactAntGenerationContext;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.ui.DelegatedPackagingElementPresentation;
+import com.intellij.packaging.impl.ui.ModuleElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @author nik
+ */
+public class ProductionModuleOutputPackagingElement extends ModuleOutputPackagingElementBase {
+  public ProductionModuleOutputPackagingElement(@NotNull Project project) {
+    super(ProductionModuleOutputElementType.ELEMENT_TYPE, project);
+  }
+
+  public ProductionModuleOutputPackagingElement(@NotNull Project project, @NotNull ModulePointer modulePointer) {
+    super(ProductionModuleOutputElementType.ELEMENT_TYPE, project, modulePointer);
+  }
+
+  @NonNls @Override
+  public String toString() {
+    return "module:" + getModuleName();
+  }
+
+  protected String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext) {
+    return generationContext.getModuleOutputPath(myModulePointer.getModuleName());
+  }
+
+  protected VirtualFile getModuleOutputPath(CompilerModuleExtension extension) {
+    return extension.getCompilerOutputPath();
+  }
+
+  @NotNull
+  @Override
+  public Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context) {
+    Module module = findModule(context);
+    if (module == null) return Collections.emptyList();
+
+    ModuleRootModel rootModel = context.getModulesProvider().getRootModel(module);
+    return Arrays.asList(rootModel.getSourceRoots(false));
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, false));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputElementType.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputElementType.java
new file mode 100644
index 0000000..c65cb16
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputElementType.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class TestModuleOutputElementType extends ModuleOutputElementTypeBase<TestModuleOutputPackagingElement> {
+  public static final TestModuleOutputElementType ELEMENT_TYPE = new TestModuleOutputElementType();
+
+  public TestModuleOutputElementType() {
+    super("module-test-output", CompilerBundle.message("element.type.name.module.test.output"));
+  }
+
+  @NotNull
+  @Override
+  public TestModuleOutputPackagingElement createEmpty(@NotNull Project project) {
+    return new TestModuleOutputPackagingElement(project);
+  }
+
+  protected ModuleOutputPackagingElementBase createElement(@NotNull Project project, @NotNull ModulePointer pointer) {
+    return new TestModuleOutputPackagingElement(project, pointer);
+  }
+
+  @Override
+  public Icon getCreateElementIcon() {
+    return PlatformIcons.TEST_SOURCE_FOLDER;
+  }
+
+  public boolean isSuitableModule(ModulesProvider modulesProvider, Module module) {
+    for (ContentEntry entry : modulesProvider.getRootModel(module).getContentEntries()) {
+      for (SourceFolder folder : entry.getSourceFolders()) {
+        if (folder.isTestSource()) return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputPackagingElement.java b/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputPackagingElement.java
new file mode 100644
index 0000000..f3110a0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/elements/TestModuleOutputPackagingElement.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2011 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.packaging.impl.elements;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.roots.SourceFolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.ArtifactAntGenerationContext;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.ui.DelegatedPackagingElementPresentation;
+import com.intellij.packaging.impl.ui.ModuleElementPresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.util.SmartList;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class TestModuleOutputPackagingElement extends ModuleOutputPackagingElementBase {
+  public TestModuleOutputPackagingElement(Project project) {
+    super(TestModuleOutputElementType.ELEMENT_TYPE, project);
+  }
+
+  public TestModuleOutputPackagingElement(Project project, ModulePointer modulePointer) {
+    super(TestModuleOutputElementType.ELEMENT_TYPE, project, modulePointer);
+  }
+
+  @Override
+  public String toString() {
+    return "module-tests:" + getModuleName();
+  }
+
+  protected String getModuleOutputAntProperty(ArtifactAntGenerationContext generationContext) {
+    return generationContext.getModuleTestOutputPath(myModulePointer.getModuleName());
+  }
+
+  protected VirtualFile getModuleOutputPath(CompilerModuleExtension extension) {
+    return extension.getCompilerOutputPathForTests();
+  }
+
+  @NotNull
+  @Override
+  public Collection<VirtualFile> getSourceRoots(PackagingElementResolvingContext context) {
+    Module module = findModule(context);
+    if (module == null) return Collections.emptyList();
+
+    List<VirtualFile> roots = new SmartList<VirtualFile>();
+    ModuleRootModel rootModel = context.getModulesProvider().getRootModel(module);
+    for (ContentEntry entry : rootModel.getContentEntries()) {
+      for (SourceFolder folder : entry.getSourceFolders()) {
+        if (folder.isTestSource()) {
+          ContainerUtil.addIfNotNull(folder.getFile(), roots);
+        }
+      }
+    }
+    return roots;
+  }
+
+  public PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context) {
+    return new DelegatedPackagingElementPresentation(new ModuleElementPresentation(myModulePointer, context, true));
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/ArtifactChooser.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/ArtifactChooser.java
new file mode 100644
index 0000000..c6e7aca
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/ArtifactChooser.java
@@ -0,0 +1,69 @@
+/*
+ * 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.packaging.impl.run;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.ElementsChooser;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import com.intellij.ui.JBColor;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ArtifactChooser extends ElementsChooser<ArtifactPointer> {
+  private static final Comparator<ArtifactPointer> ARTIFACT_COMPARATOR = new Comparator<ArtifactPointer>() {
+    public int compare(ArtifactPointer o1, ArtifactPointer o2) {
+      return o1.getArtifactName().compareToIgnoreCase(o2.getArtifactName());
+    }
+  };
+  private static final ElementProperties INVALID_ARTIFACT_PROPERTIES = new ElementProperties() {
+    public Icon getIcon() {
+      return AllIcons.Nodes.Artifact;
+    }
+
+    public Color getColor() {
+      return JBColor.RED;
+    }
+  };
+
+  public ArtifactChooser(List<ArtifactPointer> pointers) {
+    super(pointers, false);
+    for (ArtifactPointer pointer : pointers) {
+      if (pointer.getArtifact() == null) {
+        setElementProperties(pointer, INVALID_ARTIFACT_PROPERTIES);
+      }
+    }
+    sort(ARTIFACT_COMPARATOR);
+  }
+
+  @Override
+  protected String getItemText(@NotNull ArtifactPointer value) {
+    return value.getArtifactName();
+  }
+
+  @Override
+  protected Icon getItemIcon(@NotNull ArtifactPointer value) {
+    final Artifact artifact = value.getArtifact();
+    return artifact != null ? artifact.getArtifactType().getIcon() : null;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTask.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTask.java
new file mode 100644
index 0000000..690b679
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTask.java
@@ -0,0 +1,117 @@
+/*
+ * 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.packaging.impl.run;
+
+import com.intellij.execution.BeforeRunTask;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import com.intellij.packaging.artifacts.ArtifactPointerManager;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class BuildArtifactsBeforeRunTask extends BeforeRunTask<BuildArtifactsBeforeRunTask> {
+  @NonNls public static final String NAME_ATTRIBUTE = "name";
+  @NonNls public static final String ARTIFACT_ELEMENT = "artifact";
+  private List<ArtifactPointer> myArtifactPointers = new ArrayList<ArtifactPointer>();
+  private final Project myProject;
+
+  public BuildArtifactsBeforeRunTask(Project project) {
+    super(BuildArtifactsBeforeRunTaskProvider.ID);
+    myProject = project;
+  }
+
+  @Override
+  public void readExternal(Element element) {
+    super.readExternal(element);
+    final List<Element> children = element.getChildren(ARTIFACT_ELEMENT);
+    final ArtifactPointerManager pointerManager = ArtifactPointerManager.getInstance(myProject);
+    for (Element child : children) {
+      myArtifactPointers.add(pointerManager.createPointer(child.getAttributeValue(NAME_ATTRIBUTE)));
+    }
+  }
+
+  @Override
+  public void writeExternal(Element element) {
+    super.writeExternal(element);
+    for (ArtifactPointer pointer : myArtifactPointers) {
+      element.addContent(new Element(ARTIFACT_ELEMENT).setAttribute(NAME_ATTRIBUTE, pointer.getArtifactName()));
+    }
+  }
+
+  @Override
+  public BeforeRunTask clone() {
+    final BuildArtifactsBeforeRunTask task = (BuildArtifactsBeforeRunTask)super.clone();
+    task.myArtifactPointers = new ArrayList<ArtifactPointer>(myArtifactPointers);
+    return task;
+  }
+
+  @Override
+  public int getItemsCount() {
+    return myArtifactPointers.size();
+  }
+
+  public List<ArtifactPointer> getArtifactPointers() {
+    return Collections.unmodifiableList(myArtifactPointers);
+  }
+
+  public void setArtifactPointers(List<ArtifactPointer> artifactPointers) {
+    myArtifactPointers = new ArrayList<ArtifactPointer>(artifactPointers);
+  }
+
+  public void addArtifact(Artifact artifact) {
+    final ArtifactPointer pointer = ArtifactPointerManager.getInstance(myProject).createPointer(artifact);
+    if (!myArtifactPointers.contains(pointer)) {
+      myArtifactPointers.add(pointer);
+    }
+  }
+
+  public void removeArtifact(@NotNull Artifact artifact) {
+    removeArtifact(ArtifactPointerManager.getInstance(myProject).createPointer(artifact));
+  }
+
+  public void removeArtifact(final @NotNull ArtifactPointer pointer) {
+    myArtifactPointers.remove(pointer);
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+    if (!super.equals(o)) return false;
+
+    BuildArtifactsBeforeRunTask that = (BuildArtifactsBeforeRunTask)o;
+
+    if (!myArtifactPointers.equals(that.myArtifactPointers)) return false;
+    if (!myProject.equals(that.myProject)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result = super.hashCode();
+    result = 31 * result + myArtifactPointers.hashCode();
+    result = 31 * result + myProject.hashCode();
+    return result;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java
new file mode 100644
index 0000000..a1fa1b4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/run/BuildArtifactsBeforeRunTaskProvider.java
@@ -0,0 +1,260 @@
+/*
+ * 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.packaging.impl.run;
+
+import com.intellij.execution.BeforeRunTask;
+import com.intellij.execution.BeforeRunTaskProvider;
+import com.intellij.execution.RunManagerEx;
+import com.intellij.execution.configurations.RunConfiguration;
+import com.intellij.execution.impl.ConfigurationSettingsEditorWrapper;
+import com.intellij.execution.runners.ExecutionEnvironment;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.DataContext;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ModalityState;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.compiler.Compiler;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogBuilder;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.Ref;
+import com.intellij.packaging.artifacts.*;
+import com.intellij.packaging.impl.compiler.ArtifactAwareCompiler;
+import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
+import com.intellij.packaging.impl.compiler.ArtifactsCompiler;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.containers.ContainerUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public class BuildArtifactsBeforeRunTaskProvider extends BeforeRunTaskProvider<BuildArtifactsBeforeRunTask> {
+  @NonNls public static final String BUILD_ARTIFACTS_ID = "BuildArtifacts";
+  public static final Key<BuildArtifactsBeforeRunTask> ID = Key.create(BUILD_ARTIFACTS_ID);
+  private final Project myProject;
+
+  public BuildArtifactsBeforeRunTaskProvider(Project project) {
+    myProject = project;
+    project.getMessageBus().connect().subscribe(ArtifactManager.TOPIC, new ArtifactAdapter() {
+      @Override
+      public void artifactRemoved(@NotNull Artifact artifact) {
+        final RunManagerEx runManager = RunManagerEx.getInstanceEx(myProject);
+        for (RunConfiguration configuration : runManager.getAllConfigurations()) {
+          final List<BuildArtifactsBeforeRunTask> tasks = runManager.getBeforeRunTasks(configuration, ID);
+          for (BuildArtifactsBeforeRunTask task : tasks) {
+            final String artifactName = artifact.getName();
+            final List<ArtifactPointer> pointersList = task.getArtifactPointers();
+            final ArtifactPointer[] pointers = pointersList.toArray(new ArtifactPointer[pointersList.size()]);
+            for (ArtifactPointer pointer : pointers) {
+              if (pointer.getArtifactName().equals(artifactName) && ArtifactManager.getInstance(myProject).findArtifact(artifactName) == null) {
+                task.removeArtifact(pointer);
+              }
+            }
+          }
+        }
+      }
+    });
+  }
+
+  public Key<BuildArtifactsBeforeRunTask> getId() {
+    return ID;
+  }
+
+  @Override
+  public Icon getIcon() {
+    return AllIcons.Nodes.Artifact;
+  }
+
+  @Override
+  public String getName() {
+    return CompilerBundle.message("build.artifacts.before.run.description.empty");
+  }
+
+  @Override
+  public Icon getTaskIcon(BuildArtifactsBeforeRunTask task) {
+    List<ArtifactPointer> pointers = task.getArtifactPointers();
+    if (pointers == null || pointers.isEmpty())
+      return getIcon();
+    Artifact artifact = pointers.get(0).getArtifact();
+    if (artifact == null)
+      return getIcon();
+    return artifact.getArtifactType().getIcon();
+  }
+
+  @Override
+  public String getDescription(BuildArtifactsBeforeRunTask task) {
+    final List<ArtifactPointer> pointers = task.getArtifactPointers();
+    if (pointers.isEmpty()) {
+      return CompilerBundle.message("build.artifacts.before.run.description.empty");
+    }
+    if (pointers.size() == 1) {
+      return CompilerBundle.message("build.artifacts.before.run.description.single", pointers.get(0).getArtifactName());
+    }
+    return CompilerBundle.message("build.artifacts.before.run.description.multiple", pointers.size());
+  }
+
+  public boolean isConfigurable() {
+    return true;
+  }
+
+  public BuildArtifactsBeforeRunTask createTask(RunConfiguration runConfiguration) {
+    if (myProject.isDefault()) return null;
+    return new BuildArtifactsBeforeRunTask(myProject);
+  }
+
+  public boolean configureTask(RunConfiguration runConfiguration, BuildArtifactsBeforeRunTask task) {
+    final Artifact[] artifacts = ArtifactManager.getInstance(myProject).getArtifacts();
+    Set<ArtifactPointer> pointers = new THashSet<ArtifactPointer>();
+    for (Artifact artifact : artifacts) {
+      pointers.add(ArtifactPointerManager.getInstance(myProject).createPointer(artifact));
+    }
+    pointers.addAll(task.getArtifactPointers());
+    ArtifactChooser chooser = new ArtifactChooser(new ArrayList<ArtifactPointer>(pointers));
+    chooser.markElements(task.getArtifactPointers());
+    chooser.setPreferredSize(new Dimension(400, 300));
+
+    DialogBuilder builder = new DialogBuilder(myProject);
+    builder.setTitle(CompilerBundle.message("build.artifacts.before.run.selector.title"));
+    builder.setDimensionServiceKey("#BuildArtifactsBeforeRunChooser");
+    builder.addOkAction();
+    builder.addCancelAction();
+    builder.setCenterPanel(chooser);
+    builder.setPreferedFocusComponent(chooser);
+    if (builder.show() == DialogWrapper.OK_EXIT_CODE) {
+      task.setArtifactPointers(chooser.getMarkedElements());
+      return true;
+    }
+    return false;
+  }
+
+  @Override
+  public boolean canExecuteTask(RunConfiguration configuration, BuildArtifactsBeforeRunTask task) {
+    for (ArtifactPointer pointer:  task.getArtifactPointers()) {
+      if (pointer.getArtifact() != null)
+        return true;
+    }
+    return false;
+  }
+
+  public boolean executeTask(DataContext context,
+                             RunConfiguration configuration,
+                             ExecutionEnvironment env,
+                             final BuildArtifactsBeforeRunTask task) {
+    final Ref<Boolean> result = Ref.create(false);
+    final Semaphore finished = new Semaphore();
+
+    final List<Artifact> artifacts = new ArrayList<Artifact>();
+    new ReadAction() {
+      protected void run(final Result result) {
+        for (ArtifactPointer pointer : task.getArtifactPointers()) {
+          ContainerUtil.addIfNotNull(pointer.getArtifact(), artifacts);
+        }
+      }
+    }.execute();
+    
+    final CompileStatusNotification callback = new CompileStatusNotification() {
+      public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+        result.set(!aborted && errors == 0);
+        finished.up();
+      }
+    };
+    final CompilerFilter compilerFilter = new CompilerFilter() {
+      public boolean acceptCompiler(Compiler compiler) {
+        return compiler instanceof ArtifactsCompiler
+               || compiler instanceof ArtifactAwareCompiler && ((ArtifactAwareCompiler)compiler).shouldRun(artifacts);
+      }
+    };
+
+    ApplicationManager.getApplication().invokeAndWait(new Runnable() {
+      public void run() {
+        final CompilerManager manager = CompilerManager.getInstance(myProject);
+        finished.down();
+        manager.make(ArtifactCompileScope.createArtifactsScope(myProject, artifacts), compilerFilter, callback);
+      }
+    }, ModalityState.NON_MODAL);
+
+    finished.waitFor();
+    return result.get();
+  }
+
+  public static void setBuildArtifactBeforeRunOption(@NotNull JComponent runConfigurationEditorComponent,
+                                                     Project project,
+                                                     @NotNull Artifact artifact,
+                                                     final boolean enable) {
+    final DataContext dataContext = DataManager.getInstance().getDataContext(runConfigurationEditorComponent);
+    final ConfigurationSettingsEditorWrapper editor = ConfigurationSettingsEditorWrapper.CONFIGURATION_EDITOR_KEY.getData(dataContext);
+    if (editor != null) {
+      List<BeforeRunTask> tasks = editor.getStepsBeforeLaunch();
+      List<BuildArtifactsBeforeRunTask> myTasks = new ArrayList<BuildArtifactsBeforeRunTask>();
+      for (BeforeRunTask task : tasks) {
+        if (task instanceof BuildArtifactsBeforeRunTask) {
+          myTasks.add((BuildArtifactsBeforeRunTask)task);
+        }
+      }
+      if (enable && myTasks.isEmpty()) {
+        BuildArtifactsBeforeRunTask task = new BuildArtifactsBeforeRunTask(project);
+        task.addArtifact(artifact);
+        task.setEnabled(true);
+        editor.addBeforeLaunchStep(task);
+      }
+      else {
+        for (BuildArtifactsBeforeRunTask task : myTasks) {
+          if (enable) {
+            task.addArtifact(artifact);
+            task.setEnabled(true);
+          }
+          else {
+            task.removeArtifact(artifact);
+            if (task.getArtifactPointers().isEmpty()) {
+              task.setEnabled(false);
+            }
+          }
+        }
+      }
+    }
+  }
+
+  public static void setBuildArtifactBeforeRun(@NotNull Project project, @NotNull RunConfiguration configuration, @NotNull Artifact artifact) {
+    RunManagerEx runManager = RunManagerEx.getInstanceEx(project);
+    final List<BuildArtifactsBeforeRunTask> buildArtifactsTasks = runManager.getBeforeRunTasks(configuration, ID);
+    if (buildArtifactsTasks.isEmpty()) { //Add new task if absent
+      BuildArtifactsBeforeRunTask task = new BuildArtifactsBeforeRunTask(project);
+      buildArtifactsTasks.add(task);
+      List<BeforeRunTask> tasks = runManager.getBeforeRunTasks(configuration);
+      tasks.add(task);
+      runManager.setBeforeRunTasks(configuration, tasks, false);
+    }
+
+    for (BuildArtifactsBeforeRunTask task : buildArtifactsTasks) {
+      task.setEnabled(true);
+      task.addArtifact(artifact);
+
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArchiveElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArchiveElementPresentation.java
new file mode 100644
index 0000000..d48b43a
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArchiveElementPresentation.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArchiveElementPresentation extends PackagingElementPresentation {
+  private final ArchivePackagingElement myElement;
+
+  public ArchiveElementPresentation(ArchivePackagingElement element) {
+    myElement = element;
+  }
+
+  public String getPresentableName() {
+    return myElement.getArchiveFileName();
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    presentationData.setIcon(PlatformIcons.JAR_ICON);
+    presentationData.addText(myElement.getArchiveFileName(), mainAttributes);
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.FILE_COPY;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactElementPresentation.java
new file mode 100644
index 0000000..27535c4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactElementPresentation.java
@@ -0,0 +1,76 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.packaging.ui.TreeNodePresentation;
+import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author nik
+ */
+public class ArtifactElementPresentation extends TreeNodePresentation {
+  private final ArtifactPointer myArtifactPointer;
+  private final ArtifactEditorContext myContext;
+
+  public ArtifactElementPresentation(ArtifactPointer artifactPointer, ArtifactEditorContext context) {
+    myArtifactPointer = artifactPointer;
+    myContext = context;
+  }
+
+  public String getPresentableName() {
+    return myArtifactPointer != null ? myArtifactPointer.getArtifactName(myContext.getArtifactModel()) : "<unknown>";
+  }
+
+  @Override
+  public boolean canNavigateToSource() {
+    return findArtifact() != null;
+  }
+
+  @Override
+  public void navigateToSource() {
+    final Artifact artifact = findArtifact();
+    if (artifact != null) {
+      myContext.selectArtifact(artifact);
+    }
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    final Artifact artifact = findArtifact();
+    Icon icon = artifact != null ? artifact.getArtifactType().getIcon() : AllIcons.Nodes.Artifact;
+    presentationData.setIcon(icon);
+    presentationData.addText(getPresentableName(), artifact != null ? mainAttributes : SimpleTextAttributes.ERROR_ATTRIBUTES);
+  }
+
+  @Nullable
+  private Artifact findArtifact() {
+    return myArtifactPointer != null ? myArtifactPointer.findArtifact(myContext.getArtifactModel()) : null;
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.ARTIFACT;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.java
new file mode 100644
index 0000000..c14e2a8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ArtifactProblemsHolderBase.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.packaging.impl.ui;
+
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.ui.ArtifactProblemsHolder;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactProblemsHolderBase implements ArtifactProblemsHolder {
+  private final PackagingElementResolvingContext myContext;
+
+  protected ArtifactProblemsHolderBase(PackagingElementResolvingContext context) {
+    myContext = context;
+  }
+
+  @NotNull
+  public PackagingElementResolvingContext getContext() {
+    return myContext;
+  }
+
+  public void registerError(@NotNull String message, @NotNull String problemTypeId) {
+    registerError(message, problemTypeId, null);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ChooseArtifactsDialog.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ChooseArtifactsDialog.java
new file mode 100644
index 0000000..0dcb2f4
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ChooseArtifactsDialog.java
@@ -0,0 +1,41 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.ide.util.ChooseElementsDialog;
+import com.intellij.packaging.artifacts.Artifact;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class ChooseArtifactsDialog extends ChooseElementsDialog<Artifact> {
+
+  public ChooseArtifactsDialog(Project project, List<? extends Artifact> items, String title, String description) {
+    super(project, items, title, description, true);
+  }
+
+  protected String getItemText(Artifact item) {
+    return item.getName();
+  }
+
+  protected Icon getItemIcon(Artifact item) {
+    return item.getArtifactType().getIcon();
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/DelegatedPackagingElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DelegatedPackagingElementPresentation.java
new file mode 100644
index 0000000..8c5ac7d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DelegatedPackagingElementPresentation.java
@@ -0,0 +1,63 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.TreeNodePresentation;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ui.SimpleTextAttributes;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class DelegatedPackagingElementPresentation extends PackagingElementPresentation {
+  private final TreeNodePresentation myDelegate;
+
+  public DelegatedPackagingElementPresentation(TreeNodePresentation delegate) {
+    myDelegate = delegate;
+  }
+
+  public String getPresentableName() {
+    return myDelegate.getPresentableName();
+  }
+
+  public String getSearchName() {
+    return myDelegate.getSearchName();
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    myDelegate.render(presentationData, mainAttributes, commentAttributes);
+  }
+
+  @Nullable
+  public String getTooltipText() {
+    return myDelegate.getTooltipText();
+  }
+
+  public boolean canNavigateToSource() {
+    return myDelegate.canNavigateToSource();
+  }
+
+  public void navigateToSource() {
+    myDelegate.navigateToSource();
+  }
+
+  public int getWeight() {
+    return myDelegate.getWeight();
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryCopyPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryCopyPresentation.java
new file mode 100644
index 0000000..52786c3
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryCopyPresentation.java
@@ -0,0 +1,75 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class DirectoryCopyPresentation extends PackagingElementPresentation {
+  private final String mySourcePath;
+  private final String mySourceFileName;
+  private final VirtualFile myFile;
+
+  public DirectoryCopyPresentation(String filePath) {
+    mySourceFileName = PathUtil.getFileName(filePath);
+
+    String parentPath;
+    myFile = LocalFileSystem.getInstance().findFileByPath(filePath);
+    if (myFile != null) {
+      final VirtualFile parent = myFile.getParent();
+      parentPath = parent != null ? FileUtil.toSystemDependentName(parent.getPath()) : "";
+    }
+    else {
+      parentPath = FileUtil.toSystemDependentName(PathUtil.getParentPath(filePath));
+    }
+
+    mySourcePath = parentPath;
+  }
+
+  public String getPresentableName() {
+    return mySourceFileName;
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    presentationData.setIcon(AllIcons.Nodes.CopyOfFolder);
+    if (myFile == null || !myFile.isDirectory()) {
+      mainAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
+      final VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(mySourcePath));
+      if (parentFile == null) {
+        commentAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
+      }
+    }
+    presentationData.addText(CompilerBundle.message("node.text.0.directory.content", mySourceFileName), mainAttributes);
+    presentationData.addText(" (" + mySourcePath + ")", commentAttributes);
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.DIRECTORY_COPY;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryElementPresentation.java
new file mode 100644
index 0000000..cfdf2bb
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/DirectoryElementPresentation.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.packaging.impl.elements.DirectoryPackagingElement;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class DirectoryElementPresentation extends PackagingElementPresentation {
+  private final DirectoryPackagingElement myElement;
+
+  public DirectoryElementPresentation(DirectoryPackagingElement element) {
+    myElement = element;
+  }
+
+  public String getPresentableName() {
+    return myElement.getDirectoryName();
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    presentationData.setIcon(PlatformIcons.DIRECTORY_CLOSED_ICON);
+    presentationData.addText(myElement.getDirectoryName(), mainAttributes);
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.DIRECTORY;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ExtractedDirectoryPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ExtractedDirectoryPresentation.java
new file mode 100644
index 0000000..6f9d0ac
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ExtractedDirectoryPresentation.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2010 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.packaging.impl.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.impl.elements.ExtractedDirectoryPackagingElement;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ExtractedDirectoryPresentation extends PackagingElementPresentation {
+  private final String myJarPath;
+  private final String myPathInJar;
+  private final VirtualFile myFile;
+
+  public ExtractedDirectoryPresentation(ExtractedDirectoryPackagingElement element) {
+    myFile = element.findFile();
+    myJarPath = element.getFilePath();
+    myPathInJar = element.getPathInJar();
+  }
+
+  public String getPresentableName() {
+    return PathUtil.getFileName(myJarPath) + myPathInJar;
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    presentationData.setIcon(AllIcons.Nodes.ExtractedFolder);
+    final String parentPath = PathUtil.getParentPath(myJarPath);
+    if (myFile == null || !myFile.isDirectory()) {
+      mainAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
+      final VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(parentPath);
+      if (parentFile == null) {
+        commentAttributes = SimpleTextAttributes.ERROR_ATTRIBUTES;
+      }
+    }
+    presentationData.addText("Extracted '" + PathUtil.getFileName(myJarPath) + myPathInJar + "'", mainAttributes);
+    presentationData.addText(" (" + parentPath + ")", commentAttributes);
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.EXTRACTED_DIRECTORY;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/FileCopyPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/FileCopyPresentation.java
new file mode 100644
index 0000000..bbd3304
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/FileCopyPresentation.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.packaging.impl.ui;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.presentation.VirtualFilePresentation;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class FileCopyPresentation extends PackagingElementPresentation {
+  private final String mySourcePath;
+  private final String myOutputFileName;
+  private final VirtualFile myFile;
+
+  public FileCopyPresentation(String filePath, String outputFileName) {
+    myOutputFileName = outputFileName;
+
+    String parentPath;
+    myFile = LocalFileSystem.getInstance().findFileByPath(filePath);
+    if (myFile != null) {
+      final VirtualFile parent = myFile.getParent();
+      parentPath = parent != null ? FileUtil.toSystemDependentName(parent.getPath()) : "";
+    }
+    else {
+      parentPath = FileUtil.toSystemDependentName(PathUtil.getParentPath(filePath));
+    }
+
+    String sourceFileName = PathUtil.getFileName(filePath);
+    if (!sourceFileName.equals(myOutputFileName)) {
+      mySourcePath = parentPath + "/" + sourceFileName;
+    }
+    else {
+      mySourcePath = parentPath;
+    }
+  }
+
+  public String getPresentableName() {
+    return myOutputFileName;
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    if (myFile != null && !myFile.isDirectory()) {
+      presentationData.setIcon(VirtualFilePresentation.getIcon(myFile));
+      presentationData.addText(myOutputFileName, mainAttributes);
+      presentationData.addText(" (" + mySourcePath + ")", commentAttributes);
+    }
+    else {
+      presentationData.setIcon(AllIcons.FileTypes.Text);
+      presentationData.addText(myOutputFileName, SimpleTextAttributes.ERROR_ATTRIBUTES);
+      final VirtualFile parentFile = LocalFileSystem.getInstance().findFileByPath(FileUtil.toSystemIndependentName(mySourcePath));
+      presentationData.addText("(" + mySourcePath + ")",
+                      parentFile != null ? commentAttributes : SimpleTextAttributes.ERROR_ATTRIBUTES);
+    }
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.FILE_COPY;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/LibraryElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/LibraryElementPresentation.java
new file mode 100644
index 0000000..44905f8
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/LibraryElementPresentation.java
@@ -0,0 +1,101 @@
+/*
+ * 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.packaging.impl.ui;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.impl.ModuleLibraryTable;
+import com.intellij.openapi.roots.impl.libraries.LibraryImpl;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.roots.libraries.LibraryTablePresentation;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class LibraryElementPresentation extends PackagingElementPresentation {
+  private final String myLevel;
+  private final String myModuleName;
+  private final Library myLibrary;
+  private final String myLibraryName;
+  private final ArtifactEditorContext myContext;
+
+  public LibraryElementPresentation(String libraryName, String level, @Nullable String moduleName, Library library, ArtifactEditorContext context) {
+    myLevel = level;
+    myModuleName = moduleName;
+    myLibrary = library;
+    myLibraryName = libraryName;
+    myContext = context;
+  }
+
+  public String getPresentableName() {
+    return myLibraryName;
+  }
+
+  @Override
+  public boolean canNavigateToSource() {
+    return myLibrary != null;
+  }
+
+  @Override
+  public void navigateToSource() {
+    myContext.selectLibrary(myLibrary);
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    if (myLibrary != null) {
+      presentationData.setIcon(PlatformIcons.LIBRARY_ICON);
+      presentationData.addText(myLibraryName, mainAttributes);
+      presentationData.addText(getLibraryTableComment(myLibrary), commentAttributes);
+    }
+    else {
+      presentationData.addText(myLibraryName + " (" + (myModuleName != null ? "module '" + myModuleName + "'" : myLevel) + ")", 
+                               SimpleTextAttributes.ERROR_ATTRIBUTES);
+    }
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.LIBRARY;
+  }
+
+  public static String getLibraryTableDisplayName(final Library library) {
+    LibraryTable table = library.getTable();
+    LibraryTablePresentation presentation = table != null ? table.getPresentation() : ModuleLibraryTable.MODULE_LIBRARY_TABLE_PRESENTATION;
+    return presentation.getDisplayName(false);
+  }
+
+  public static String getLibraryTableComment(final Library library) {
+    LibraryTable libraryTable = library.getTable();
+    String displayName;
+    if (libraryTable != null) {
+      displayName = libraryTable.getPresentation().getDisplayName(false);
+    }
+    else {
+      Module module = ((LibraryImpl)library).getModule();
+      String tableName = getLibraryTableDisplayName(library);
+      displayName = module != null ? "'" + module.getName() + "' " + tableName : tableName;
+    }
+    return " (" + displayName + ")";
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/ModuleElementPresentation.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ModuleElementPresentation.java
new file mode 100644
index 0000000..af59bc0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/ModuleElementPresentation.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.packaging.impl.ui;
+
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModulePointer;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementWeights;
+import com.intellij.packaging.ui.TreeNodePresentation;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.PlatformIcons;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public class ModuleElementPresentation extends TreeNodePresentation {
+  private final ModulePointer myModulePointer;
+  private final ArtifactEditorContext myContext;
+  private final boolean myTestOutput;
+
+  public ModuleElementPresentation(@Nullable ModulePointer modulePointer, @NotNull ArtifactEditorContext context, final boolean testOutput) {
+    myModulePointer = modulePointer;
+    myContext = context;
+    myTestOutput = testOutput;
+  }
+
+  public String getPresentableName() {
+    return myModulePointer != null ? myModulePointer.getModuleName() : "<unknown>";
+  }
+
+  @Override
+  public boolean canNavigateToSource() {
+    return findModule() != null;
+  }
+
+  @Nullable
+  private Module findModule() {
+    return myModulePointer != null ? myModulePointer.getModule() : null;
+  }
+
+  @Override
+  public void navigateToSource() {
+    final Module module = findModule();
+    if (module != null) {
+      myContext.selectModule(module);
+    }
+  }
+
+  public void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes, SimpleTextAttributes commentAttributes) {
+    final Module module = findModule();
+    if (myTestOutput) {
+      presentationData.setIcon(PlatformIcons.TEST_SOURCE_FOLDER);
+    }
+    else if (module != null) {
+      presentationData.setIcon(ModuleType.get(module).getIcon());
+    }
+    String moduleName;
+    if (module != null) {
+      moduleName = module.getName();
+      final ModifiableModuleModel moduleModel = myContext.getModifiableModuleModel();
+      if (moduleModel != null) {
+        final String newName = moduleModel.getNewName(module);
+        if (newName != null) {
+          moduleName = newName;
+        }
+      }
+    }
+    else if (myModulePointer != null) {
+      moduleName = myModulePointer.getModuleName();
+    }
+    else {
+      moduleName = "<unknown>";
+    }
+
+    String text = myTestOutput ? CompilerBundle.message("node.text.0.test.compile.output", moduleName)
+                               : CompilerBundle.message("node.text.0.compile.output", moduleName);
+    presentationData.addText(text, module != null ? mainAttributes : SimpleTextAttributes.ERROR_ATTRIBUTES);
+  }
+
+  @Override
+  public int getWeight() {
+    return PackagingElementWeights.MODULE;
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java
new file mode 100644
index 0000000..f72bd75
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileAction.java
@@ -0,0 +1,104 @@
+/**
+ * @author cdr
+ */
+package com.intellij.packaging.impl.ui.actions;
+
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.PlatformDataKeys;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.compiler.CompilerManager;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Clock;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.wm.WindowManager;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.impl.artifacts.ArtifactBySourceFileFinder;
+import com.intellij.util.text.SyncDateFormat;
+import org.jetbrains.annotations.NotNull;
+
+import java.text.SimpleDateFormat;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class PackageFileAction extends AnAction {
+  private static final SyncDateFormat TIME_FORMAT = new SyncDateFormat(new SimpleDateFormat("h:mm:ss a"));
+
+  public PackageFileAction() {
+    super(CompilerBundle.message("action.name.package.file"), CompilerBundle.message("action.description.package.file"), null);
+  }
+
+  @Override
+  public void update(AnActionEvent e) {
+    boolean visible = false;
+    final Project project = e.getData(PlatformDataKeys.PROJECT);
+    if (project != null) {
+      final List<VirtualFile> files = getFilesToPackage(e, project);
+      if (!files.isEmpty()) {
+        visible = true;
+        e.getPresentation().setText(files.size() == 1 ? CompilerBundle.message("action.name.package.file") : CompilerBundle.message("action.name.package.files"));
+      }
+    }
+
+    e.getPresentation().setVisible(visible);
+  }
+
+  @NotNull
+  private static List<VirtualFile> getFilesToPackage(@NotNull AnActionEvent e, @NotNull Project project) {
+    final VirtualFile[] files = e.getData(PlatformDataKeys.VIRTUAL_FILE_ARRAY);
+    if (files == null) return Collections.emptyList();
+
+    List<VirtualFile> result = new ArrayList<VirtualFile>();
+    ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    final CompilerManager compilerManager = CompilerManager.getInstance(project);
+    for (VirtualFile file : files) {
+      if (file == null || file.isDirectory() ||
+          fileIndex.isInSourceContent(file) && compilerManager.isCompilableFileType(file.getFileType())) {
+        return Collections.emptyList();
+      }
+      final Collection<? extends Artifact> artifacts = ArtifactBySourceFileFinder.getInstance(project).findArtifacts(file);
+      for (Artifact artifact : artifacts) {
+        if (!StringUtil.isEmpty(artifact.getOutputPath())) {
+          result.add(file);
+          break;
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public void actionPerformed(AnActionEvent event) {
+    final Project project = event.getData(PlatformDataKeys.PROJECT);
+    if (project == null) return;
+
+    FileDocumentManager.getInstance().saveAllDocuments();
+    final List<VirtualFile> files = getFilesToPackage(event, project);
+    Artifact[] allArtifacts = ArtifactManager.getInstance(project).getArtifacts();
+    PackageFileWorker.startPackagingFiles(project, files, allArtifacts, new Runnable() {
+      public void run() {
+        setStatusText(project, files);
+      }
+    });
+  }
+
+  private static void setStatusText(Project project, List<VirtualFile> files) {
+    if (!files.isEmpty()) {
+      StringBuilder fileNames = new StringBuilder();
+      for (VirtualFile file : files) {
+        if (fileNames.length() != 0) fileNames.append(", ");
+        fileNames.append("'").append(file.getName()).append("'");
+      }
+      String time = TIME_FORMAT.format(Clock.getTime());
+      final String statusText = CompilerBundle.message("status.text.file.has.been.packaged", files.size(), fileNames, time);
+      WindowManager.getInstance().getStatusBar(project).setInfo(statusText);
+    }
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java
new file mode 100644
index 0000000..6be07f0
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/actions/PackageFileWorker.java
@@ -0,0 +1,183 @@
+/*
+ * 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.packaging.impl.ui.actions;
+
+import com.intellij.notification.Notification;
+import com.intellij.notification.NotificationType;
+import com.intellij.notification.Notifications;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.deployment.DeploymentUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.progress.Task;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ArtifactRootElement;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.impl.artifacts.ArtifactUtil;
+import com.intellij.packaging.impl.artifacts.PackagingElementPath;
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import com.intellij.util.PathUtil;
+import com.intellij.util.io.zip.JBZipEntry;
+import com.intellij.util.io.zip.JBZipFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class PackageFileWorker {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.packaging.impl.ui.actions.PackageFileWorker");
+  private final File myFile;
+  private final String myRelativeOutputPath;
+
+  private PackageFileWorker(File file, String relativeOutputPath) {
+    myFile = file;
+    myRelativeOutputPath = relativeOutputPath;
+  }
+
+  public static void startPackagingFiles(final Project project, final List<VirtualFile> files,
+                                         final Artifact[] artifacts, final Runnable onFinished) {
+    ProgressManager.getInstance().run(new Task.Backgroundable(project, "Packaging Files") {
+      @Override
+      public void run(@NotNull ProgressIndicator indicator) {
+        try {
+          for (final VirtualFile file : files) {
+            indicator.checkCanceled();
+            new ReadAction() {
+              protected void run(final Result result) {
+                try {
+                  packageFile(file, project, artifacts);
+                }
+                catch (IOException e) {
+                  String message = CompilerBundle.message("message.tect.package.file.io.error", e.toString());
+                  Notifications.Bus.notify(new Notification("Package File", "Cannot package file", message, NotificationType.ERROR));
+                }
+              }
+            }.execute();
+          }
+        }
+        finally {
+          ApplicationManager.getApplication().invokeLater(onFinished);
+        }
+      }
+    });
+  }
+
+  public static void packageFile(@NotNull VirtualFile file, @NotNull Project project, final Artifact[] artifacts) throws IOException {
+    LOG.debug("Start packaging file: " + file.getPath());
+    final Collection<Trinity<Artifact, PackagingElementPath, String>> items = ArtifactUtil.findContainingArtifactsWithOutputPaths(file, project, artifacts);
+    File ioFile = VfsUtil.virtualToIoFile(file);
+    for (Trinity<Artifact, PackagingElementPath, String> item : items) {
+      final Artifact artifact = item.getFirst();
+      final String outputPath = artifact.getOutputPath();
+      if (!StringUtil.isEmpty(outputPath)) {
+        PackageFileWorker worker = new PackageFileWorker(ioFile, item.getThird());
+        LOG.debug(" package to " + outputPath);
+        worker.packageFile(outputPath, item.getSecond().getParents());
+      }
+    }
+  }
+
+  private void packageFile(String outputPath, List<CompositePackagingElement<?>> parents) throws IOException {
+    List<CompositePackagingElement<?>> parentsList = new ArrayList<CompositePackagingElement<?>>(parents);
+    Collections.reverse(parentsList);
+    if (!parentsList.isEmpty() && parentsList.get(0) instanceof ArtifactRootElement) {
+      parentsList = parentsList.subList(1, parentsList.size());
+    }
+    copyFile(outputPath, parentsList);
+  }
+
+  private void copyFile(String outputPath, List<CompositePackagingElement<?>> parents) throws IOException {
+    if (parents.isEmpty()) {
+      final String fullOutputPath = DeploymentUtil.appendToPath(outputPath, myRelativeOutputPath);
+      LOG.debug("  copying to " + fullOutputPath);
+      FileUtil.copy(myFile, new File(FileUtil.toSystemDependentName(fullOutputPath)));
+      return;
+    }
+
+    final CompositePackagingElement<?> element = parents.get(0);
+    final String nextOutputPath = outputPath + "/" + element.getName();
+    final List<CompositePackagingElement<?>> parentsTrail = parents.subList(1, parents.size());
+    if (element instanceof ArchivePackagingElement) {
+      packFile(nextOutputPath, "", parentsTrail);
+    }
+    else {
+      copyFile(nextOutputPath, parentsTrail);
+    }
+  }
+
+  private void packFile(String archivePath, String pathInArchive, List<CompositePackagingElement<?>> parents) throws IOException {
+    final File archiveFile = new File(FileUtil.toSystemDependentName(archivePath));
+    if (parents.isEmpty()) {
+      LOG.debug("  adding to archive " + archivePath);
+      JBZipFile file = getOrCreateZipFile(archiveFile);
+      try {
+        final String fullPathInArchive = DeploymentUtil.trimForwardSlashes(DeploymentUtil.appendToPath(pathInArchive, myRelativeOutputPath));
+        final JBZipEntry entry = file.getOrCreateEntry(fullPathInArchive);
+        entry.setData(FileUtil.loadFileBytes(myFile));
+      }
+      finally {
+        file.close();
+      }
+      return;
+    }
+
+    final CompositePackagingElement<?> element = parents.get(0);
+    final String nextPathInArchive = DeploymentUtil.trimForwardSlashes(DeploymentUtil.appendToPath(pathInArchive, element.getName()));
+    final List<CompositePackagingElement<?>> parentsTrail = parents.subList(1, parents.size());
+    if (element instanceof ArchivePackagingElement) {
+      JBZipFile zipFile = getOrCreateZipFile(archiveFile);
+      try {
+        final JBZipEntry entry = zipFile.getOrCreateEntry(nextPathInArchive);
+        LOG.debug("  extracting to temp file: " + nextPathInArchive + " from " + archivePath);
+        final File tempFile = FileUtil.createTempFile("packageFile" + FileUtil.sanitizeFileName(nextPathInArchive), FileUtil.getExtension(PathUtil.getFileName(nextPathInArchive)));
+        if (entry.getSize() != -1) {
+          FileUtil.writeToFile(tempFile, entry.getData());
+        }
+        packFile(FileUtil.toSystemIndependentName(tempFile.getAbsolutePath()), "", parentsTrail);
+        entry.setData(FileUtil.loadFileBytes(tempFile));
+        FileUtil.delete(tempFile);
+      }
+      finally {
+        zipFile.close();
+      }
+    }
+    else {
+      packFile(archivePath, nextPathInArchive, parentsTrail);
+    }
+  }
+
+  private static JBZipFile getOrCreateZipFile(File archiveFile) throws IOException {
+    FileUtil.createIfDoesntExist(archiveFile);
+    return new JBZipFile(archiveFile);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ArchiveElementPropertiesPanel.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ArchiveElementPropertiesPanel.java
new file mode 100644
index 0000000..dd2902d
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ArchiveElementPropertiesPanel.java
@@ -0,0 +1,28 @@
+/*
+ * 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.packaging.impl.ui.properties;
+
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+
+/**
+ * @author nik
+ */
+public class ArchiveElementPropertiesPanel extends ElementWithManifestPropertiesPanel<ArchivePackagingElement> {
+  public ArchiveElementPropertiesPanel(ArchivePackagingElement element, final ArtifactEditorContext context) {
+    super(element, context);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/DirectoryElementPropertiesPanel.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/DirectoryElementPropertiesPanel.java
new file mode 100644
index 0000000..804d236
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/DirectoryElementPropertiesPanel.java
@@ -0,0 +1,28 @@
+/*
+ * 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.packaging.impl.ui.properties;
+
+import com.intellij.packaging.impl.elements.DirectoryPackagingElement;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+
+/**
+ * @author nik
+ */
+public class DirectoryElementPropertiesPanel extends ElementWithManifestPropertiesPanel<DirectoryPackagingElement> {
+  public DirectoryElementPropertiesPanel(DirectoryPackagingElement element, ArtifactEditorContext context) {
+    super(element, context);
+  }
+}
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.form b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.form
new file mode 100644
index 0000000..f1e8930
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.form
@@ -0,0 +1,136 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="com.intellij.packaging.impl.ui.properties.ElementWithManifestPropertiesPanel">
+  <grid id="27dc6" binding="myMainPanel" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+    <margin top="5" left="5" bottom="5" right="5"/>
+    <constraints>
+      <xy x="20" y="20" width="500" height="400"/>
+    </constraints>
+    <properties/>
+    <border type="none"/>
+    <children>
+      <vspacer id="e5716">
+        <constraints>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+        </constraints>
+      </vspacer>
+      <grid id="98ebe" binding="myPropertiesPanel" layout-manager="CardLayout" hgap="0" vgap="0">
+        <constraints>
+          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <grid id="e398c" layout-manager="GridLayoutManager" row-count="4" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <card name="properties"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="9a3d6" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text resource-bundle="messages/CompilerBundle" key="label.text.main.class"/>
+                </properties>
+              </component>
+              <component id="d87aa" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myMainClassField">
+                <constraints>
+                  <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="40600" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text resource-bundle="messages/CompilerBundle" key="label.text.class.path"/>
+                </properties>
+              </component>
+              <component id="a5121" class="com.intellij.openapi.ui.TextFieldWithBrowseButton" binding="myClasspathField">
+                <constraints>
+                  <grid row="3" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties/>
+              </component>
+              <component id="e12c" class="javax.swing.JLabel" binding="myTitleLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="2" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="element name"/>
+                </properties>
+              </component>
+              <component id="446b5" class="javax.swing.JLabel">
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <labelFor value="aca67"/>
+                  <text value="Manifest &amp;File:"/>
+                </properties>
+              </component>
+              <component id="aca67" class="javax.swing.JTextField" binding="myManifestPathField">
+                <constraints>
+                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="6" anchor="8" fill="1" indent="0" use-parent-layout="false">
+                    <preferred-size width="150" height="-1"/>
+                  </grid>
+                </constraints>
+                <properties>
+                  <editable value="false"/>
+                </properties>
+              </component>
+            </children>
+          </grid>
+          <grid id="4473f" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+            <margin top="0" left="0" bottom="0" right="0"/>
+            <constraints>
+              <card name="buttons"/>
+            </constraints>
+            <properties/>
+            <border type="none"/>
+            <children>
+              <component id="66e62" class="javax.swing.JButton" binding="myCreateManifestButton" default-binding="true">
+                <constraints>
+                  <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="&amp;Create Manifest..."/>
+                </properties>
+              </component>
+              <hspacer id="970f7">
+                <constraints>
+                  <grid row="1" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="6" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </hspacer>
+              <vspacer id="bf917">
+                <constraints>
+                  <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
+                </constraints>
+              </vspacer>
+              <component id="c6af2" class="javax.swing.JButton" binding="myUseExistingManifestButton" default-binding="true">
+                <constraints>
+                  <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="&amp;Use Existing Manifest..."/>
+                </properties>
+              </component>
+              <component id="a0a7b" class="javax.swing.JLabel" binding="myManifestNotFoundLabel">
+                <constraints>
+                  <grid row="0" column="0" row-span="1" col-span="3" vsize-policy="0" hsize-policy="0" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
+                </constraints>
+                <properties>
+                  <text value="META-INF/MANIFEST.MF file not found"/>
+                </properties>
+              </component>
+            </children>
+          </grid>
+        </children>
+      </grid>
+    </children>
+  </grid>
+</form>
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.java b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.java
new file mode 100644
index 0000000..ad58d51
--- /dev/null
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/ui/properties/ElementWithManifestPropertiesPanel.java
@@ -0,0 +1,176 @@
+/*
+ * 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.packaging.impl.ui.properties;
+
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.impl.elements.CompositeElementWithManifest;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.ManifestFileConfiguration;
+import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
+import com.intellij.ui.DocumentAdapter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.event.DocumentEvent;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ElementWithManifestPropertiesPanel<E extends CompositeElementWithManifest<?>> extends PackagingElementPropertiesPanel {
+  private final E myElement;
+  private final ArtifactEditorContext myContext;
+  private JPanel myMainPanel;
+  private TextFieldWithBrowseButton myMainClassField;
+  private TextFieldWithBrowseButton myClasspathField;
+  private JLabel myTitleLabel;
+  private JButton myCreateManifestButton;
+  private JButton myUseExistingManifestButton;
+  private JPanel myPropertiesPanel;
+  private JTextField myManifestPathField;
+  private JLabel myManifestNotFoundLabel;
+  private ManifestFileConfiguration myManifestFileConfiguration;
+
+  public ElementWithManifestPropertiesPanel(E element, final ArtifactEditorContext context) {
+    myElement = element;
+    myContext = context;
+
+    ManifestFileUtil.setupMainClassField(context.getProject(), myMainClassField);
+
+    myClasspathField.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        Messages.showTextAreaDialog(myClasspathField.getTextField(), "Edit Classpath", "classpath-attribute-editor");
+      }
+    });
+    myClasspathField.getTextField().getDocument().addDocumentListener(new DocumentAdapter() {
+      @Override
+      protected void textChanged(DocumentEvent e) {
+        myContext.queueValidation();
+      }
+    });
+    myUseExistingManifestButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        chooseManifest();
+      }
+    });
+    myCreateManifestButton.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        createManifest();
+      }
+    });
+  }
+
+  private void createManifest() {
+    final VirtualFile file = ManifestFileUtil.showDialogAndCreateManifest(myContext, myElement);
+    if (file == null) {
+      return;
+    }
+
+    ManifestFileUtil.addManifestFileToLayout(file.getPath(), myContext, myElement);
+    updateManifest();
+    myContext.getThisArtifactEditor().updateLayoutTree();
+  }
+
+  private void chooseManifest() {
+    final FileChooserDescriptor descriptor = new FileChooserDescriptor(true, false, false, false, false, false) {
+      @Override
+      public boolean isFileVisible(VirtualFile file, boolean showHiddenFiles) {
+        return super.isFileVisible(file, showHiddenFiles) && (file.isDirectory() ||
+               file.getName().equalsIgnoreCase(ManifestFileUtil.MANIFEST_FILE_NAME));
+      }
+    };
+    descriptor.setTitle("Specify Path to MANIFEST.MF file");
+    final VirtualFile file = FileChooser.chooseFile(descriptor, myContext.getProject(), null);
+    if (file == null) return;
+
+    ManifestFileUtil.addManifestFileToLayout(file.getPath(), myContext, myElement);
+    updateManifest();
+    myContext.getThisArtifactEditor().updateLayoutTree();
+  }
+
+  private void updateManifest() {
+    myManifestFileConfiguration = myContext.getManifestFile(myElement, myContext.getArtifactType());
+    final String card;
+    if (myManifestFileConfiguration != null) {
+      card = "properties";
+      myManifestPathField.setText(FileUtil.toSystemDependentName(myManifestFileConfiguration.getManifestFilePath()));
+      myMainClassField.setText(StringUtil.notNullize(myManifestFileConfiguration.getMainClass()));
+      myMainClassField.setEnabled(myManifestFileConfiguration.isWritable());
+      myClasspathField.setText(StringUtil.join(myManifestFileConfiguration.getClasspath(), " "));
+      myClasspathField.setEnabled(myManifestFileConfiguration.isWritable());
+    }
+    else {
+      card = "buttons";
+      myManifestPathField.setText("");
+    }
+    ((CardLayout)myPropertiesPanel.getLayout()).show(myPropertiesPanel, card);
+  }
+
+  public void reset() {
+    myTitleLabel.setText("'" + myElement.getName() + "' manifest properties:");
+    myManifestNotFoundLabel.setText("META-INF/MANIFEST.MF file not found in '" + myElement.getName() + "'");
+    updateManifest();
+  }
+
+  public boolean isModified() {
+    return myManifestFileConfiguration != null && (!myManifestFileConfiguration.getClasspath().equals(getConfiguredClasspath())
+           || !Comparing.equal(myManifestFileConfiguration.getMainClass(), getConfiguredMainClass())
+           || !Comparing.equal(myManifestFileConfiguration.getManifestFilePath(), getConfiguredManifestPath()));
+  }
+
+  @Nullable
+  private String getConfiguredManifestPath() {
+    final String path = myManifestPathField.getText();
+    return path.length() != 0 ? FileUtil.toSystemIndependentName(path) : null;
+  }
+
+  @Override
+  public void apply() {
+    if (myManifestFileConfiguration != null) {
+      myManifestFileConfiguration.setMainClass(getConfiguredMainClass());
+      myManifestFileConfiguration.setClasspath(getConfiguredClasspath());
+      myManifestFileConfiguration.setManifestFilePath(getConfiguredManifestPath());
+    }
+  }
+
+  private List<String> getConfiguredClasspath() {
+    return StringUtil.split(myClasspathField.getText(), " ");
+  }
+
+  @NotNull
+  public JComponent createComponent() {
+    return myMainPanel;
+  }
+
+  @Nullable
+  private String getConfiguredMainClass() {
+    final String className = myMainClassField.getText();
+    return className.length() != 0 ? className : null;
+  }
+
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java
new file mode 100644
index 0000000..ebd49e4
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/BaseCompilerTestCase.java
@@ -0,0 +1,443 @@
+package com.intellij.compiler;
+
+import com.intellij.compiler.impl.CompileDriver;
+import com.intellij.compiler.impl.ExitStatus;
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.compiler.*;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.CompilerProjectExtension;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.newvfs.NewVirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.impl.compiler.ArtifactCompileScope;
+import com.intellij.testFramework.ModuleTestCase;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.testFramework.VfsTestUtil;
+import com.intellij.util.ParameterizedRunnable;
+import com.intellij.util.concurrency.Semaphore;
+import com.intellij.util.io.TestFileSystemBuilder;
+import com.intellij.util.ui.UIUtil;
+import gnu.trove.THashSet;
+import junit.framework.Assert;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.util.JpsPathUtil;
+
+import javax.swing.*;
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author nik
+ */
+public abstract class BaseCompilerTestCase extends ModuleTestCase {
+  protected boolean useExternalCompiler() {
+    return false;
+  }
+
+  @Override
+  protected void setUpModule() {
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    if (useExternalCompiler()) {
+      CompilerTestUtil.enableExternalCompiler(myProject);
+    }
+    else {
+      CompilerTestUtil.disableExternalCompiler(myProject);
+    }
+  }
+
+  @Override
+  protected Sdk getTestProjectJdk() {
+    if (useExternalCompiler()) {
+      return JavaAwareProjectJdkTableImpl.getInstanceEx().getInternalJdk();
+    }
+    return super.getTestProjectJdk();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    for (Artifact artifact : getArtifactManager().getArtifacts()) {
+      final String outputPath = artifact.getOutputPath();
+      if (!StringUtil.isEmpty(outputPath)) {
+        FileUtil.delete(new File(FileUtil.toSystemDependentName(outputPath)));
+      }
+    }
+    if (useExternalCompiler()) {
+      CompilerTestUtil.disableExternalCompiler(myProject);
+    }
+
+    super.tearDown();
+  }
+
+  protected ArtifactManager getArtifactManager() {
+    return ArtifactManager.getInstance(myProject);
+  }
+
+  protected String getProjectBasePath() {
+    return getBaseDir().getPath();
+  }
+
+  protected VirtualFile getBaseDir() {
+    final VirtualFile baseDir = myProject.getBaseDir();
+    Assert.assertNotNull(baseDir);
+    return baseDir;
+  }
+
+  protected void copyToProject(String relativePath) {
+    File dir = PathManagerEx.findFileUnderProjectHome(relativePath, getClass());
+    final File target = new File(FileUtil.toSystemDependentName(getProjectBasePath()));
+    try {
+      FileUtil.copyDir(dir, target);
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+    new WriteAction() {
+      protected void run(final Result result) {
+        VirtualFile virtualDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(target);
+        assertNotNull(target.getAbsolutePath() + " not found", virtualDir);
+        virtualDir.refresh(false, true);
+      }
+    }.execute();
+  }
+
+  protected Module addModule(final String moduleName, final @Nullable VirtualFile sourceRoot) {
+    return new WriteAction<Module>() {
+      @Override
+      protected void run(final Result<Module> result) {
+        final Module module = createModule(moduleName);
+        if (sourceRoot != null) {
+          PsiTestUtil.addSourceContentToRoots(module, sourceRoot);
+        }
+        ModuleRootModificationUtil.setModuleSdk(module, getTestProjectJdk());
+        result.setResult(module);
+      }
+    }.execute().getResultObject();
+  }
+
+  protected VirtualFile createFile(final String path) {
+    return createFile(path, "");
+  }
+
+  protected VirtualFile createFile(final String path, final String text) {
+    return VfsTestUtil.createFile(getBaseDir(), path, text);
+  }
+
+  protected CompilationLog make(final Artifact... artifacts) {
+    final CompileScope scope = ArtifactCompileScope.createArtifactsScope(myProject, Arrays.asList(artifacts));
+    return make(scope, CompilerFilter.ALL);
+  }
+
+  protected CompilationLog recompile(final Artifact... artifacts) {
+    final CompileScope scope = ArtifactCompileScope.createArtifactsScope(myProject, Arrays.asList(artifacts));
+    return compile(scope, CompilerFilter.ALL, true);
+  }
+
+  protected CompilationLog make(Module... modules) {
+    return make(getCompilerManager().createModulesCompileScope(modules, false), CompilerFilter.ALL);
+  }
+
+  protected CompilationLog recompile(Module... modules) {
+    return compile(getCompilerManager().createModulesCompileScope(modules, false), CompilerFilter.ALL, true);
+  }
+
+  protected CompilerManager getCompilerManager() {
+    return CompilerManager.getInstance(myProject);
+  }
+
+  protected void assertModulesUpToDate() {
+    boolean upToDate = getCompilerManager().isUpToDate(getCompilerManager().createProjectCompileScope(myProject));
+    assertTrue("Modules are not up to date", upToDate);
+  }
+
+  protected CompilationLog compile(boolean force, VirtualFile... files) {
+    return compile(getCompilerManager().createFilesCompileScope(files), CompilerFilter.ALL, force);
+  }
+
+  protected CompilationLog make(final CompileScope scope, final CompilerFilter filter) {
+    return compile(scope, filter, false);
+  }
+
+  protected CompilationLog compile(final CompileScope scope, final CompilerFilter filter, final boolean forceCompile) {
+    return compile(scope, filter, forceCompile, false);
+  }
+
+  protected CompilationLog compile(final CompileScope scope, final CompilerFilter filter, final boolean forceCompile,
+                                   final boolean errorsExpected) {
+    return compile(errorsExpected, new ParameterizedRunnable<CompileStatusNotification>() {
+      @Override
+      public void run(CompileStatusNotification callback) {
+        final CompilerManager compilerManager = getCompilerManager();
+        if (forceCompile) {
+          Assert.assertSame("Only 'ALL' filter is supported for forced compilation", CompilerFilter.ALL, filter);
+          compilerManager.compile(scope, callback);
+        }
+        else {
+          compilerManager.make(scope, filter, callback);
+        }
+      }
+    });
+  }
+
+  protected CompilationLog rebuild() {
+    return compile(false, new ParameterizedRunnable<CompileStatusNotification>() {
+      @Override
+      public void run(CompileStatusNotification compileStatusNotification) {
+        getCompilerManager().rebuild(compileStatusNotification);
+      }
+    });
+  }
+
+  protected CompilationLog compile(final boolean errorsExpected, final ParameterizedRunnable<CompileStatusNotification> action) {
+    CompilationLog log = compile(action);
+    if (errorsExpected && log.myErrors.length == 0) {
+      Assert.fail("compilation finished without errors");
+    }
+    else if (!errorsExpected && log.myErrors.length > 0) {
+      Assert.fail("compilation finished with errors: " + Arrays.toString(log.myErrors));
+    }
+    return log;
+  }
+
+  private CompilationLog compile(final ParameterizedRunnable<CompileStatusNotification> action) {
+    final Ref<CompilationLog> result = Ref.create(null);
+    final Semaphore semaphore = new Semaphore();
+    semaphore.down();
+    UIUtil.invokeAndWaitIfNeeded(new Runnable() {
+      @Override
+      public void run() {
+
+        CompilerManagerImpl.testSetup();
+        final CompileStatusNotification callback = new CompileStatusNotification() {
+          @Override
+          public void finished(boolean aborted, int errors, int warnings, CompileContext compileContext) {
+            try {
+              if (aborted) {
+                Assert.fail("compilation aborted");
+              }
+              ExitStatus status = CompileDriver.getExternalBuildExitStatus(compileContext);
+              result.set(new CompilationLog(status == ExitStatus.UP_TO_DATE,
+                                            CompilerManagerImpl.getPathsToRecompile(), CompilerManagerImpl.getPathsToDelete(),
+                                            compileContext.getMessages(CompilerMessageCategory.ERROR),
+                                            compileContext.getMessages(CompilerMessageCategory.WARNING)));
+            }
+            finally {
+              semaphore.up();
+            }
+          }
+        };
+        if (useExternalCompiler()) {
+          myProject.save();
+          CompilerTestUtil.saveSdkTable();
+          CompilerTestUtil.scanSourceRootsToRecompile(myProject);
+        }
+        action.run(callback);
+      }
+    });
+
+    final long start = System.currentTimeMillis();
+    while (!semaphore.waitFor(10)) {
+      if (System.currentTimeMillis() - start > 60 * 1000) {
+        throw new RuntimeException("timeout");
+      }
+      if (SwingUtilities.isEventDispatchThread()) {
+        UIUtil.dispatchAllInvocationEvents();
+      }
+    }
+    if (SwingUtilities.isEventDispatchThread()) {
+      UIUtil.dispatchAllInvocationEvents();
+    }
+
+    return result.get();
+  }
+
+  private Set<String> getRelativePaths(String[] paths) {
+    final Set<String> set = new THashSet<String>();
+    final String basePath = myProject.getBaseDir().getPath();
+    for (String path : paths) {
+      set.add(StringUtil.trimStart(StringUtil.trimStart(FileUtil.toSystemIndependentName(path), basePath), "/"));
+    }
+    return set;
+  }
+
+  protected void changeFile(VirtualFile file) {
+    changeFile(file, null);
+  }
+
+  protected void changeFile(VirtualFile file, final String newText) {
+    try {
+      if (newText != null) {
+        VfsUtil.saveText(file, newText);
+      }
+      ((NewVirtualFile)file).setTimeStamp(file.getTimeStamp() + 10);
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  protected void deleteFile(final VirtualFile file) {
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        try {
+          file.delete(this);
+        }
+        catch (IOException e) {
+          throw new AssertionError(e);
+        }
+      }
+    }.execute();
+  }
+
+  @Override
+  protected void setUpProject() throws Exception {
+    super.setUpProject();
+    final String baseUrl = myProject.getBaseDir().getUrl();
+    CompilerProjectExtension.getInstance(myProject).setCompilerOutputUrl(baseUrl + "/out");
+  }
+
+  @Override
+  protected File getIprFile() throws IOException {
+    File iprFile = super.getIprFile();
+    if (useExternalCompiler()) {
+      FileUtil.delete(iprFile);
+    }
+    return iprFile;
+  }
+
+  @Override
+  protected Module doCreateRealModule(String moduleName) {
+    if (useExternalCompiler()) {
+      //todo[nik] reuse code from PlatformTestCase
+      final VirtualFile baseDir = myProject.getBaseDir();
+      Assert.assertNotNull(baseDir);
+      final File moduleFile = new File(baseDir.getPath().replace('/', File.separatorChar), moduleName + ModuleFileType.DOT_DEFAULT_EXTENSION);
+      PlatformTestCase.myFilesToDelete.add(moduleFile);
+      return new WriteAction<Module>() {
+        @Override
+        protected void run(Result<Module> result) throws Throwable {
+          Module module = ModuleManager.getInstance(myProject)
+            .newModule(FileUtil.toSystemIndependentName(moduleFile.getAbsolutePath()), getModuleType().getId());
+          module.getModuleFile();
+          result.setResult(module);
+        }
+      }.execute().getResultObject();
+    }
+    return super.doCreateRealModule(moduleName);
+  }
+
+  @Override
+  protected boolean isRunInWriteAction() {
+    return false;
+  }
+
+  protected static void assertOutput(Module module, TestFileSystemBuilder item) {
+    File outputDir = getOutputDir(module);
+    Assert.assertTrue("Output directory " + outputDir.getAbsolutePath() + " doesn't exist", outputDir.exists());
+    item.build().assertDirectoryEqual(outputDir);
+  }
+
+  protected static void assertNoOutput(Module module) {
+    File dir = getOutputDir(module);
+    Assert.assertFalse("Output directory " + dir.getAbsolutePath() + " does exist", dir.exists());
+  }
+
+  protected static File getOutputDir(Module module) {
+    CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+    Assert.assertNotNull(extension);
+    String outputUrl = extension.getCompilerOutputUrl();
+    Assert.assertNotNull("Output directory for module '" + module.getName() + "' isn't specified", outputUrl);
+    return JpsPathUtil.urlToFile(outputUrl);
+  }
+
+  protected class CompilationLog {
+    private final Set<String> myRecompiledPaths;
+    private final Set<String> myDeletedPaths;
+    private final boolean myExternalBuildUpToDate;
+    private final CompilerMessage[] myErrors;
+    private final CompilerMessage[] myWarnings;
+
+    public CompilationLog(boolean externalBuildUpToDate, String[] recompiledPaths, String[] deletedPaths, CompilerMessage[] errors, CompilerMessage[] warnings) {
+      myExternalBuildUpToDate = externalBuildUpToDate;
+      myErrors = errors;
+      myWarnings = warnings;
+      myRecompiledPaths = getRelativePaths(recompiledPaths);
+      myDeletedPaths = getRelativePaths(deletedPaths);
+    }
+
+    public void assertUpToDate() {
+      if (useExternalCompiler()) {
+        assertTrue(myExternalBuildUpToDate);
+      }
+      else {
+        checkRecompiled();
+        checkDeleted();
+      }
+    }
+
+    public void assertRecompiled(String... expected) {
+      checkRecompiled(expected);
+      checkDeleted();
+    }
+
+    public void assertDeleted(String... expected) {
+      checkRecompiled();
+      checkDeleted(expected);
+    }
+
+    public void assertRecompiledAndDeleted(String[] recompiled, String... deleted) {
+      checkRecompiled(recompiled);
+      checkDeleted(deleted);
+    }
+
+    private void checkRecompiled(String... expected) {
+      assertSet("recompiled", myRecompiledPaths, expected);
+    }
+
+    private void checkDeleted(String... expected) {
+      assertSet("deleted", myDeletedPaths, expected);
+    }
+
+    public CompilerMessage[] getErrors() {
+      return myErrors;
+    }
+
+    public CompilerMessage[] getWarnings() {
+      return myWarnings;
+    }
+
+    private void assertSet(String name, Set<String> actual, String[] expected) {
+      if (useExternalCompiler()) return;
+      for (String path : expected) {
+        if (!actual.remove(path)) {
+          Assert.fail("'" + path + "' is not " + name + ". " + name + ": " + new HashSet<String>(actual));
+        }
+      }
+      if (!actual.isEmpty()) {
+        Assert.fail("'" + actual.iterator().next() + "' must not be " + name);
+      }
+    }
+  }
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java b/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java
new file mode 100644
index 0000000..69cb63a
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/CompilerTestUtil.java
@@ -0,0 +1,87 @@
+package com.intellij.compiler;
+
+import com.intellij.compiler.impl.TranslatingCompilerFilesMonitor;
+import com.intellij.compiler.impl.javaCompiler.javac.JavacConfiguration;
+import com.intellij.compiler.server.BuildManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.application.ex.ApplicationManagerEx;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.impl.JavaAwareProjectJdkTableImpl;
+import com.intellij.openapi.projectRoots.impl.ProjectJdkTableImpl;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.SystemProperties;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.jps.model.java.compiler.JpsJavaCompilerOptions;
+import org.jetbrains.jps.model.serialization.JDomSerializationUtil;
+import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class CompilerTestUtil {
+  private CompilerTestUtil() {
+  }
+
+  public static void setupJavacForTests(Project project) {
+    CompilerConfigurationImpl compilerConfiguration = (CompilerConfigurationImpl)CompilerConfiguration.getInstance(project);
+    compilerConfiguration.projectOpened();
+    compilerConfiguration.setDefaultCompiler(compilerConfiguration.getJavacCompiler());
+
+    JpsJavaCompilerOptions javacSettings = JavacConfiguration.getOptions(project, JavacConfiguration.class);
+    javacSettings.setTestsUseExternalCompiler(true);
+  }
+
+  public static void scanSourceRootsToRecompile(Project project) {
+    // need this to emulate project opening
+    final List<VirtualFile> roots = Arrays.asList(ProjectRootManager.getInstance(project).getContentSourceRoots());
+    TranslatingCompilerFilesMonitor.getInstance().scanSourceContent(new TranslatingCompilerFilesMonitor.ProjectRef(project), roots, roots.size(), true);
+  }
+
+  public static void saveSdkTable() {
+    try {
+      ProjectJdkTableImpl table = (ProjectJdkTableImpl)ProjectJdkTable.getInstance();
+      File sdkFile = table.getExportFiles()[0];
+      FileUtil.createParentDirs(sdkFile);
+      Element root = new Element("application");
+      root.addContent(JDomSerializationUtil.createComponentElement(JpsGlobalLoader.SDK_TABLE_COMPONENT_NAME).addContent(table.getState().cloneContent()));
+      JDOMUtil.writeDocument(new Document(root), sdkFile, SystemProperties.getLineSeparator());
+    }
+    catch (IOException e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  public static void enableExternalCompiler(final Project project) {
+    new WriteAction() {
+      protected void run(final Result result) {
+        CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = true;
+        ApplicationManagerEx.getApplicationEx().doNotSave(false);
+        JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
+        table.addJdk(table.getInternalJdk());
+      }
+    }.execute();
+  }
+
+  public static void disableExternalCompiler(final Project project) {
+    new WriteAction() {
+      protected void run(final Result result) {
+        CompilerWorkspaceConfiguration.getInstance(project).USE_COMPILE_SERVER = false;
+        ApplicationManagerEx.getApplicationEx().doNotSave(true);
+        JavaAwareProjectJdkTableImpl table = JavaAwareProjectJdkTableImpl.getInstanceEx();
+        table.removeJdk(table.getInternalJdk());
+        BuildManager.getInstance().stopWatchingProject(project);
+      }
+    }.execute();
+  }
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactCompilerTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactCompilerTestCase.java
new file mode 100644
index 0000000..ad03189
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactCompilerTestCase.java
@@ -0,0 +1,116 @@
+package com.intellij.compiler.artifacts;
+
+import com.intellij.compiler.BaseCompilerTestCase;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.DependencyScope;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.impl.artifacts.PlainArtifactType;
+import com.intellij.util.io.TestFileSystemBuilder;
+import com.intellij.util.io.TestFileSystemItem;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+import static com.intellij.compiler.artifacts.ArtifactsTestCase.commitModel;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactCompilerTestCase extends BaseCompilerTestCase {
+
+  protected void deleteArtifact(final Artifact artifact) {
+    final ModifiableArtifactModel model = getArtifactManager().createModifiableModel();
+    model.removeArtifact(artifact);
+    commitModel(model);
+  }
+
+  protected Artifact addArtifact(TestPackagingElementBuilder builder) {
+    return addArtifact("a", builder);
+  }
+
+  protected Artifact addArtifact(final String name, TestPackagingElementBuilder builder) {
+    return addArtifact(name, builder.build());
+  }
+
+  protected Artifact addArtifact(String name, final CompositePackagingElement<?> root) {
+    return addArtifact(name, PlainArtifactType.getInstance(), root);
+  }
+
+  protected Artifact addArtifact(final String name, final ArtifactType type, final CompositePackagingElement<?> root) {
+    return getArtifactManager().addArtifact(name, type, root);
+  }
+
+  protected Library addProjectLibrary(final @Nullable Module module, final String name, final VirtualFile... jars) {
+    return addProjectLibrary(module, name, DependencyScope.COMPILE, jars);
+  }
+
+  protected Library addProjectLibrary(final @Nullable Module module, final String name, final DependencyScope scope,
+                                      final VirtualFile... jars) {
+    return PackagingElementsTestCase.addProjectLibrary(myProject, module, name, scope, jars);
+  }
+
+  protected TestPackagingElementBuilder root() {
+    return TestPackagingElementBuilder.root(myProject);
+  }
+
+  protected TestPackagingElementBuilder archive(String name) {
+    return TestPackagingElementBuilder.archive(myProject, name);
+  }
+
+  protected CompilationLog compileProject() {
+    return make(getArtifactManager().getArtifacts());
+  }
+
+  protected void changeFileInJar(String jarPath, String pathInJar) throws Exception {
+    final VirtualFile jarFile = LocalFileSystem.getInstance().findFileByPath(jarPath);
+    assertNotNull(jarFile);
+    final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(jarFile);
+    assertNotNull(jarRoot);
+    VirtualFile jarEntry = jarRoot.findFileByRelativePath(pathInJar);
+    assertNotNull(jarEntry);
+    assertNotNull(jarFile);
+    changeFile(jarFile);
+    jarFile.refresh(false, false);
+
+    jarEntry = jarRoot.findFileByRelativePath(pathInJar);
+    assertNotNull(jarEntry);
+  }
+
+  protected static TestFileSystemBuilder fs() {
+    return TestFileSystemItem.fs();
+  }
+
+  public static void assertNoOutput(Artifact artifact) {
+    final String outputPath = artifact.getOutputPath();
+    assertNotNull("output path not specified for " + artifact.getName(), outputPath);
+    assertFalse(new File(FileUtil.toSystemDependentName(outputPath)).exists());
+  }
+
+  public static void assertEmptyOutput(Artifact a1) throws IOException {
+    assertOutput(a1, ArtifactCompilerTestCase.fs());
+  }
+
+  public static void assertOutput(Artifact artifact, TestFileSystemBuilder item) {
+    final VirtualFile outputFile = getOutputDir(artifact);
+    outputFile.refresh(false, true);
+    item.build().assertDirectoryEqual(VfsUtil.virtualToIoFile(outputFile));
+  }
+
+  protected static VirtualFile getOutputDir(Artifact artifact) {
+    final String output = artifact.getOutputPath();
+    assertNotNull("output path not specified for " + artifact.getName(), output);
+    final VirtualFile outputFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(output);
+    assertNotNull("output file not found " + output, outputFile);
+    return outputFile;
+  }
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java
new file mode 100644
index 0000000..9c60d0c
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestCase.java
@@ -0,0 +1,291 @@
+package com.intellij.compiler.artifacts;
+
+import com.intellij.facet.Facet;
+import com.intellij.facet.impl.DefaultFacetsProvider;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.artifacts.*;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.*;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.ManifestFileProvider;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.artifacts.PlainArtifactType;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import com.intellij.packaging.ui.ArtifactEditor;
+import com.intellij.packaging.ui.ManifestFileConfiguration;
+import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.PsiTestUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.util.*;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactsTestCase extends IdeaTestCase {
+  protected boolean mySetupModule;
+
+  protected ArtifactManager getArtifactManager() {
+    return ArtifactManager.getInstance(myProject);
+  }
+
+  @Override
+  protected void setUpModule() {
+    if (mySetupModule) {
+      super.setUpModule();
+    }
+  }
+
+  protected void deleteArtifact(final Artifact artifact) {
+    final ModifiableArtifactModel model = getArtifactManager().createModifiableModel();
+    model.removeArtifact(artifact);
+    commitModel(model);
+  }
+
+  protected static void commitModel(final ModifiableArtifactModel model) {
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        model.commit();
+      }
+    }.execute();
+  }
+
+  protected Artifact rename(Artifact artifact, String newName) {
+    final ModifiableArtifactModel model = getArtifactManager().createModifiableModel();
+    model.getOrCreateModifiableArtifact(artifact).setName(newName);
+    commitModel(model);
+    return artifact;
+  }
+
+  protected Artifact addArtifact(String name) {
+    return addArtifact(name, null);
+  }
+
+  protected Artifact addArtifact(String name, final CompositePackagingElement<?> root) {
+    return addArtifact(name, PlainArtifactType.getInstance(), root);
+  }
+
+  protected Artifact addArtifact(final String name, final ArtifactType type, final CompositePackagingElement<?> root) {
+    return getArtifactManager().addArtifact(name, type, root);
+  }
+
+  protected PackagingElementResolvingContext getContext() {
+    return ArtifactManager.getInstance(myProject).getResolvingContext();
+  }
+
+  public static void renameFile(final VirtualFile file, final String newName) {
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        try {
+          file.rename(IdeaTestCase.class, newName);
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+      }
+    }.execute();
+  }
+
+  protected Module addModule(final String moduleName, final @Nullable VirtualFile sourceRoot) {
+    return new WriteAction<Module>() {
+      @Override
+      protected void run(final Result<Module> result) {
+        final Module module = createModule(moduleName);
+        if (sourceRoot != null) {
+          PsiTestUtil.addSourceContentToRoots(module, sourceRoot);
+        }
+        ModuleRootModificationUtil.setModuleSdk(module, getTestProjectJdk());
+        result.setResult(module);
+      }
+    }.execute().getResultObject();
+  }
+
+  public static class MockPackagingEditorContext extends ArtifactEditorContextImpl {
+    public MockPackagingEditorContext(ArtifactsStructureConfigurableContext parent, final ArtifactEditorEx editor) {
+      super(parent, editor);
+    }
+
+    @Override
+    public void selectArtifact(@NotNull Artifact artifact) {
+    }
+
+    @Override
+    public void selectFacet(@NotNull Facet<?> facet) {
+    }
+
+    @Override
+    public void selectModule(@NotNull Module module) {
+    }
+
+    @Override
+    public void selectLibrary(@NotNull Library library) {
+    }
+
+    @Override
+    public void queueValidation() {
+    }
+
+    @Override
+    public List<Artifact> chooseArtifacts(List<? extends Artifact> artifacts, String title) {
+      return new ArrayList<Artifact>(artifacts);
+    }
+
+    @Override
+    public List<Module> chooseModules(List<Module> modules, String title) {
+      return modules;
+    }
+
+    @Override
+    public List<Library> chooseLibraries(String title) {
+      return Collections.emptyList();
+    }
+  }
+
+  public class MockArtifactsStructureConfigurableContext implements ArtifactsStructureConfigurableContext {
+    private ModifiableArtifactModel myModifiableModel;
+    private final Map<Module, ModifiableRootModel> myModifiableRootModels = new HashMap<Module, ModifiableRootModel>();
+    private final Map<CompositePackagingElement<?>, ManifestFileConfiguration> myManifestFiles =
+      new HashMap<CompositePackagingElement<?>, ManifestFileConfiguration>();
+    private final ArtifactEditorManifestFileProvider myManifestFileProvider = new ArtifactEditorManifestFileProvider(this);
+
+    @Override
+    @NotNull
+    public ModifiableArtifactModel getOrCreateModifiableArtifactModel() {
+      if (myModifiableModel == null) {
+        myModifiableModel = ArtifactManager.getInstance(myProject).createModifiableModel();
+      }
+      return myModifiableModel;
+    }
+
+    @Override
+    public ModifiableModuleModel getModifiableModuleModel() {
+      return null;
+    }
+
+    @Override
+    @NotNull
+    public ModifiableRootModel getOrCreateModifiableRootModel(@NotNull Module module) {
+      ModifiableRootModel model = myModifiableRootModels.get(module);
+      if (model == null) {
+        model = ModuleRootManager.getInstance(module).getModifiableModel();
+        myModifiableRootModels.put(module, model);
+      }
+      return model;
+    }
+
+    @Override
+    public ArtifactEditorSettings getDefaultSettings() {
+      return new ArtifactEditorSettings();
+    }
+
+    @Override
+    @NotNull
+    public Project getProject() {
+      return myProject;
+    }
+
+    @Override
+    @NotNull
+    public ArtifactModel getArtifactModel() {
+      if (myModifiableModel != null) {
+        return myModifiableModel;
+      }
+      return ArtifactManager.getInstance(myProject);
+    }
+
+    public void commitModel() {
+      if (myModifiableModel != null) {
+        myModifiableModel.commit();
+      }
+    }
+
+    @Override
+    @NotNull
+    public ModulesProvider getModulesProvider() {
+      return new DefaultModulesProvider(myProject);
+    }
+
+    @Override
+    @NotNull
+    public FacetsProvider getFacetsProvider() {
+      return DefaultFacetsProvider.INSTANCE;
+    }
+
+    @Override
+    public Library findLibrary(@NotNull String level, @NotNull String libraryName) {
+      return ArtifactManager.getInstance(myProject).getResolvingContext().findLibrary(level, libraryName);
+    }
+
+    @NotNull
+    @Override
+    public ManifestFileProvider getManifestFileProvider() {
+      return myManifestFileProvider;
+    }
+
+    @Override
+    public ManifestFileConfiguration getManifestFile(CompositePackagingElement<?> element, ArtifactType artifactType) {
+      final VirtualFile manifestFile = ManifestFileUtil.findManifestFile(element, this, PlainArtifactType.getInstance());
+      if (manifestFile == null) {
+        return null;
+      }
+
+      ManifestFileConfiguration configuration = myManifestFiles.get(element);
+      if (configuration == null) {
+        configuration = ManifestFileUtil.createManifestFileConfiguration(manifestFile);
+        myManifestFiles.put(element, configuration);
+      }
+      return configuration;
+    }
+
+    @Override
+    public CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact) {
+      return artifact.getRootElement();
+    }
+
+    @Override
+    public void editLayout(@NotNull Artifact artifact, Runnable action) {
+      final ModifiableArtifact modifiableArtifact = getOrCreateModifiableArtifactModel().getOrCreateModifiableArtifact(artifact);
+      modifiableArtifact.setRootElement(artifact.getRootElement());
+      action.run();
+    }
+
+    @Override
+    public ArtifactEditor getOrCreateEditor(Artifact artifact) {
+      throw new UnsupportedOperationException("'getOrCreateEditor' not implemented in " + getClass().getName());
+    }
+
+    @Override
+    @NotNull
+    public Artifact getOriginalArtifact(@NotNull Artifact artifact) {
+      if (myModifiableModel != null) {
+        return myModifiableModel.getOriginalArtifact(artifact);
+      }
+      return artifact;
+    }
+
+    @Override
+    public void queueValidation(Artifact artifact) {
+    }
+
+    @Override
+    @NotNull
+    public ArtifactProjectStructureElement getOrCreateArtifactElement(@NotNull Artifact artifact) {
+      throw new UnsupportedOperationException("'getOrCreateArtifactElement' not implemented in " + getClass().getName());
+    }
+  }
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java
new file mode 100644
index 0000000..3eb811f
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/ArtifactsTestUtil.java
@@ -0,0 +1,133 @@
+package com.intellij.compiler.artifacts;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactManager;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.impl.elements.ArchivePackagingElement;
+import com.intellij.packaging.impl.elements.DirectoryPackagingElement;
+import com.intellij.packaging.impl.elements.ManifestFileUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.Manifest;
+
+import static junit.framework.Assert.assertEquals;
+import static junit.framework.Assert.assertNotNull;
+
+/**
+ * @author nik
+ */
+public class ArtifactsTestUtil {
+  public static String printToString(PackagingElement element, int level) {
+    StringBuilder builder = new StringBuilder(StringUtil.repeatSymbol(' ', level));
+    if (element instanceof ArchivePackagingElement) {
+      builder.append(((ArchivePackagingElement)element).getArchiveFileName());
+    }
+    else if (element instanceof DirectoryPackagingElement) {
+      builder.append(((DirectoryPackagingElement)element).getDirectoryName()).append("/");
+    }
+    else {
+      builder.append(element.toString());
+    }
+    builder.append("\n");
+    if (element instanceof CompositePackagingElement) {
+      for (PackagingElement<?> child : ((CompositePackagingElement<?>)element).getChildren()) {
+        builder.append(printToString(child, level + 1));
+      }
+    }
+    return builder.toString();
+  }
+
+  public static void assertLayout(PackagingElement element, String expected) {
+    assertEquals(adjustMultiLine(expected), printToString(element, 0));
+  }
+
+  private static String adjustMultiLine(String expected) {
+    final List<String> strings = StringUtil.split(StringUtil.trimStart(expected, "\n"), "\n");
+    int min = Integer.MAX_VALUE;
+    for (String s : strings) {
+      int k = 0;
+      while (k < s.length() && s.charAt(k) == ' ') {
+        k++;
+      }
+      min = Math.min(min, k);
+    }
+    List<String> lines = new ArrayList<String>();
+    for (String s : strings) {
+      lines.add(s.substring(min));
+    }
+    return StringUtil.join(lines, "\n") + "\n";      
+  }
+
+  public static void assertLayout(Project project, String artifactName, String expected) {
+    assertLayout(findArtifact(project, artifactName).getRootElement(), expected);
+  }
+
+  public static void assertOutputPath(Project project, String artifactName, String expected) {
+    assertEquals(expected, findArtifact(project, artifactName).getOutputPath());
+  }
+
+  public static void assertOutputFileName(Project project, String artifactName, String expected) {
+    assertEquals(expected, findArtifact(project, artifactName).getRootElement().getName());
+  }
+
+  public static void setOutput(final Project project, final String artifactName, final String outputPath) {
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel();
+        model.getOrCreateModifiableArtifact(findArtifact(project, artifactName)).setOutputPath(outputPath);
+        model.commit();
+      }
+    }.execute();
+  }
+
+  public static void addArtifactToLayout(final Project project, final Artifact parent, final Artifact toAdd) {
+    new WriteAction() {
+      @Override
+      protected void run(final Result result) {
+        final ModifiableArtifactModel model = ArtifactManager.getInstance(project).createModifiableModel();
+        final PackagingElement<?> artifactElement = PackagingElementFactory.getInstance().createArtifactElement(toAdd, project);
+        model.getOrCreateModifiableArtifact(parent).getRootElement().addOrFindChild(artifactElement);
+        model.commit();
+      }
+    }.execute();
+  }
+
+  public static Artifact findArtifact(Project project, String artifactName) {
+    final ArtifactManager manager = ArtifactManager.getInstance(project);
+    final Artifact artifact = manager.findArtifact(artifactName);
+    assertNotNull("'" + artifactName + "' artifact not found", artifact);
+    return artifact;
+  }
+
+  public static void assertManifest(Artifact artifact, PackagingElementResolvingContext context, @Nullable String mainClass, @Nullable String classpath) {
+    final CompositePackagingElement<?> rootElement = artifact.getRootElement();
+    final ArtifactType type = artifact.getArtifactType();
+    assertManifest(rootElement, context, type, mainClass, classpath);
+  }
+
+  public static void assertManifest(CompositePackagingElement<?> rootElement,
+                                     PackagingElementResolvingContext context,
+                                     ArtifactType type,
+                                     @Nullable String mainClass, @Nullable String classpath) {
+    final VirtualFile file = ManifestFileUtil.findManifestFile(rootElement, context, type);
+    assertNotNull(file);
+    final Manifest manifest = ManifestFileUtil.readManifest(file);
+    assertEquals(mainClass, manifest.getMainAttributes().getValue(Attributes.Name.MAIN_CLASS));
+    assertEquals(classpath, manifest.getMainAttributes().getValue(Attributes.Name.CLASS_PATH));
+  }
+
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java
new file mode 100644
index 0000000..a6a667a
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/PackagingElementsTestCase.java
@@ -0,0 +1,130 @@
+package com.intellij.compiler.artifacts;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.DependencyScope;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTablesRegistrar;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.testFramework.VfsTestUtil;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementsTestCase extends ArtifactsTestCase {
+  protected Artifact addArtifact(TestPackagingElementBuilder builder) {
+    return addArtifact("a", builder);
+  }
+
+  protected Artifact addArtifact(final String name, TestPackagingElementBuilder builder) {
+    return addArtifact(name, builder.build());
+  }
+
+  protected static void assertLayout(Artifact artifact, String expected) {
+    assertLayout(artifact.getRootElement(), expected);
+  }
+
+  protected static void assertLayout(PackagingElement element, String expected) {
+    ArtifactsTestUtil.assertLayout(element, expected);
+  }
+
+  protected String getProjectBasePath() {
+    return getBaseDir().getPath();
+  }
+
+  protected VirtualFile getBaseDir() {
+    final VirtualFile baseDir = myProject.getBaseDir();
+    assertNotNull(baseDir);
+    return baseDir;
+  }
+
+  protected TestPackagingElementBuilder root() {
+    return TestPackagingElementBuilder.root(myProject);
+  }
+
+  protected TestPackagingElementBuilder archive(String name) {
+    return TestPackagingElementBuilder.archive(myProject, name);
+  }
+
+  protected VirtualFile createFile(final String path) {
+    return createFile(path, "");
+  }
+
+  protected VirtualFile createFile(final String path, final String text) {
+    return VfsTestUtil.createFile(getBaseDir(), path, text);
+  }
+
+  protected VirtualFile createDir(final String path) {
+    return VfsTestUtil.createDir(getBaseDir(), path);
+  }
+
+  protected static VirtualFile getJDomJar() {
+    return getJarFromLibDirectory("jdom.jar");
+  }
+
+  protected static String getLocalJarPath(VirtualFile jarEntry) {
+    return PathUtil.getLocalFile(jarEntry).getPath();
+  }
+
+  protected static String getJUnitJarPath() {
+    return getLocalJarPath(getJarFromLibDirectory("junit.jar"));
+  }
+
+  private static VirtualFile getJarFromLibDirectory(final String relativePath) {
+    final File file = PathManager.findFileInLibDirectory(relativePath);
+    final VirtualFile virtualFile = LocalFileSystem.getInstance().findFileByIoFile(file);
+    assertNotNull(file.getAbsolutePath() + " not found", virtualFile);
+    final VirtualFile jarRoot = JarFileSystem.getInstance().getJarRootForLocalFile(virtualFile);
+    assertNotNull(jarRoot);
+    return jarRoot;
+  }
+
+  protected Library addProjectLibrary(final @Nullable Module module, final String name, final VirtualFile... jars) {
+    return addProjectLibrary(module, name, DependencyScope.COMPILE, jars);
+  }
+
+  protected Library addProjectLibrary(final @Nullable Module module, final String name, final DependencyScope scope,
+                                      final VirtualFile... jars) {
+    return addProjectLibrary(myProject, module, name, scope, jars);
+  }
+
+  static Library addProjectLibrary(final Project project, final @Nullable Module module, final String name, final DependencyScope scope,
+                                   final VirtualFile[] jars) {
+    return new WriteAction<Library>() {
+      @Override
+      protected void run(final Result<Library> result) {
+        final Library library = LibraryTablesRegistrar.getInstance().getLibraryTable(project).createLibrary(name);
+        final Library.ModifiableModel libraryModel = library.getModifiableModel();
+        for (VirtualFile jar : jars) {
+          libraryModel.addRoot(jar, OrderRootType.CLASSES);
+        }
+        libraryModel.commit();
+        if (module != null) {
+          ModuleRootModificationUtil.addDependency(module, library, scope, false);
+        }
+        result.setResult(library);
+      }
+    }.execute().getResultObject();
+  }
+
+  protected static void addModuleLibrary(final Module module, final VirtualFile jar) {
+    ModuleRootModificationUtil.addModuleLibrary(module, jar.getUrl());
+  }
+
+  protected static void addModuleDependency(final Module module, final Module dependency) {
+    ModuleRootModificationUtil.addDependency(module, dependency);
+  }
+}
diff --git a/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/TestPackagingElementBuilder.java b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/TestPackagingElementBuilder.java
new file mode 100644
index 0000000..3c1f6376
--- /dev/null
+++ b/java/compiler/impl/testSrc/com/intellij/compiler/artifacts/TestPackagingElementBuilder.java
@@ -0,0 +1,101 @@
+package com.intellij.compiler.artifacts;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementFactory;
+
+/**
+* @author nik
+*/
+public class TestPackagingElementBuilder {
+  private final CompositePackagingElement<?> myElement;
+  private final TestPackagingElementBuilder myParent;
+  private final Project myProject;
+
+  private TestPackagingElementBuilder(Project project, CompositePackagingElement<?> element, TestPackagingElementBuilder parent) {
+    myElement = element;
+    myParent = parent;
+    myProject = project;
+  }
+
+  public static TestPackagingElementBuilder root(Project project) {
+    return new TestPackagingElementBuilder(project, PackagingElementFactory.getInstance().createArtifactRootElement(), null);
+  }
+
+  public static TestPackagingElementBuilder archive(final Project project, String name) {
+    return new TestPackagingElementBuilder(project, PackagingElementFactory.getInstance().createArchive(name), null);
+  }
+
+  public CompositePackagingElement<?> build() {
+    TestPackagingElementBuilder builder = this;
+    while (builder.myParent != null) {
+      builder = builder.myParent;
+    }
+    return builder.myElement;
+  }
+
+  public TestPackagingElementBuilder file(VirtualFile file) {
+    return file(file.getPath());
+  }
+
+  public TestPackagingElementBuilder file(String path) {
+    myElement.addOrFindChild(getFactory().createFileCopyWithParentDirectories(path, "/"));
+    return this;
+  }
+
+  private static PackagingElementFactory getFactory() {
+    return PackagingElementFactory.getInstance();
+  }
+
+  public TestPackagingElementBuilder dirCopy(VirtualFile dir) {
+    return dirCopy(dir.getPath());
+  }
+
+  public TestPackagingElementBuilder dirCopy(String path) {
+    myElement.addOrFindChild(getFactory().createDirectoryCopyWithParentDirectories(path, "/"));
+    return this;
+  }
+
+  public TestPackagingElementBuilder extractedDir(String jarPath, String pathInJar) {
+    myElement.addOrFindChild(getFactory().createExtractedDirectoryWithParentDirectories(jarPath, pathInJar, "/"));
+    return this;
+  }
+
+  public TestPackagingElementBuilder module(Module module) {
+    myElement.addOrFindChild(getFactory().createModuleOutput(module));
+    return this;
+  }
+
+  public TestPackagingElementBuilder lib(Library library) {
+    myElement.addOrFindChildren(getFactory().createLibraryElements(library));
+    return this;
+  }
+
+  public TestPackagingElementBuilder artifact(Artifact artifact) {
+    myElement.addOrFindChild(getFactory().createArtifactElement(artifact, myProject));
+    return this;
+  }
+
+  public TestPackagingElementBuilder archive(String name) {
+    final CompositePackagingElement<?> archive = getFactory().createArchive(name);
+    return new TestPackagingElementBuilder(myProject, myElement.addOrFindChild(archive), this);
+  }
+
+  public TestPackagingElementBuilder dir(String name) {
+    return new TestPackagingElementBuilder(myProject, myElement.addOrFindChild(getFactory().createDirectory(name)), this);
+  }
+
+  public TestPackagingElementBuilder add(PackagingElement<?> element) {
+    myElement.addOrFindChild(element);
+    return this;
+  }
+
+  public TestPackagingElementBuilder end() {
+    return myParent;
+  }
+}
diff --git a/java/compiler/instrumentation-util/instrumentation-util.iml b/java/compiler/instrumentation-util/instrumentation-util.iml
new file mode 100644
index 0000000..60d62d3
--- /dev/null
+++ b/java/compiler/instrumentation-util/instrumentation-util.iml
@@ -0,0 +1,13 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="asm4" level="project" />
+  </component>
+</module>
+
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java
new file mode 100644
index 0000000..abde877
--- /dev/null
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumentationClassFinder.java
@@ -0,0 +1,765 @@
+package com.intellij.compiler.instrumentation;
+
+import org.jetbrains.asm4.ClassReader;
+import org.jetbrains.asm4.ClassVisitor;
+import org.jetbrains.asm4.MethodVisitor;
+import org.jetbrains.asm4.Opcodes;
+import sun.misc.Resource;
+
+import java.io.*;
+import java.net.URISyntaxException;
+import java.net.URL;
+import java.net.URLClassLoader;
+import java.util.*;
+import java.util.zip.ZipEntry;
+import java.util.zip.ZipFile;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 2/16/12
+ */
+public class InstrumentationClassFinder {
+  private static final PseudoClass[] EMPTY_PSEUDOCLASS_ARRAY = new PseudoClass[0];
+  private static final String CLASS_RESOURCE_EXTENSION = ".class";
+  private static final URL[] URL_EMPTY_ARRAY = new URL[0];
+  private final Map<String, PseudoClass> myLoaded = new HashMap<String, PseudoClass>(); // className -> class object
+  private final ClassFinderClasspath myPlatformClasspath;
+  private final ClassFinderClasspath myClasspath;
+  private final URL[] myPlatformUrls;
+  private final URL[] myClasspathUrls;
+  private ClassLoader myLoader;
+  private byte[] myBuffer;
+
+  public InstrumentationClassFinder(final URL[] cp) {
+    this(URL_EMPTY_ARRAY, cp);
+  }
+
+  public InstrumentationClassFinder(final URL[] platformUrls, final URL[] classpathUrls) {
+    myPlatformUrls = platformUrls;
+    myClasspathUrls = classpathUrls;
+    myPlatformClasspath = new ClassFinderClasspath(platformUrls);
+    myClasspath = new ClassFinderClasspath(classpathUrls);
+  }
+
+  // compatibility with legacy code requiring ClassLoader
+  public ClassLoader getLoader() {
+    ClassLoader loader = myLoader;
+    if (loader != null) {
+      return loader;
+    }
+    final URLClassLoader platformLoader = myPlatformUrls.length > 0 ? new URLClassLoader(myPlatformUrls, null) : null;
+    final ClassLoader cpLoader = new URLClassLoader(myClasspathUrls, platformLoader);
+    loader = new ClassLoader(cpLoader) {
+
+      public InputStream getResourceAsStream(String name) {
+        InputStream is = null;
+        is = super.getResourceAsStream(name);
+        if (is == null) {
+          try {
+            is = InstrumentationClassFinder.this.getResourceAsStream(name);
+          }
+          catch (IOException ignored) {
+          }
+        }
+        return is;
+      }
+
+      protected Class findClass(String name) throws ClassNotFoundException {
+        final InputStream is = lookupClassBeforeClasspath(name.replace('.', '/'));
+        if (is == null) {
+          throw new ClassNotFoundException("Class not found: " + name.replace('/', '.'));  // ensure presentable class name in error message
+        }
+        try {
+          final byte[] bytes = loadBytes(is);
+          return defineClass(name, bytes, 0, bytes.length);
+        }
+        finally {
+          try {
+            is.close();
+          }
+          catch (IOException ignored) {
+          }
+        }
+      }
+    };
+    myLoader = loader;
+    return loader;
+  }
+
+  public void releaseResources() {
+    myPlatformClasspath.releaseResources();
+    myClasspath.releaseResources();
+    myLoaded.clear();
+    myBuffer = null;
+    myLoader = null;
+  }
+
+  public PseudoClass loadClass(final String name) throws IOException, ClassNotFoundException{
+    final String internalName = name.replace('.', '/'); // normalize
+    final PseudoClass aClass = myLoaded.get(internalName);
+    if (aClass != null) {
+      return aClass;
+    }
+
+    final InputStream is = getClassBytesAsStream(internalName);
+
+    if (is == null) {
+      throw new ClassNotFoundException("Class not found: " + name.replace('/', '.')); // ensure presentable class name in error message
+    }
+
+    try {
+      final PseudoClass result = loadPseudoClass(is);
+      myLoaded.put(internalName, result);
+      return result;
+    }
+    finally {
+      is.close();
+    }
+  }
+
+  public void cleanCachedData(String className) {
+    myLoaded.remove(className.replace('.', '/'));
+  }
+
+  public InputStream getClassBytesAsStream(String className) throws IOException {
+    final String internalName = className.replace('.', '/'); // normalize
+    InputStream is = null;
+    // first look into platformCp
+    final String resourceName = internalName + CLASS_RESOURCE_EXTENSION;
+    Resource resource = myPlatformClasspath.getResource(resourceName, false);
+    if (resource != null) {
+      is = resource.getInputStream();
+    }
+    // second look into memory and classspath
+    if (is == null) {
+      is = lookupClassBeforeClasspath(internalName);
+    }
+
+    if (is == null) {
+      resource = myClasspath.getResource(resourceName, false);
+      if (resource != null) {
+        is = resource.getInputStream();
+      }
+    }
+
+    if (is == null) {
+      is = lookupClassAfterClasspath(internalName);
+    }
+    return is;
+  }
+
+  public InputStream getResourceAsStream(String resourceName) throws IOException {
+    InputStream is = null;
+
+    Resource resource = myPlatformClasspath.getResource(resourceName, false);
+    if (resource != null) {
+      is = resource.getInputStream();
+    }
+
+    if (is == null) {
+      resource = myClasspath.getResource(resourceName, false);
+      if (resource != null) {
+        is = resource.getInputStream();
+      }
+    }
+
+    return is;
+  }
+
+  protected InputStream lookupClassBeforeClasspath(final String internalClassName) {
+    return null;
+  }
+
+  protected InputStream lookupClassAfterClasspath(final String internalClassName) {
+    return null;
+  }
+
+  private PseudoClass loadPseudoClass(InputStream is) throws IOException {
+    final ClassReader reader = new ClassReader(is);
+    final V visitor = new V();
+
+    reader.accept(visitor, ClassReader.SKIP_CODE | ClassReader.SKIP_DEBUG | ClassReader.SKIP_FRAMES);
+
+    return new PseudoClass(visitor.myName, visitor.mySuperclassName, visitor.myInterfaces, visitor.myModifiers, visitor.myMethods);
+  }
+  
+  public final class PseudoClass {
+    private final String myName;
+    private final String mySuperClass;
+    private final String[] myInterfaces;
+    private final int myModifiers;
+    private final List<PseudoMethod> myMethods;
+
+    private PseudoClass(final String name, final String superClass, final String[] interfaces, final int modifiers, List<PseudoMethod> methods) {
+      myName = name;
+      mySuperClass = superClass;
+      myInterfaces = interfaces;
+      myModifiers = modifiers;
+      myMethods = methods;
+    }
+
+    public int getModifiers() {
+      return myModifiers;
+    }
+
+    public boolean isInterface() {
+      return (myModifiers & Opcodes.ACC_INTERFACE) > 0;
+    }
+
+    public String getName() {
+      return myName;
+    }
+
+    public List<PseudoMethod> getMethods() {
+      return myMethods;
+    }
+
+    public List<PseudoMethod> findMethods(String name) {
+      final List<PseudoMethod> result = new ArrayList<PseudoMethod>();
+      for (PseudoMethod method : myMethods) {
+        if (method.getName().equals(name)){
+          result.add(method);
+        }
+      }
+      return result;
+    }
+
+    public PseudoMethod findMethod(String name, String descriptor) {
+      for (PseudoMethod method : myMethods) {
+        if (method.getName().equals(name) && method.getSignature().equals(descriptor)){
+          return method;
+        }
+      }
+      return null;
+    }
+
+    public InstrumentationClassFinder getFinder() {
+      return InstrumentationClassFinder.this;
+    }
+
+    public PseudoClass getSuperClass() throws IOException, ClassNotFoundException {
+      final String superClass = mySuperClass;
+      return superClass != null? loadClass(superClass) : null;
+    }
+
+    public PseudoClass[] getInterfaces() throws IOException, ClassNotFoundException {
+      if (myInterfaces == null) {
+        return EMPTY_PSEUDOCLASS_ARRAY;
+      }
+
+      final PseudoClass[] result = new PseudoClass[myInterfaces.length];
+
+      for (int i = 0; i < result.length; i++) {
+        result[i] = loadClass(myInterfaces[i]);
+      }
+
+      return result;
+    }
+
+    public boolean equals (final Object o) {
+      if (this == o) return true;
+      if (o == null || getClass() != o.getClass()) return false;
+
+      return getName().equals(((PseudoClass)o).getName());
+    }
+
+    private boolean isSubclassOf(final PseudoClass x) throws IOException, ClassNotFoundException {
+      for (PseudoClass c = this; c != null; c = c.getSuperClass()) {
+        final PseudoClass superClass = c.getSuperClass();
+
+        if (superClass != null && superClass.equals(x)) {
+          return true;
+        }
+      }
+
+      return false;
+    }
+
+    private boolean implementsInterface(final PseudoClass x) throws IOException, ClassNotFoundException {
+      for (PseudoClass c = this; c != null; c = c.getSuperClass()) {
+        final PseudoClass[] tis = c.getInterfaces();
+        for (final PseudoClass ti : tis) {
+          if (ti.equals(x) || ti.implementsInterface(x)) {
+            return true;
+          }
+        }
+      }
+      return false;
+    }
+
+    public boolean isAssignableFrom(final PseudoClass x) throws IOException, ClassNotFoundException {
+      if (this.equals(x)) {
+        return true;
+      }
+      if (x.isSubclassOf(this)) {
+        return true;
+      }
+      if (x.implementsInterface(this)) {
+        return true;
+      }
+      if (x.isInterface() && "java/lang/Object".equals(getName())) {
+        return true;
+      }
+      return false;
+    }
+
+    public boolean hasDefaultPublicConstructor() {
+      for (PseudoMethod method : myMethods) {
+        if ("<init>".equals(method.getName()) && "()V".equals(method.getSignature())) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    public String getDescriptor() {
+      return "L" + myName + ";";
+    }
+  }
+
+  public static final class PseudoMethod {
+    private final int myAccess;
+    private final String myName;
+    private final String mySignature;
+
+    public PseudoMethod(int access, String name, String signature) {
+      myAccess = access;
+      myName = name;
+      mySignature = signature;
+    }
+
+    public int getModifiers() {
+      return myAccess;
+    }
+
+    public String getName() {
+      return myName;
+    }
+
+    public String getSignature() {
+      return mySignature;
+    }
+  }
+
+  private static class V extends ClassVisitor {
+    public String mySuperclassName = null;
+    public String[] myInterfaces = null;
+    public String myName = null;
+    public int myModifiers;
+    private final List<PseudoMethod> myMethods = new ArrayList<PseudoMethod>();
+
+    private V() {
+      super(Opcodes.ASM4);
+    }
+
+    public MethodVisitor visitMethod(int access, String name, String desc, String signature, String[] exceptions) {
+      if ((access & Opcodes.ACC_PUBLIC) > 0) {
+        myMethods.add(new PseudoMethod(access, name, desc));
+      }
+      return super.visitMethod(access, name, desc, signature, exceptions);
+    }
+
+    public void visit(int version, int access, String pName, String signature, String pSuperName, String[] pInterfaces) {
+      mySuperclassName = pSuperName;
+      myInterfaces = pInterfaces;
+      myName = pName;
+      myModifiers = access;
+    }
+  }
+
+  static class ClassFinderClasspath {
+    private static final String FILE_PROTOCOL = "file";
+
+    private final Stack<URL> myUrls = new Stack<URL>();
+    private final List<Loader> myLoaders = new ArrayList<Loader>();
+    private final Map<URL,Loader> myLoadersMap = new HashMap<URL, Loader>();
+
+    public ClassFinderClasspath(URL[] urls) {
+      if (urls.length > 0) {
+        for (int i = urls.length - 1; i >= 0; i--) {
+          myUrls.push(urls[i]);
+        }
+      }
+    }
+
+    public Resource getResource(String s, boolean flag) {
+      int i = 0;
+      for (Loader loader; (loader = getLoader(i)) != null; i++) {
+        Resource resource = loader.getResource(s, flag);
+        if (resource != null) {
+          return resource;
+        }
+      }
+
+      return null;
+    }
+
+    public void releaseResources() {
+      for (Loader loader : myLoaders) {
+        loader.releaseResources();
+      }
+      myLoaders.clear();
+      myLoadersMap.clear();
+    }
+
+    private synchronized Loader getLoader(int i) {
+      while (myLoaders.size() < i + 1) {
+        URL url;
+        synchronized (myUrls) {
+          if (myUrls.empty()) {
+            return null;
+          }
+          url = myUrls.pop();
+        }
+
+        if (myLoadersMap.containsKey(url)) {
+          continue;
+        }
+
+        Loader loader;
+        try {
+          loader = getLoader(url, myLoaders.size());
+          if (loader == null) {
+            continue;
+          }
+        }
+        catch (IOException ioexception) {
+          continue;
+        }
+
+        myLoaders.add(loader);
+        myLoadersMap.put(url, loader);
+      }
+
+      return myLoaders.get(i);
+    }
+
+    private Loader getLoader(final URL url, int index) throws IOException {
+      String s;
+      try {
+        s = url.toURI().getSchemeSpecificPart();
+      }
+      catch (URISyntaxException thisShouldNotHappen) {
+        thisShouldNotHappen.printStackTrace();
+        s = url.getFile();
+      }
+
+      Loader loader = null;
+      if (s != null  && new File(s).isDirectory()) {
+        if (FILE_PROTOCOL.equals(url.getProtocol())) {
+          loader = new FileLoader(url, index);
+        }
+      }
+      else {
+        loader = new JarLoader(url, index);
+      }
+
+      return loader;
+    }
+
+
+    private abstract static class Loader {
+      protected static final String JAR_PROTOCOL = "jar";
+      protected static final String FILE_PROTOCOL = "file";
+
+      private final URL myURL;
+      private final int myIndex;
+
+      protected Loader(URL url, int index) {
+        myURL = url;
+        myIndex = index;
+      }
+
+
+      protected URL getBaseURL() {
+        return myURL;
+      }
+
+      public abstract Resource getResource(final String name, boolean flag);
+
+      public abstract void releaseResources();
+
+      public int getIndex() {
+        return myIndex;
+      }
+    }
+
+    private static class FileLoader extends Loader {
+      private final File myRootDir;
+
+      @SuppressWarnings({"HardCodedStringLiteral"})
+      FileLoader(URL url, int index) throws IOException {
+        super(url, index);
+        if (!FILE_PROTOCOL.equals(url.getProtocol())) {
+          throw new IllegalArgumentException("url");
+        }
+        else {
+          final String s = unescapePercentSequences(url.getFile().replace('/', File.separatorChar));
+          myRootDir = new File(s);
+        }
+      }
+
+      public void releaseResources() {
+      }
+
+      public Resource getResource(final String name, boolean check) {
+        URL url = null;
+        File file = null;
+
+        try {
+          url = new URL(getBaseURL(), name);
+          if (!url.getFile().startsWith(getBaseURL().getFile())) {
+            return null;
+          }
+
+          file = new File(myRootDir, name.replace('/', File.separatorChar));
+          if (!check || file.exists()) {     // check means we load or process resource so we check its existence via old way
+            return new FileResource(name, url, file, !check);
+          }
+        }
+        catch (Exception exception) {
+          if (!check && file != null && file.exists()) {
+            try {   // we can not open the file if it is directory, Resource still can be created
+              return new FileResource(name, url, file, false);
+            }
+            catch (IOException ex) {
+            }
+          }
+        }
+        return null;
+      }
+
+      private class FileResource extends Resource {
+        private final String myName;
+        private final URL myUrl;
+        private final File myFile;
+
+        public FileResource(String name, URL url, File file, boolean willLoadBytes) throws IOException {
+          myName = name;
+          myUrl = url;
+          myFile = file;
+          if (willLoadBytes) getByteBuffer(); // check for existence by creating cached file input stream
+        }
+
+        public String getName() {
+          return myName;
+        }
+
+        public URL getURL() {
+          return myUrl;
+        }
+
+        public URL getCodeSourceURL() {
+          return getBaseURL();
+        }
+
+        public InputStream getInputStream() throws IOException {
+          return new BufferedInputStream(new FileInputStream(myFile));
+        }
+
+        public int getContentLength() throws IOException {
+          return -1;
+        }
+
+        public String toString() {
+          return myFile.getAbsolutePath();
+        }
+      }
+
+      public String toString() {
+        return "FileLoader [" + myRootDir + "]";
+      }
+    }
+
+    private class JarLoader extends Loader {
+      private final URL myURL;
+      private ZipFile myZipFile;
+
+      JarLoader(URL url, int index) throws IOException {
+        super(new URL(JAR_PROTOCOL, "", -1, url + "!/"), index);
+        myURL = url;
+      }
+
+      public void releaseResources() {
+        final ZipFile zipFile = myZipFile;
+        if (zipFile != null) {
+          myZipFile = null;
+          try {
+            zipFile.close();
+          }
+          catch (IOException e) {
+            throw new RuntimeException();
+          }
+        }
+      }
+
+      private ZipFile acquireZipFile() throws IOException {
+        ZipFile zipFile = myZipFile;
+        if (zipFile == null) {
+          zipFile = doGetZipFile();
+          myZipFile = zipFile;
+        }
+        return zipFile;
+      }
+
+      private ZipFile doGetZipFile() throws IOException {
+        if (FILE_PROTOCOL.equals(myURL.getProtocol())) {
+          String s = unescapePercentSequences(myURL.getFile().replace('/', File.separatorChar));
+          if (!new File(s).exists()) {
+            throw new FileNotFoundException(s);
+          }
+          else {
+            return new ZipFile(s);
+          }
+        }
+
+        return null;
+      }
+
+      public Resource getResource(String name, boolean flag) {
+        try {
+          final ZipFile file = acquireZipFile();
+          if (file != null) {
+            final ZipEntry entry = file.getEntry(name);
+            if (entry != null) {
+              return new JarResource(entry, new URL(getBaseURL(), name));
+            }
+          }
+        }
+        catch (Exception e) {
+          return null;
+        }
+        return null;
+      }
+
+      private class JarResource extends Resource {
+        private final ZipEntry myEntry;
+        private final URL myUrl;
+
+        public JarResource(ZipEntry name, URL url) {
+          myEntry = name;
+          myUrl = url;
+        }
+
+        public String getName() {
+          return myEntry.getName();
+        }
+
+        public URL getURL() {
+          return myUrl;
+        }
+
+        public URL getCodeSourceURL() {
+          return myURL;
+        }
+
+        public InputStream getInputStream() throws IOException {
+          try {
+            final ZipFile file = acquireZipFile();
+            if (file == null) {
+              return null;
+            }
+
+            final InputStream inputStream = file.getInputStream(myEntry);
+            if (inputStream == null) {
+              return null; // if entry was not found
+            }
+            return new FilterInputStream(inputStream) {};
+          }
+          catch (IOException e) {
+            e.printStackTrace();
+            return null;
+          }
+        }
+
+        public int getContentLength() {
+          return (int)myEntry.getSize();
+        }
+      }
+
+      public String toString() {
+        return "JarLoader [" + myURL + "]";
+      }
+    }
+  }
+
+
+  private static String unescapePercentSequences(String s) {
+    if (s.indexOf('%') == -1) {
+      return s;
+    }
+    StringBuilder decoded = new StringBuilder();
+    final int len = s.length();
+    int i = 0;
+    while (i < len) {
+      char c = s.charAt(i);
+      if (c == '%') {
+        List<Integer> bytes = new ArrayList<Integer>();
+        while (i + 2 < len && s.charAt(i) == '%') {
+          final int d1 = decode(s.charAt(i + 1));
+          final int d2 = decode(s.charAt(i + 2));
+          if (d1 != -1 && d2 != -1) {
+            bytes.add(((d1 & 0xf) << 4 | d2 & 0xf));
+            i += 3;
+          }
+          else {
+            break;
+          }
+        }
+        if (!bytes.isEmpty()) {
+          final byte[] bytesArray = new byte[bytes.size()];
+          for (int j = 0; j < bytes.size(); j++) {
+            bytesArray[j] = (byte)bytes.get(j).intValue();
+          }
+          try {
+            decoded.append(new String(bytesArray, "UTF-8"));
+            continue;
+          }
+          catch (UnsupportedEncodingException ignored) {
+          }
+        }
+      }
+
+      decoded.append(c);
+      i++;
+    }
+    return decoded.toString();
+  }
+
+  private static int decode(char c) {
+    if ((c >= '0') && (c <= '9')){
+      return c - '0';
+    }
+    if ((c >= 'a') && (c <= 'f')){
+      return c - 'a' + 10;
+    }
+    if ((c >= 'A') && (c <= 'F')){
+      return c - 'A' + 10;
+    }
+    return -1;
+  }
+
+  public byte[] loadBytes(InputStream stream) {
+    byte[] buf = myBuffer;
+    if (buf == null) {
+      buf = new byte[512];
+      myBuffer = buf;
+    }
+
+    final ByteArrayOutputStream result = new ByteArrayOutputStream();
+    try {
+      while (true) {
+        int n = stream.read(buf, 0, buf.length);
+        if (n <= 0) {
+          break;
+        }
+        result.write(buf, 0, n);
+      }
+      result.close();
+    }
+    catch (IOException ignored) {
+    }
+    return result.toByteArray();
+  }
+
+}
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java
new file mode 100644
index 0000000..b2f93c5
--- /dev/null
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/instrumentation/InstrumenterClassWriter.java
@@ -0,0 +1,43 @@
+package com.intellij.compiler.instrumentation;
+
+import org.jetbrains.asm4.ClassWriter;
+
+/**
+* @author Eugene Zhuravlev
+*         Date: 3/27/12
+*/
+public class InstrumenterClassWriter extends ClassWriter {
+  private final InstrumentationClassFinder myFinder;
+
+  public InstrumenterClassWriter(int flags, final InstrumentationClassFinder finder) {
+    super(flags);
+    myFinder = finder;
+  }
+
+  protected String getCommonSuperClass(final String type1, final String type2) {
+    try {
+      final InstrumentationClassFinder.PseudoClass cls1 = myFinder.loadClass(type1);
+      final InstrumentationClassFinder.PseudoClass cls2 = myFinder.loadClass(type2);
+      if (cls1.isAssignableFrom(cls2)) {
+        return cls1.getName();
+      }
+      if (cls2.isAssignableFrom(cls1)) {
+        return cls2.getName();
+      }
+      if (cls1.isInterface() || cls2.isInterface()) {
+        return "java/lang/Object";
+      }
+      else {
+        InstrumentationClassFinder.PseudoClass c = cls1;
+        do {
+          c = c.getSuperClass();
+        }
+        while (!c.isAssignableFrom(cls2));
+        return c.getName();
+      }
+    }
+    catch (Exception e) {
+      throw new RuntimeException(e.toString(), e);
+    }
+  }
+}
diff --git a/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
new file mode 100644
index 0000000..77bc538
--- /dev/null
+++ b/java/compiler/instrumentation-util/src/com/intellij/compiler/notNullVerification/NotNullVerifyingInstrumenter.java
@@ -0,0 +1,182 @@
+/*
+ * 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.compiler.notNullVerification;
+
+import org.jetbrains.asm4.*;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public class NotNullVerifyingInstrumenter extends ClassVisitor implements Opcodes {
+  private static final String NOT_NULL_CLASS_NAME = "org/jetbrains/annotations/NotNull";
+  private static final String NOT_NULL_TYPE = "L"+ NOT_NULL_CLASS_NAME + ";";
+  private static final String SYNTHETIC_CLASS_NAME = "java/lang/Synthetic";
+  private static final String SYNTHETIC_TYPE = "L" + SYNTHETIC_CLASS_NAME + ";";
+  private static final String IAE_CLASS_NAME = "java/lang/IllegalArgumentException";
+  private static final String ISE_CLASS_NAME = "java/lang/IllegalStateException";
+  private static final String STRING_CLASS_NAME = "java/lang/String";
+  private static final String CONSTRUCTOR_NAME = "<init>";
+  private static final String EXCEPTION_INIT_SIGNATURE = "(L" + STRING_CLASS_NAME + ";)V";
+
+  private static final String NULL_ARG_MESSAGE = "Argument %d for @NotNull parameter of %s.%s must not be null";
+  private static final String NULL_RESULT_MESSAGE = "@NotNull method %s.%s must not return null";
+
+  private String myClassName;
+  private boolean myIsModification = false;
+  private RuntimeException myPostponedError;
+
+  public NotNullVerifyingInstrumenter(final ClassVisitor classVisitor) {
+    super(Opcodes.ASM4, classVisitor);
+  }
+
+  public boolean isModification() {
+    return myIsModification;
+  }
+
+  @Override
+  public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+    super.visit(version, access, name, signature, superName, interfaces);
+    myClassName = name;
+  }
+
+  @Override
+  public MethodVisitor visitMethod(final int access, final String name, String desc, String signature, String[] exceptions) {
+    final Type[] args = Type.getArgumentTypes(desc);
+    final Type returnType = Type.getReturnType(desc);
+    final MethodVisitor v = cv.visitMethod(access, name, desc, signature, exceptions);
+    return new MethodVisitor(Opcodes.ASM4, v) {
+
+      private final List<Integer> myNotNullParams = new ArrayList<Integer>();
+      private int mySyntheticCount = 0;
+      private boolean myIsNotNull = false;
+      private Label myStartGeneratedCodeLabel;
+
+      public AnnotationVisitor visitParameterAnnotation(final int parameter, final String anno, final boolean visible) {
+        final AnnotationVisitor av = mv.visitParameterAnnotation(parameter, anno, visible);
+        if (isReferenceType(args[parameter]) && anno.equals(NOT_NULL_TYPE)) {
+          myNotNullParams.add(new Integer(parameter));
+        }
+        else if (anno.equals(SYNTHETIC_TYPE)) {
+          // see http://forge.ow2.org/tracker/?aid=307392&group_id=23&atid=100023&func=detail
+          mySyntheticCount++;
+        }
+        return av;
+      }
+
+      @Override
+      public AnnotationVisitor visitAnnotation(String anno, boolean isRuntime) {
+        final AnnotationVisitor av = mv.visitAnnotation(anno, isRuntime);
+        if (isReferenceType(returnType) && anno.equals(NOT_NULL_TYPE)) {
+          myIsNotNull = true;
+        }
+
+        return av;
+      }
+
+      @Override
+      public void visitCode() {
+        if (myNotNullParams.size() > 0) {
+          myStartGeneratedCodeLabel = new Label();
+          mv.visitLabel(myStartGeneratedCodeLabel);
+        }
+        for (Integer param : myNotNullParams) {
+          int var = ((access & ACC_STATIC) == 0) ? 1 : 0;
+          for (int i = 0; i < param; ++i) {
+            var += args[i].getSize();
+          }
+          mv.visitVarInsn(ALOAD, var);
+
+          Label end = new Label();
+          mv.visitJumpInsn(IFNONNULL, end);
+
+          generateThrow(IAE_CLASS_NAME, String.format(NULL_ARG_MESSAGE, param - mySyntheticCount, myClassName, name), end);
+        }
+      }
+
+      @Override
+      public void visitLocalVariable(String name, String desc, String signature, Label start, Label end, int index) {
+        final boolean isStatic = (access & ACC_STATIC) != 0;
+        final boolean isParameter = isStatic ? index < args.length : index <= args.length;
+        final Label label = (isParameter && myStartGeneratedCodeLabel != null) ? myStartGeneratedCodeLabel : start;
+        mv.visitLocalVariable(name, desc, signature, label, end, index);
+      }
+
+      @Override
+      public void visitInsn(int opcode) {
+        if (opcode == ARETURN) {
+          if (myIsNotNull) {
+            mv.visitInsn(DUP);
+            final Label skipLabel = new Label();
+            mv.visitJumpInsn(IFNONNULL, skipLabel);
+            generateThrow(ISE_CLASS_NAME, String.format(NULL_RESULT_MESSAGE, myClassName, name), skipLabel);
+          }
+        }
+
+        mv.visitInsn(opcode);
+      }
+
+      private void generateThrow(final String exceptionClass, final String descr, final Label end) {
+        mv.visitTypeInsn(NEW, exceptionClass);
+        mv.visitInsn(DUP);
+        mv.visitLdcInsn(descr);
+        mv.visitMethodInsn(INVOKESPECIAL, exceptionClass, CONSTRUCTOR_NAME, EXCEPTION_INIT_SIGNATURE);
+        mv.visitInsn(ATHROW);
+        mv.visitLabel(end);
+
+        myIsModification = true;
+        processPostponedErrors();
+      }
+
+      @Override
+      public void visitMaxs(final int maxStack, final int maxLocals) {
+        try {
+          super.visitMaxs(maxStack, maxLocals);
+        }
+        catch (Throwable e) {
+          registerError(name, "visitMaxs", e);
+        }
+      }
+    };
+  }
+
+  private static boolean isReferenceType(final Type type) {
+    return type.getSort() == Type.OBJECT || type.getSort() == Type.ARRAY;
+  }
+
+  private void registerError(String methodName, String operationName, Throwable e) {
+    if (myPostponedError == null) {
+      // throw the first error that occurred
+      Throwable err = e.getCause();
+      if (err == null) {
+        err = e;
+      }
+      myPostponedError = new RuntimeException("Operation '" + operationName + "' failed for " + myClassName + "." + methodName + "(): " + err.getMessage(), err);
+    }
+    if (myIsModification) {
+      processPostponedErrors();
+    }
+  }
+
+  private void processPostponedErrors() {
+    final RuntimeException error = myPostponedError;
+    if (error != null) {
+      throw error;
+    }
+  }
+}
diff --git a/java/compiler/javac2/javac2.iml b/java/compiler/javac2/javac2.iml
new file mode 100644
index 0000000..c44096e
--- /dev/null
+++ b/java/compiler/javac2/javac2.iml
@@ -0,0 +1,169 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="false" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" LANGUAGE_LEVEL="JDK_1_5" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="library" name="Ant" level="project" />
+    <orderEntry type="module" module-name="forms-compiler" />
+    <orderEntry type="module" module-name="forms_rt" />
+    <orderEntry type="library" name="asm4" level="project" />
+    <orderEntry type="module" module-name="instrumentation-util" />
+  </component>
+  <component name="copyright">
+    <Base>
+      <setting name="state" value="0" />
+    </Base>
+    <LanguageOptions name="HTML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JAVA">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="/*&#10; * Copyright 2000-2005 JetBrains s.r.o.&#10; * &#10; * Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10; * you may not use this file except in compliance with the License.&#10; * You may obtain a copy of the License at&#10; * &#10; * http://www.apache.org/licenses/LICENSE-2.0&#10; * &#10; * Unless required by applicable law or agreed to in writing, software&#10; * distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10; * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10; * See the License for the specific language governing permissions and&#10; * limitations under the License.&#10; */" />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JSP">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JavaScript">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="Properties">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="XML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="__TEMPLATE__">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright 2000-&amp;#36;{today.year} JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="4" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+  </component>
+</module>
+
diff --git a/java/compiler/javac2/src/com/intellij/ant/InstrumentIdeaExtensions.java b/java/compiler/javac2/src/com/intellij/ant/InstrumentIdeaExtensions.java
new file mode 100644
index 0000000..0c07341
--- /dev/null
+++ b/java/compiler/javac2/src/com/intellij/ant/InstrumentIdeaExtensions.java
@@ -0,0 +1,32 @@
+/*
+ * 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.ant;
+
+/**
+ * This ant task is used to instrument compiled classes with idea
+ * extensions without compiling java sources.
+ */
+public class InstrumentIdeaExtensions extends Javac2 {
+    /**
+     * Customize behavior of {@link Javac2} disabling compilation of java classes.
+     *
+     * @return false, meaning that java classes are not compiled
+     * @see com.intellij.ant.Javac2#areJavaClassesCompiled()
+     */
+    protected boolean areJavaClassesCompiled() {
+        return false;
+    }
+}
diff --git a/java/compiler/javac2/src/com/intellij/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
new file mode 100644
index 0000000..3676261
--- /dev/null
+++ b/java/compiler/javac2/src/com/intellij/ant/Javac2.java
@@ -0,0 +1,554 @@
+/*
+ * 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.ant;
+
+import com.intellij.compiler.instrumentation.InstrumentationClassFinder;
+import com.intellij.compiler.instrumentation.InstrumenterClassWriter;
+import com.intellij.compiler.notNullVerification.NotNullVerifyingInstrumenter;
+import com.intellij.uiDesigner.compiler.*;
+import com.intellij.uiDesigner.lw.CompiledClassPropertiesProvider;
+import com.intellij.uiDesigner.lw.LwRootContainer;
+import org.apache.tools.ant.BuildException;
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.taskdefs.Javac;
+import org.apache.tools.ant.types.Path;
+import org.jetbrains.asm4.ClassReader;
+import org.jetbrains.asm4.ClassVisitor;
+import org.jetbrains.asm4.ClassWriter;
+import org.jetbrains.asm4.Opcodes;
+
+import java.io.*;
+import java.net.MalformedURLException;
+import java.net.URL;
+import java.util.*;
+
+public class Javac2 extends Javac {
+    private ArrayList myFormFiles;
+    private List myNestedFormPathList;
+
+    public Javac2() {
+    }
+
+    /**
+     * Check if Java classes should be actually compiled by the task. This method is overridden by
+     * {@link com.intellij.ant.InstrumentIdeaExtensions} task in order to suppress actual compilation
+     * of the java sources.
+     *
+     * @return true if the java classes are compiled, false if just instrumentation is performed.
+     */
+    protected boolean areJavaClassesCompiled() {
+        return true;
+    }
+
+    /**
+     * This method is called when option that supported only for the case when java sources are compiled
+     * and it is not supported for the case when only instrumentation is performed.
+     *
+     * @param optionName the option name to warn about.
+     */
+    private void unsupportedOptionMessage(final String optionName) {
+        if (!areJavaClassesCompiled()) {
+            log("The option " + optionName + " is not supported by InstrumentIdeaExtensions task", Project.MSG_ERR);
+        }
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param v the option value
+     */
+    public void setDebugLevel(String v) {
+        unsupportedOptionMessage("debugLevel");
+        super.setDebugLevel(v);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param list the option value
+     */
+    public void setListfiles(boolean list) {
+        unsupportedOptionMessage("listFiles");
+        super.setListfiles(list);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param memoryInitialSize the option value
+     */
+    public void setMemoryInitialSize(String memoryInitialSize) {
+        unsupportedOptionMessage("memoryInitialSize");
+        super.setMemoryInitialSize(memoryInitialSize);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param memoryMaximumSize the option value
+     */
+    public void setMemoryMaximumSize(String memoryMaximumSize) {
+        unsupportedOptionMessage("memoryMaximumSize");
+        super.setMemoryMaximumSize(memoryMaximumSize);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param encoding the option value
+     */
+    public void setEncoding(String encoding) {
+        unsupportedOptionMessage("encoding");
+        super.setEncoding(encoding);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param optimize the option value
+     */
+    public void setOptimize(boolean optimize) {
+        unsupportedOptionMessage("optimize");
+        super.setOptimize(optimize);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param depend the option value
+     */
+    public void setDepend(boolean depend) {
+        unsupportedOptionMessage("depend");
+        super.setDepend(depend);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param f the option value
+     */
+    public void setFork(boolean f) {
+        unsupportedOptionMessage("fork");
+        super.setFork(f);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param forkExec the option value
+     */
+    public void setExecutable(String forkExec) {
+        unsupportedOptionMessage("executable");
+        super.setExecutable(forkExec);
+    }
+
+    /**
+     * The overridden setter method that warns about unsupported option.
+     *
+     * @param compiler the option value
+     */
+    public void setCompiler(String compiler) {
+        unsupportedOptionMessage("compiler");
+        super.setCompiler(compiler);
+    }
+
+    /**
+     * Sets the nested form directories that will be used during the
+     * compilation.
+     * @param nestedformdirs a list of {@link PrefixedPath}
+     */
+    public void setNestedformdirs(List nestedformdirs) {
+        myNestedFormPathList = nestedformdirs;
+    }
+
+    /**
+     * Gets the nested form directories that will be used during the
+     * compilation.
+     * @return the extension directories as a list of {@link PrefixedPath}
+     */
+    public List getNestedformdirs() {
+        return myNestedFormPathList;
+    }
+
+    /**
+     * Adds a path to nested form directories.
+     * @return a path to be configured
+     */
+    public PrefixedPath createNestedformdirs() {
+        PrefixedPath p = new PrefixedPath(getProject());
+        if (myNestedFormPathList == null) {
+            myNestedFormPathList = new ArrayList();
+        }
+        myNestedFormPathList.add(p);
+        return p;
+    }
+
+    /**
+     * The overridden compile method that does not actually compiles java sources but only instruments
+     * class files.
+     */
+    protected void compile() {
+      // compile java
+      if (areJavaClassesCompiled()) {
+        super.compile();
+      }
+
+      InstrumentationClassFinder finder = buildClasspathClassLoader();
+      if (finder == null) {
+        return;
+      }
+      try {
+        instrumentForms(finder);
+
+        //NotNull instrumentation
+        final int instrumented = instrumentNotNull(getDestdir(), finder);
+
+        log("Added @NotNull assertions to " + instrumented + " files", Project.MSG_INFO);
+      }
+      finally {
+        finder.releaseResources();
+      }
+    }
+
+  /**
+     * Instrument forms
+     *
+     * @param finder a classloader to use
+     */
+    private void instrumentForms(final InstrumentationClassFinder finder) {
+        // we instrument every file, because we cannot find which files should not be instrumented without dependency storage
+        final ArrayList formsToInstrument = myFormFiles;
+
+        if (formsToInstrument.size() == 0) {
+            log("No forms to instrument found", Project.MSG_VERBOSE);
+            return;
+        }
+
+        final HashMap class2form = new HashMap();
+
+        for (int i = 0; i < formsToInstrument.size(); i++) {
+            final File formFile = (File)formsToInstrument.get(i);
+
+            log("compiling form " + formFile.getAbsolutePath(), Project.MSG_VERBOSE);
+            final LwRootContainer rootContainer;
+            try {
+                rootContainer = Utils.getRootContainer(formFile.toURI().toURL(), new CompiledClassPropertiesProvider(finder.getLoader()));
+            }
+            catch (AlienFormFileException e) {
+                // ignore non-IDEA forms
+                continue;
+            }
+            catch (Exception e) {
+                fireError("Cannot process form file " + formFile.getAbsolutePath() + ". Reason: " + e);
+                continue;
+            }
+
+            final String classToBind = rootContainer.getClassToBind();
+            if (classToBind == null) {
+                continue;
+            }
+
+            String name = classToBind.replace('.', '/');
+            File classFile = getClassFile(name);
+            if (classFile == null) {
+                log(formFile.getAbsolutePath() + ": Class to bind does not exist: " + classToBind, Project.MSG_WARN);
+                continue;
+            }
+
+            final File alreadyProcessedForm = (File)class2form.get(classToBind);
+            if (alreadyProcessedForm != null) {
+                fireError(formFile.getAbsolutePath() +
+                          ": " +
+                          "The form is bound to the class " +
+                          classToBind +
+                          ".\n" +
+                          "Another form " +
+                          alreadyProcessedForm.getAbsolutePath() +
+                          " is also bound to this class.");
+                continue;
+            }
+            class2form.put(classToBind, formFile);
+
+            try {
+                int version;
+                InputStream stream = new FileInputStream(classFile);
+                try {
+                    version = getClassFileVersion(new ClassReader(stream));
+                }
+                finally {
+                    stream.close();
+                }
+                AntNestedFormLoader formLoader = new AntNestedFormLoader(finder.getLoader(), myNestedFormPathList);
+                InstrumenterClassWriter classWriter = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder);
+                final AsmCodeGenerator codeGenerator = new AsmCodeGenerator(rootContainer, finder, formLoader, false, classWriter);
+                codeGenerator.patchFile(classFile);
+                final FormErrorInfo[] warnings = codeGenerator.getWarnings();
+
+                for (int j = 0; j < warnings.length; j++) {
+                    log(formFile.getAbsolutePath() + ": " + warnings[j].getErrorMessage(), Project.MSG_WARN);
+                }
+                final FormErrorInfo[] errors = codeGenerator.getErrors();
+                if (errors.length > 0) {
+                    StringBuffer message = new StringBuffer();
+                    for (int j = 0; j < errors.length; j++) {
+                        if (message.length() > 0) {
+                            message.append("\n");
+                        }
+                        message.append(formFile.getAbsolutePath()).append(": ").append(errors[j].getErrorMessage());
+                    }
+                    fireError(message.toString());
+                }
+            }
+            catch (Exception e) {
+                fireError("Forms instrumentation failed for " + formFile.getAbsolutePath() + ": " + e.toString());
+            }
+        }
+    }
+
+    /**
+     * @return the flags for class writer
+     */
+    private static int getAsmClassWriterFlags(int version) {
+        return version >= Opcodes.V1_6 && version != Opcodes.V1_1 ? ClassWriter.COMPUTE_FRAMES : ClassWriter.COMPUTE_MAXS;
+    }
+
+    /**
+     * Create class loader based on classpath, bootclasspath, and sourcepath.
+     *
+     * @return a URL classloader
+     */
+    private InstrumentationClassFinder buildClasspathClassLoader() {
+        final StringBuffer classPathBuffer = new StringBuffer();
+        final Path cp = new Path(getProject());
+        appendPath(cp, getBootclasspath());
+        cp.setLocation(getDestdir().getAbsoluteFile());
+        appendPath(cp, getClasspath());
+        appendPath(cp, getSourcepath());
+        appendPath(cp, getSrcdir());
+        if (getIncludeantruntime()) {
+            cp.addExisting(cp.concatSystemClasspath("last"));
+        }
+        if (getIncludejavaruntime()) {
+            cp.addJavaRuntime();
+        }
+        cp.addExtdirs(getExtdirs());
+
+        final String[] pathElements = cp.list();
+        for (int i = 0; i < pathElements.length; i++) {
+            final String pathElement = pathElements[i];
+            classPathBuffer.append(File.pathSeparator);
+            classPathBuffer.append(pathElement);
+        }
+
+        final String classPath = classPathBuffer.toString();
+        log("classpath=" + classPath, Project.MSG_VERBOSE);
+
+        try {
+            return createInstrumentationClassFinder(classPath);
+        }
+        catch (MalformedURLException e) {
+            fireError(e.getMessage());
+            return null;
+        }
+    }
+
+    /**
+     * Append path to class path if the appened path is not empty and is not null
+     *
+     * @param cp the path to modify
+     * @param p  the path to append
+     */
+    private void appendPath(Path cp, final Path p) {
+        if (p != null && p.size() > 0) {
+            cp.append(p);
+        }
+    }
+
+    /**
+     * Instrument classes with NotNull annotations
+     *
+     * @param dir    the directory with classes to instrument (the directory is processed recursively)
+     * @param finder the classloader to use
+     * @return the amount of classes actually affected by instrumentation
+     */
+    private int instrumentNotNull(File dir, final InstrumentationClassFinder finder) {
+        int instrumented = 0;
+        final File[] files = dir.listFiles();
+        for (int i = 0; i < files.length; i++) {
+            File file = files[i];
+            final String name = file.getName();
+            if (name.endsWith(".class")) {
+                final String path = file.getPath();
+                log("Adding @NotNull assertions to " + path, Project.MSG_VERBOSE);
+                try {
+                    final FileInputStream inputStream = new FileInputStream(file);
+                    try {
+                        ClassReader reader = new ClassReader(inputStream);
+
+                        int version = getClassFileVersion(reader);
+
+                        if (version >= Opcodes.V1_5) {
+                            ClassWriter writer = new InstrumenterClassWriter(getAsmClassWriterFlags(version), finder);
+
+                            final NotNullVerifyingInstrumenter instrumenter = new NotNullVerifyingInstrumenter(writer);
+                            reader.accept(instrumenter, 0);
+                            if (instrumenter.isModification()) {
+                                final FileOutputStream fileOutputStream = new FileOutputStream(path);
+                                try {
+                                    fileOutputStream.write(writer.toByteArray());
+                                    instrumented++;
+                                }
+                                finally {
+                                    fileOutputStream.close();
+                                }
+                            }
+                        }
+                    }
+                    finally {
+                        inputStream.close();
+                    }
+                }
+                catch (IOException e) {
+                    log("Failed to instrument @NotNull assertion for " + path + ": " + e.getMessage(), Project.MSG_WARN);
+                }
+                catch (Exception e) {
+                    fireError("@NotNull instrumentation failed for " + path + ": " + e.toString());
+                }
+            }
+            else if (file.isDirectory()) {
+                instrumented += instrumentNotNull(file, finder);
+            }
+        }
+
+        return instrumented;
+    }
+
+    private static int getClassFileVersion(ClassReader reader) {
+        final int[] classfileVersion = new int[1];
+        reader.accept(new ClassVisitor(Opcodes.ASM4) {
+            public void visit(int version, int access, String name, String signature, String superName, String[] interfaces) {
+                classfileVersion[0] = version;
+            }
+        }, 0);
+
+        return classfileVersion[0];
+    }
+
+    private void fireError(final String message) {
+        if (failOnError) {
+            throw new BuildException(message, getLocation());
+        }
+        else {
+            log(message, Project.MSG_ERR);
+        }
+    }
+
+    private File getClassFile(String className) {
+        final String classOrInnerName = getClassOrInnerName(className);
+        if (classOrInnerName == null) return null;
+        return new File(getDestdir().getAbsolutePath(), classOrInnerName + ".class");
+    }
+
+    private String getClassOrInnerName(String className) {
+        File classFile = new File(getDestdir().getAbsolutePath(), className + ".class");
+        if (classFile.exists()) return className;
+        int position = className.lastIndexOf('/');
+        if (position == -1) return null;
+        return getClassOrInnerName(className.substring(0, position) + '$' + className.substring(position + 1));
+    }
+
+    protected void resetFileLists() {
+        super.resetFileLists();
+        myFormFiles = new ArrayList();
+    }
+
+    protected void scanDir(final File srcDir, final File destDir, final String[] files) {
+        super.scanDir(srcDir, destDir, files);
+        for (int i = 0; i < files.length; i++) {
+            final String file = files[i];
+            if (file.endsWith(".form")) {
+                log("Found form file " + file, Project.MSG_VERBOSE);
+                myFormFiles.add(new File(srcDir, file));
+            }
+        }
+    }
+
+  private static InstrumentationClassFinder createInstrumentationClassFinder(final String classPath) throws MalformedURLException {
+    final ArrayList urls = new ArrayList();
+    for (StringTokenizer tokenizer = new StringTokenizer(classPath, File.pathSeparator); tokenizer.hasMoreTokens();) {
+      final String s = tokenizer.nextToken();
+      urls.add(new File(s).toURI().toURL());
+    }
+    final URL[] urlsArr = (URL[])urls.toArray(new URL[urls.size()]);
+    return new InstrumentationClassFinder(urlsArr);
+  }
+
+  private class AntNestedFormLoader implements NestedFormLoader {
+        private final ClassLoader myLoader;
+        private final List myNestedFormPathList;
+        private final HashMap myFormCache = new HashMap();
+
+        public AntNestedFormLoader(final ClassLoader loader, List nestedFormPathList) {
+            myLoader = loader;
+            myNestedFormPathList = nestedFormPathList;
+        }
+
+        public LwRootContainer loadForm(String formFilePath) throws Exception {
+            if (myFormCache.containsKey(formFilePath)) {
+                return (LwRootContainer)myFormCache.get(formFilePath);
+            }
+
+            String lowerFormFilePath = formFilePath.toLowerCase();
+            log("Searching for form " + lowerFormFilePath, Project.MSG_VERBOSE);
+            for (Iterator iterator = myFormFiles.iterator(); iterator.hasNext();) {
+                File file = (File)iterator.next();
+                String name = file.getAbsolutePath().replace(File.separatorChar, '/').toLowerCase();
+                log("Comparing with " + name, Project.MSG_VERBOSE);
+                if (name.endsWith(lowerFormFilePath)) {
+                  return loadForm(formFilePath, new FileInputStream(file));
+                }
+            }
+
+            if (myNestedFormPathList != null) {
+                for (int i = 0; i < myNestedFormPathList.size(); i++) {
+                    PrefixedPath path = (PrefixedPath)myNestedFormPathList.get(i);
+                    File formFile = path.findFile(formFilePath);
+                    if (formFile != null) {
+                        return loadForm(formFilePath, new FileInputStream(formFile));
+                    }
+                }
+            }
+            InputStream resourceStream = myLoader.getResourceAsStream(formFilePath);
+            if (resourceStream != null) {
+                return loadForm(formFilePath, resourceStream);
+            }
+            throw new Exception("Cannot find nested form file " + formFilePath);
+        }
+
+        private LwRootContainer loadForm(String formFileName, InputStream resourceStream) throws Exception {
+            final LwRootContainer container = Utils.getRootContainer(resourceStream, null);
+            myFormCache.put(formFileName, container);
+            return container;
+        }
+
+        public String getClassToBindName(LwRootContainer container) {
+            final String className = container.getClassToBind();
+            String result = getClassOrInnerName(className.replace('.', '/'));
+            if (result != null) return result.replace('/', '.');
+            return className;
+        }
+    }
+}
diff --git a/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java
new file mode 100644
index 0000000..c7af4eb
--- /dev/null
+++ b/java/compiler/javac2/src/com/intellij/ant/PrefixedPath.java
@@ -0,0 +1,79 @@
+/*
+ * Copyright 2000-2011 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.ant;
+
+import org.apache.tools.ant.Project;
+import org.apache.tools.ant.types.Path;
+
+import java.io.File;
+
+/**
+ * Allows to specify relative output prefix for Path.
+ * Used to support searching for nested form files under source roots with package prefixes.
+ *
+ * @author nik
+ */
+public class PrefixedPath extends Path {
+  private String myPrefix;
+
+  public PrefixedPath(Project project) {
+    super(project);
+  }
+
+  public PrefixedPath(Project p, String path) {
+    super(p, path);
+  }
+
+  public String getPrefix() {
+    return myPrefix;
+  }
+
+  public void setPrefix(String prefix) {
+    myPrefix = prefix;
+  }
+
+  public File findFile(String relativePath) {
+    relativePath = trimStartSlash(relativePath);
+    String prefix = myPrefix;
+    if (prefix != null) {
+      prefix = trimStartSlash(ensureEndsWithSlash(prefix));
+      if (!relativePath.toLowerCase().startsWith(prefix.toLowerCase())) {
+        return null;
+      }
+      relativePath = relativePath.substring(prefix.length());
+    }
+
+    String[] dirsList = list();
+    for (int j = 0, listLength = dirsList.length; j < listLength; j++) {
+      String fullPath = ensureEndsWithSlash(dirsList[j]) + relativePath;
+      File file = new File(fullPath.replace('/', File.separatorChar));
+      if (file.isFile()) {
+        return file;
+      }
+    }
+    return null;
+  }
+
+  private static String trimStartSlash(String path) {
+    if (path.startsWith("/")) return path.substring(1);
+    return path;
+  }
+
+  private static String ensureEndsWithSlash(String path) {
+    if (!path.endsWith("/")) return path + "/";
+    return path;
+  }
+}
diff --git a/java/compiler/javac2/src/com/intellij/uiDesigner/ant/Javac2.java b/java/compiler/javac2/src/com/intellij/uiDesigner/ant/Javac2.java
new file mode 100644
index 0000000..d5a0f4e
--- /dev/null
+++ b/java/compiler/javac2/src/com/intellij/uiDesigner/ant/Javac2.java
@@ -0,0 +1,30 @@
+/*
+ * 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.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 25.07.2006
+ * Time: 17:59:03
+ */
+package com.intellij.uiDesigner.ant;
+
+/**
+ * @noinspection ClassNameSameAsAncestorName
+ * @deprecated
+ */
+public class Javac2 extends com.intellij.ant.Javac2 {
+}
diff --git a/java/compiler/openapi/compiler-openapi.iml b/java/compiler/openapi/compiler-openapi.iml
new file mode 100644
index 0000000..9fb5c93
--- /dev/null
+++ b/java/compiler/openapi/compiler-openapi.iml
@@ -0,0 +1,165 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="openapi" />
+  </component>
+  <component name="copyright">
+    <Base>
+      <setting name="state" value="0" />
+    </Base>
+    <LanguageOptions name="HTML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JAVA">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="/*&#10; * Copyright (c) &amp;#36;today.year Your Corporation. All Rights Reserved.&#10; */" />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JSP">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="JavaScript">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="Properties">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="XML">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright (c) &amp;#36;today.year, Your Corporation. All Rights Reserved." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="2" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+    <LanguageOptions name="__TEMPLATE__">
+      <option name="templateOptions">
+        <value>
+          <option name="block" value="true" />
+          <option name="separateBefore" value="false" />
+          <option name="separateAfter" value="false" />
+          <option name="prefixLines" value="true" />
+          <option name="lenBefore" value="80" />
+          <option name="lenAfter" value="80" />
+          <option name="box" value="false" />
+          <option name="filler" value=" " />
+        </value>
+      </option>
+      <option name="notice" value="Copyright 2000-&amp;#36;{today.year} JetBrains s.r.o.&#10;&#10;Licensed under the Apache License, Version 2.0 (the &quot;License&quot;);&#10;you may not use this file except in compliance with the License.&#10;You may obtain a copy of the License at&#10;&#10;http://www.apache.org/licenses/LICENSE-2.0&#10;&#10;Unless required by applicable law or agreed to in writing, software&#10;distributed under the License is distributed on an &quot;AS IS&quot; BASIS,&#10;WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.&#10;See the License for the specific language governing permissions and&#10;limitations under the License." />
+      <option name="keyword" value="Copyright" />
+      <option name="fileTypeOverride" value="4" />
+      <option name="relativeBefore" value="true" />
+      <option name="addBlankAfter" value="true" />
+      <option name="fileLocation" value="1" />
+      <option name="useAlternate" value="false" />
+    </LanguageOptions>
+  </component>
+</module>
+
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java
new file mode 100644
index 0000000..9aa97cf
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerConfiguration.java
@@ -0,0 +1,64 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.compiler.options.ExcludedEntriesConfiguration;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+
+public abstract class CompilerConfiguration {
+  // need this flag for profiling purposes. In production code is always set to 'true'
+  public static final boolean MAKE_ENABLED = true;
+
+  @Nullable
+  public abstract String getProjectBytecodeTarget();
+
+  @Nullable
+  public abstract String getBytecodeTargetLevel(Module module);
+
+  public abstract void setBytecodeTargetLevel(Module module, String level);
+
+  @NotNull
+  public abstract AnnotationProcessingConfiguration getAnnotationProcessingConfiguration(Module module);
+
+  /**
+   * @return true if exists at least one enabled annotation processing profile
+   */
+  public abstract boolean isAnnotationProcessorsEnabled();
+
+  public static CompilerConfiguration getInstance(Project project) {
+    return project.getComponent(CompilerConfiguration.class);
+  }
+
+  public abstract boolean isExcludedFromCompilation(VirtualFile virtualFile);
+
+  public abstract boolean isResourceFile(VirtualFile virtualFile);
+
+  public abstract boolean isResourceFile(String path);
+
+  public abstract void addResourceFilePattern(String namePattern) throws MalformedPatternException;
+
+  public abstract boolean isAddNotNullAssertions();
+
+  public abstract void setAddNotNullAssertions(boolean enabled);
+
+  public abstract ExcludedEntriesConfiguration getExcludedEntriesConfiguration();
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java
new file mode 100644
index 0000000..c2e85ef
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerSettingsFactory.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.options.Configurable;
+import com.intellij.openapi.project.Project;
+
+/**
+ * Please use {@link com.intellij.openapi.options.ConfigurableEP#parentId} to put your configurable under Compiler Settings
+ * @author Eugene Zhuravlev
+ *         Date: Sep 17, 2008
+ */
+@Deprecated
+public interface CompilerSettingsFactory {
+  ExtensionPointName<CompilerSettingsFactory> EP_NAME = ExtensionPointName.create("com.intellij.compilerSettingsFactory");
+
+  Configurable create(Project project);
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
new file mode 100644
index 0000000..98250d9
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/CompilerWorkspaceConfiguration.java
@@ -0,0 +1,65 @@
+/*
+ * 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.
+ */
+
+/*
+ * @author Eugene Zhuravlev
+ */
+package com.intellij.compiler;
+
+import com.intellij.openapi.components.*;
+import com.intellij.openapi.project.Project;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+
+@State(
+  name = "CompilerWorkspaceConfiguration",
+  storages = {
+    @Storage(
+      file = StoragePathMacros.WORKSPACE_FILE
+    )}
+)
+public class CompilerWorkspaceConfiguration implements PersistentStateComponent<CompilerWorkspaceConfiguration> {
+  public static final int DEFAULT_COMPILE_PROCESS_HEAP_SIZE = 700;
+  public static final String DEFAULT_COMPILE_PROCESS_VM_OPTIONS = "-ea";
+
+  public boolean AUTO_SHOW_ERRORS_IN_EDITOR = true;
+  @Deprecated public boolean CLOSE_MESSAGE_VIEW_IF_SUCCESS = true;
+  public boolean CLEAR_OUTPUT_DIRECTORY = true;
+  public boolean USE_COMPILE_SERVER = true;
+  public boolean MAKE_PROJECT_ON_SAVE = true;
+  public boolean PARALLEL_COMPILATION = false;
+  public int COMPILER_PROCESS_HEAP_SIZE = DEFAULT_COMPILE_PROCESS_HEAP_SIZE;
+  public String COMPILER_PROCESS_ADDITIONAL_VM_OPTIONS = DEFAULT_COMPILE_PROCESS_VM_OPTIONS;
+
+  public static CompilerWorkspaceConfiguration getInstance(Project project) {
+    return ServiceManager.getService(project, CompilerWorkspaceConfiguration.class);
+  }
+
+  public CompilerWorkspaceConfiguration getState() {
+    return this;
+  }
+
+  public void loadState(CompilerWorkspaceConfiguration state) {
+    XmlSerializerUtil.copyBean(state, this);
+  }
+
+  public boolean useOutOfProcessBuild() {
+    return USE_COMPILE_SERVER;
+  }
+
+  public boolean allowAutoMakeWhileRunningApplication() {
+    return false;/*ALLOW_AUTOMAKE_WHILE_RUNNING_APPLICATION*/
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.java b/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.java
new file mode 100644
index 0000000..af7636c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/MalformedPatternException.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.compiler;
+
+public class MalformedPatternException extends RuntimeException {
+  public MalformedPatternException(Throwable cause) {
+    super(cause);
+  }
+
+  @Override
+  public String getLocalizedMessage() {
+    return getCause().getLocalizedMessage();
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java
new file mode 100644
index 0000000..44b7b2a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ModuleCompilerUtil.java
@@ -0,0 +1,173 @@
+/*
+ * 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.compiler;
+
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ModuleRootModel;
+import com.intellij.openapi.util.Pair;
+import com.intellij.util.Chunk;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.graph.*;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author dsl
+ */
+public final class ModuleCompilerUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.compiler.ModuleCompilerUtil");
+  private ModuleCompilerUtil() { }
+
+  public static Module[] getDependencies(Module module) {
+    return ModuleRootManager.getInstance(module).getDependencies();
+  }
+
+  public static Graph<Module> createModuleGraph(final Module[] modules) {
+    return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<Module>() {
+      public Collection<Module> getNodes() {
+        return Arrays.asList(modules);
+      }
+
+      public Iterator<Module> getIn(Module module) {
+        return Arrays.asList(getDependencies(module)).iterator();
+      }
+    }));
+  }
+
+  public static List<Chunk<Module>> getSortedModuleChunks(Project project, List<Module> modules) {
+    final Module[] allModules = ModuleManager.getInstance(project).getModules();
+    final List<Chunk<Module>> chunks = getSortedChunks(createModuleGraph(allModules));
+
+    final Set<Module> modulesSet = new HashSet<Module>(modules);
+    // leave only those chunks that contain at least one module from modules
+    for (Iterator<Chunk<Module>> it = chunks.iterator(); it.hasNext();) {
+      final Chunk<Module> chunk = it.next();
+      if (!ContainerUtil.intersects(chunk.getNodes(), modulesSet)) {
+        it.remove();
+      }
+    }
+    return chunks;
+  }
+
+  public static <Node> List<Chunk<Node>> getSortedChunks(final Graph<Node> graph) {
+    final Graph<Chunk<Node>> chunkGraph = toChunkGraph(graph);
+    final List<Chunk<Node>> chunks = new ArrayList<Chunk<Node>>(chunkGraph.getNodes().size());
+    for (final Chunk<Node> chunk : chunkGraph.getNodes()) {
+      chunks.add(chunk);
+    }
+    DFSTBuilder<Chunk<Node>> builder = new DFSTBuilder<Chunk<Node>>(chunkGraph);
+    if (!builder.isAcyclic()) {
+      LOG.error("Acyclic graph expected");
+      return null;
+    }
+
+    Collections.sort(chunks, builder.comparator());
+    return chunks;
+  }
+  
+  public static <Node> Graph<Chunk<Node>> toChunkGraph(final Graph<Node> graph) {
+    return GraphAlgorithms.getInstance().computeSCCGraph(graph);
+  }
+
+  public static void sortModules(final Project project, final List<Module> modules) {
+    final Application application = ApplicationManager.getApplication();
+    Runnable sort = new Runnable() {
+      public void run() {
+        Comparator<Module> comparator = ModuleManager.getInstance(project).moduleDependencyComparator();
+        Collections.sort(modules, comparator);
+      }
+    };
+    if (application.isDispatchThread()) {
+      sort.run();
+    }
+    else {
+      application.runReadAction(sort);
+    }
+  }
+
+
+  public static <T extends ModuleRootModel> GraphGenerator<T> createGraphGenerator(final Map<Module, T> models) {
+    return GraphGenerator.create(CachingSemiGraph.create(new GraphGenerator.SemiGraph<T>() {
+      public Collection<T> getNodes() {
+        return models.values();
+      }
+
+      public Iterator<T> getIn(final ModuleRootModel model) {
+        final Module[] modules = model.getModuleDependencies();
+        final List<T> dependencies = new ArrayList<T>();
+        for (Module module : modules) {
+          T depModel = models.get(module);
+          if (depModel != null) {
+            dependencies.add(depModel);
+          }
+        }
+        return dependencies.iterator();
+      }
+    }));
+  }
+
+  /**
+   * @return pair of modules which become circular after adding dependency, or null if all remains OK
+   */
+  @Nullable
+  public static Pair<Module, Module> addingDependencyFormsCircularity(final Module currentModule, Module toDependOn) {
+    assert currentModule != toDependOn;
+    // whatsa lotsa of @&#^%$ codes-a!
+
+    final Map<Module, ModifiableRootModel> models = new LinkedHashMap<Module, ModifiableRootModel>();
+    Project project = currentModule.getProject();
+    for (Module module : ModuleManager.getInstance(project).getModules()) {
+      ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+      models.put(module, model);
+    }
+    ModifiableRootModel currentModel = models.get(currentModule);
+    ModifiableRootModel toDependOnModel = models.get(toDependOn);
+    Collection<Chunk<ModifiableRootModel>> nodesBefore = buildChunks(models);
+    for (Chunk<ModifiableRootModel> chunk : nodesBefore) {
+      if (chunk.containsNode(toDependOnModel) && chunk.containsNode(currentModel)) return null; // they circular already
+    }
+
+    try {
+      currentModel.addModuleOrderEntry(toDependOn);
+      Collection<Chunk<ModifiableRootModel>> nodesAfter = buildChunks(models);
+      for (Chunk<ModifiableRootModel> chunk : nodesAfter) {
+        if (chunk.containsNode(toDependOnModel) && chunk.containsNode(currentModel)) {
+          Iterator<ModifiableRootModel> nodes = chunk.getNodes().iterator();
+          return Pair.create(nodes.next().getModule(), nodes.next().getModule());
+        }
+      }
+    }
+    finally {
+      for (ModifiableRootModel model : models.values()) {
+        model.dispose();
+      }
+    }
+    return null;
+  }
+
+  public static <T extends ModuleRootModel> Collection<Chunk<T>> buildChunks(final Map<Module, T> models) {
+    return toChunkGraph(createGraphGenerator(models)).getNodes();
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java
new file mode 100644
index 0000000..51ee7d1
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildProperties.java
@@ -0,0 +1,271 @@
+/*
+ * 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2006
+ */
+package com.intellij.compiler.ant;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.HashSet;
+import java.util.Set;
+
+public abstract class BuildProperties extends CompositeGenerator {
+  public static final @NonNls String TARGET_ALL = "all";
+  public static final @NonNls String TARGET_BUILD_MODULES = "build.modules";
+  public static final @NonNls String TARGET_CLEAN = "clean";
+  public static final @NonNls String TARGET_INIT = "init";
+  public static final @NonNls String TARGET_REGISTER_CUSTOM_COMPILERS = "register.custom.compilers";
+  public static final @NonNls String DEFAULT_TARGET = TARGET_ALL;
+  public static final @NonNls String PROPERTY_COMPILER_NAME = "compiler.name";
+  public static final @NonNls String PROPERTY_COMPILER_ADDITIONAL_ARGS = "compiler.args";
+  public static final @NonNls String PROPERTY_COMPILER_MAX_MEMORY = "compiler.max.memory";
+  public static final @NonNls String PROPERTY_COMPILER_EXCLUDES = "compiler.excluded";
+  public static final @NonNls String PROPERTY_COMPILER_RESOURCE_PATTERNS = "compiler.resources";
+  public static final @NonNls String PROPERTY_IGNORED_FILES = "ignored.files";
+  public static final @NonNls String PROPERTY_COMPILER_GENERATE_DEBUG_INFO = "compiler.debug";
+  public static final @NonNls String PROPERTY_COMPILER_GENERATE_NO_WARNINGS = "compiler.generate.no.warnings";
+  public static final @NonNls String PROPERTY_PROJECT_JDK_HOME = "project.jdk.home";
+  public static final @NonNls String PROPERTY_PROJECT_JDK_BIN = "project.jdk.bin";
+  public static final @NonNls String PROPERTY_PROJECT_JDK_CLASSPATH = "project.jdk.classpath";
+  public static final @NonNls String PROPERTY_SKIP_TESTS = "skip.tests";
+  public static final @NonNls String PROPERTY_LIBRARIES_PATTERNS = "library.patterns";
+  public static final @NonNls String PROPERTY_IDEA_HOME = "idea.home";
+  public static final @NonNls String PROPERTY_JAVAC2_HOME = "javac2.home";
+  public static final @NonNls String PROPERTY_JAVAC2_CLASSPATH_ID = "javac2.classpath";
+
+  protected abstract void createJdkGenerators(Project project);
+
+  public static Sdk[] getUsedJdks(Project project) {
+    final Set<Sdk> jdks = new HashSet<Sdk>();
+    Module[] modules = ModuleManager.getInstance(project).getModules();
+    for (Module module : modules) {
+      Sdk jdk = ModuleRootManager.getInstance(module).getSdk();
+      if (jdk != null) {
+        jdks.add(jdk);
+      }
+    }
+    return jdks.toArray(new Sdk[jdks.size()]);
+  }
+
+  @NonNls
+  public static String getJdkPathId(@NonNls final String jdkName) {
+    return "jdk.classpath." + convertName(jdkName);
+  }
+
+  @NonNls
+  public static String getModuleChunkJdkClasspathProperty(@NonNls final String moduleChunkName) {
+    return "module.jdk.classpath." + convertName(moduleChunkName);
+  }
+
+  @NonNls
+  public static String getModuleChunkJdkHomeProperty(@NonNls final String moduleChunkName) {
+    return "module.jdk.home." + convertName(moduleChunkName);
+  }
+
+  @NonNls
+  public static String getModuleChunkJdkBinProperty(@NonNls final String moduleChunkName) {
+    return "module.jdk.bin." + convertName(moduleChunkName);
+  }
+
+  @NonNls
+  public static String getModuleChunkCompilerArgsProperty(@NonNls final String moduleName) {
+    return "compiler.args." + convertName(moduleName);
+  }
+
+  @NonNls
+  public static String getLibraryPathId(@NonNls final String libraryName) {
+    return "library." + convertName(libraryName) + ".classpath";
+  }
+
+  @NonNls
+  public static String getJdkHomeProperty(@NonNls final String jdkName) {
+    return "jdk.home." + convertName(jdkName);
+  }
+
+  @NonNls
+  public static String getJdkBinProperty(@NonNls final String jdkName) {
+    return "jdk.bin." + convertName(jdkName);
+  }
+
+  @NonNls
+  public static String getCompileTargetName(@NonNls String moduleName) {
+    return "compile.module." + convertName(moduleName);
+  }
+
+  @NonNls
+  public static String getOutputPathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".output.dir";
+  }
+
+  @NonNls
+  public static String getOutputPathForTestsProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".testoutput.dir";
+  }
+
+  @NonNls
+  public static String getClasspathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".module.production.classpath";
+  }
+
+  @NonNls
+  public static String getTestClasspathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".module.classpath";
+  }
+
+  @NonNls
+  public static String getRuntimeClasspathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".runtime.production.module.classpath";
+  }
+
+  @NonNls
+  public static String getTestRuntimeClasspathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".runtime.module.classpath";
+  }
+
+  @NonNls
+  public static String getBootClasspathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".module.bootclasspath";
+  }
+
+  @NonNls
+  public static String getSourcepathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".module.sourcepath";
+  }
+
+  @NonNls
+  public static String getTestSourcepathProperty(@NonNls String moduleName) {
+    return convertName(moduleName) + ".module.test.sourcepath";
+  }
+
+  @NonNls
+  public static String getExcludedFromModuleProperty(@NonNls String moduleName) {
+    return "excluded.from.module." + convertName(moduleName);
+  }
+
+  @NonNls
+  public static String getExcludedFromCompilationProperty(@NonNls String moduleName) {
+    return "excluded.from.compilation." + convertName(moduleName);
+  }
+
+  @NonNls
+  public static String getProjectBuildFileName(Project project) {
+    return convertName(project.getName());
+  }
+
+  @NonNls
+  public static String getModuleChunkBuildFileName(final ModuleChunk chunk) {
+    return "module_" + convertName(chunk.getName());
+  }
+
+  @NonNls
+  public static String getModuleCleanTargetName(@NonNls String moduleName) {
+    return "clean.module." + convertName(moduleName);
+  }
+
+  @NonNls
+  public static String getModuleChunkBasedirProperty(ModuleChunk chunk) {
+    return "module." + convertName(chunk.getName()) + ".basedir";
+  }
+
+  /**
+   * left for compatibility
+   *
+   * @param module the module to get property for
+   * @return name of the property
+   */
+  @NonNls
+  public static String getModuleBasedirProperty(Module module) {
+    return "module." + convertName(module.getName()) + ".basedir";
+  }
+
+  @NonNls
+  public static String getProjectBaseDirProperty() {
+    return "basedir";
+  }
+
+  public static File getModuleChunkBaseDir(ModuleChunk chunk) {
+    return chunk.getBaseDir();
+  }
+
+  public static File getProjectBaseDir(final Project project) {
+    final VirtualFile baseDir = project.getBaseDir();
+    assert baseDir != null;
+    return VfsUtil.virtualToIoFile(baseDir);
+  }
+
+  /**
+   * Convert name. All double quotes are removed and spaces are replaced with underscore.
+   *
+   * @param name a name to convert
+   * @return a converted name
+   */
+  @NonNls
+  public static String convertName(@NonNls final String name) {
+    //noinspection HardCodedStringLiteral
+    return name.replaceAll("\"", "").replaceAll("\\s+", "_").toLowerCase();
+  }
+
+  @NonNls
+  public static String getPathMacroProperty(@NonNls String pathMacro) {
+    return "path.variable." + convertName(pathMacro);
+  }
+
+  @NonNls
+  public static String propertyRef(@NonNls String propertyName) {
+    return "${" + propertyName + "}";
+  }
+
+  /**
+   * Construct path relative to the specified property
+   *
+   * @param propertyName the property name
+   * @param relativePath the relative path
+   * @return the path relative to the property
+   */
+  @NonNls
+  public static String propertyRelativePath(@NonNls String propertyName, @NonNls String relativePath) {
+    return "${" + propertyName + "}/" + relativePath;
+  }
+
+
+  public static File toCanonicalFile(final File file) {
+    File canonicalFile;
+    try {
+      canonicalFile = file.getCanonicalFile();
+    }
+    catch (IOException e) {
+      canonicalFile = file;
+    }
+    return canonicalFile;
+  }
+
+  @NonNls
+  public static String getTempDirForModuleProperty(@NonNls String moduleName) {
+    return "tmp.dir." + convertName(moduleName);
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java
new file mode 100644
index 0000000..65a7587
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/BuildTargetsFactory.java
@@ -0,0 +1,39 @@
+/*
+ * 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2006
+ */
+package com.intellij.compiler.ant;
+
+import com.intellij.compiler.ant.taskdefs.Target;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class BuildTargetsFactory {
+  public static BuildTargetsFactory getInstance() {
+    return ServiceManager.getService(BuildTargetsFactory.class);
+  }
+
+  public abstract Generator createComment(String comment);
+
+  //for test
+  public abstract GenerationOptions getDefaultOptions(Project project);
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java
new file mode 100644
index 0000000..adb1cb0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkBuildExtension.java
@@ -0,0 +1,85 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.ExtensionPoints;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.elements.ArtifactAntGenerationContext;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.List;
+
+public abstract class ChunkBuildExtension {
+  public static final ExtensionPointName<ChunkBuildExtension> EP_NAME = ExtensionPointName.create(ExtensionPoints.ANT_BUILD_GEN);
+
+  @NotNull
+  @NonNls
+  public abstract String[] getTargets(final ModuleChunk chunk);
+
+  public abstract void process(Project project, ModuleChunk chunk, GenerationOptions genOptions, CompositeGenerator generator);
+
+  public void generateProjectTargets(Project project, GenerationOptions genOptions, CompositeGenerator generator) {
+  }
+
+  public void generateProperties(final PropertyFileGenerator generator, final Project project, final GenerationOptions options) {
+  }
+
+  public void generateTasksForArtifact(Artifact artifact, boolean preprocessing, ArtifactAntGenerationContext context,
+                                       CompositeGenerator generator) {
+  }
+
+  public List<String> getCleanTargetNames(Project project, GenerationOptions genOptions) {
+    return Collections.emptyList();
+  }
+
+  public static String[] getAllTargets(ModuleChunk chunk) {
+    List<String> allTargets = new ArrayList<String>();
+    final ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+    for (ChunkBuildExtension extension : extensions) {
+      ContainerUtil.addAll(allTargets, extension.getTargets(chunk));
+    }
+    if (allTargets.isEmpty()) {
+      allTargets.add(BuildProperties.getCompileTargetName(chunk.getName()));
+    }
+    return ArrayUtil.toStringArray(allTargets);
+  }
+
+  public static void process(CompositeGenerator generator, ModuleChunk chunk, GenerationOptions genOptions) {
+    final Project project = chunk.getProject();
+    final ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+    for (ChunkBuildExtension extension : extensions) {
+      extension.process(project, chunk, genOptions, generator);
+    }
+  }
+
+  public static void generateAllProperties(final PropertyFileGenerator propertyFileGenerator,
+                                           final Project project,
+                                           final GenerationOptions genOptions) {
+    ChunkBuildExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+    for (ChunkBuildExtension extension : extensions) {
+      extension.generateProperties(propertyFileGenerator, project, genOptions);
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java
new file mode 100644
index 0000000..2356389
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ChunkCustomCompilerExtension.java
@@ -0,0 +1,114 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.ExtensionPoints;
+import com.intellij.compiler.ant.taskdefs.PatternSetRef;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.LinkedList;
+
+/**
+ * The extenstion point for the custom compilers
+ */
+public abstract class ChunkCustomCompilerExtension {
+  /**
+   * Extension point name
+   */
+  public static final ExtensionPointName<ChunkCustomCompilerExtension> EP_NAME =
+    ExtensionPointName.create(ExtensionPoints.ANT_CUSTOM_COMPILER);
+  /**
+   * Comparator that compares extensions using names. It is used for make order of elements predictable.
+   */
+  protected static final Comparator<ChunkCustomCompilerExtension> COMPARATOR = new Comparator<ChunkCustomCompilerExtension>() {
+    public int compare(ChunkCustomCompilerExtension o1, ChunkCustomCompilerExtension o2) {
+      return o1.getClass().getName().compareTo(o2.getClass().getName());
+    }
+  };
+
+  /**
+   * Generate custom compile task inside compile target. Note that if more
+   * than one extension requested custom compilation, all of them are included into ant
+   * build and fail task is added to the compile target.
+   *
+   * @param project          the context project
+   * @param chunk            the chunk to compile
+   * @param genOptions       an options to compile
+   * @param generator        a generator where custom compilation tasks will be added.
+   * @param compileTests     if true, tests are compiled
+   * @param compilerArgs     the javac compilier arguements
+   * @param bootclasspathTag the boot classpath element for the javac compiler
+   * @param classpathTag     the classpath tag for the javac compiler
+   * @param compilerExcludes the compiler excluded tag
+   * @param srcTag           the soruce tag
+   * @param outputPathRef    the output path references
+   */
+  @SuppressWarnings({"UnusedDeclaration"})
+  public abstract void generateCustomCompile(Project project,
+                                             ModuleChunk chunk,
+                                             GenerationOptions genOptions,
+                                             boolean compileTests,
+                                             CompositeGenerator generator,
+                                             Tag compilerArgs,
+                                             Tag bootclasspathTag,
+                                             Tag classpathTag,
+                                             PatternSetRef compilerExcludes,
+                                             Tag srcTag,
+                                             String outputPathRef);
+
+  /**
+   * Generate task registration for custom compiler if needed.
+   *
+   * @param project    the context project
+   * @param genOptions an options to compile
+   * @param generator  a generator where custom compilation tasks will be added.
+   */
+  @SuppressWarnings({"UnusedDeclaration"})
+  public abstract void generateCustomCompilerTaskRegistration(Project project, GenerationOptions genOptions, CompositeGenerator generator);
+
+  /**
+   * Allows to check if the custom compilation task is required to compile module sources.
+   * Such task should be able to process standard java sources as well.
+   *
+   * @param chunk a chunk to check
+   * @return true if the facet requires custom comiplation.
+   */
+  @SuppressWarnings({"UnusedDeclaration", "MethodMayBeStatic"})
+  public abstract boolean hasCustomCompile(final ModuleChunk chunk);
+
+  /**
+   * Get custom compilation providers for module chunk
+   *
+   * @param chunk a chunk to examine
+   * @return a list of custom compilators
+   */
+  public static ChunkCustomCompilerExtension[] getCustomCompile(ModuleChunk chunk) {
+    final ChunkCustomCompilerExtension[] extensions = Extensions.getRootArea().getExtensionPoint(EP_NAME).getExtensions();
+    LinkedList<ChunkCustomCompilerExtension> compilers = new LinkedList<ChunkCustomCompilerExtension>();
+    for (ChunkCustomCompilerExtension extension : extensions) {
+      if (extension.hasCustomCompile(chunk)) {
+        compilers.add(extension);
+      }
+    }
+    final ChunkCustomCompilerExtension[] rc = compilers.toArray(new ChunkCustomCompilerExtension[compilers.size()]);
+    Arrays.sort(rc, ChunkCustomCompilerExtension.COMPARATOR);
+    return rc;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java
new file mode 100644
index 0000000..884e125
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/CompositeGenerator.java
@@ -0,0 +1,122 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.util.Pair;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * A composite generator
+ *
+ * @author Eugene Zhuravlev
+ *         Date: Mar 25, 2004
+ */
+public class CompositeGenerator extends Generator {
+  /**
+   * child generators
+   */
+  private final List<Pair<Generator, Integer>> myGenerators = new ArrayList<Pair<Generator, Integer>>();
+  /**
+   * New line property
+   */
+  private boolean hasLeadingNewline = true;
+
+  /**
+   * A constructor
+   */
+  public CompositeGenerator() {
+  }
+
+  /**
+   * A constructor that adds two elements
+   *
+   * @param generator1      the first generator
+   * @param generator2      the second generator
+   * @param emptyLinesCount the amount of new lines between two generators
+   */
+  public CompositeGenerator(Generator generator1, Generator generator2, int emptyLinesCount) {
+    add(generator1);
+    add(generator2, emptyLinesCount);
+  }
+
+  /**
+   * By default, the composite generator generates an empty newline before generating nested eleemnts.
+   * Setting the property to the false, allows suppressing it.
+   *
+   * @param value the new value of the property
+   */
+  public void setHasLeadingNewline(boolean value) {
+    hasLeadingNewline = value;
+  }
+
+  /**
+   * Add child generator with no emtpy lines before it
+   *
+   * @param generator the generator to add
+   */
+  public final void add(Generator generator) {
+    add(generator, 0);
+  }
+
+  /**
+   * Add child generator with the specified amount of empty lines before it
+   *
+   * @param generator       a generator
+   * @param emptyLinesCount amount of empty lines
+   */
+  public final void add(Generator generator, int emptyLinesCount) {
+    myGenerators.add(new Pair<Generator, Integer>(generator, new Integer(emptyLinesCount)));
+  }
+
+  /**
+   * Generate content.
+   *
+   * @param out output stream
+   * @throws IOException in case of IO propblem
+   * @see #setHasLeadingNewline(boolean)
+   */
+  public void generate(PrintWriter out) throws IOException {
+    boolean first = true;
+    for (final Pair<Generator, Integer> pair : myGenerators) {
+      if (first) {
+        if (hasLeadingNewline) {
+          crlf(out);
+        }
+        first = false;
+      }
+      else {
+        crlf(out);
+      }
+      final int emptyLinesCount = pair.getSecond().intValue();
+      for (int idx = 0; idx < emptyLinesCount; idx++) {
+        crlf(out);
+      }
+      pair.getFirst().generate(out);
+    }
+  }
+
+  /**
+   * @return amount of the child generators
+   */
+  public final int getGeneratorCount() {
+    return myGenerators.size();
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java
new file mode 100644
index 0000000..fc286ee
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationOptions.java
@@ -0,0 +1,152 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.module.Module;
+
+/**
+ * Ant file generation options. This object is availalbe during construction of ant object tree.
+ *
+ * @author anna
+ */
+public abstract class GenerationOptions {
+  /**
+     * This option specifies whether mulitfile or single file ant script is created.
+     */
+    public final boolean generateSingleFile;
+    /**
+     * This option specifies whehter standard javac or javac2 task is used
+     */
+    public final boolean enableFormCompiler;
+    /**
+     * This option speciries whether files are backed up before generation
+     */
+    public final boolean backupPreviouslyGeneratedFiles;
+    /**
+     * This option specifies whether target JDK is forced during compilation or default ant JDK is used.
+     */
+    public final boolean forceTargetJdk;
+    /**
+     * if true, the runtime classpath is inlined
+     */
+    public final boolean inlineRuntimeClasspath;
+    /**
+     * if true, the runtime classpath is inlined
+     */
+    public final boolean expandJarDirectories;
+
+
+    /**
+     * A constructor
+     *
+     * @param forceTargetJdk                 a value of corresponding option
+     * @param generateSingleFile             a value of corresponding option
+     * @param enableFormCompiler             a value of corresponding option
+     * @param backupPreviouslyGeneratedFiles a value of corresponding option
+     * @param inlineRuntimeClasspath         if true, a runtiem classpaths are inlined
+     * @param expandJarDirectories           if true, jar directories are expaned
+     */
+    public GenerationOptions(boolean forceTargetJdk,
+                             boolean generateSingleFile,
+                             boolean enableFormCompiler,
+                             boolean backupPreviouslyGeneratedFiles,
+                             boolean inlineRuntimeClasspath,
+                             boolean expandJarDirectories) {
+        this.forceTargetJdk = forceTargetJdk;
+        this.generateSingleFile = generateSingleFile;
+        this.enableFormCompiler = enableFormCompiler;
+        this.backupPreviouslyGeneratedFiles = backupPreviouslyGeneratedFiles;
+        this.inlineRuntimeClasspath = inlineRuntimeClasspath;
+        this.expandJarDirectories = expandJarDirectories;
+    }
+
+    /**
+     * A constructor
+     *
+     * @param forceTargetJdk                 a value of corresponding option
+     * @param generateSingleFile             a value of corresponding option
+     * @param enableFormCompiler             a value of corresponding option
+     * @param backupPreviouslyGeneratedFiles a value of corresponding option
+     * @param inlineRuntimeClasspath         if true a runtiem classpaths are inlined
+     */
+    public GenerationOptions(boolean forceTargetJdk,
+                             boolean generateSingleFile,
+                             boolean enableFormCompiler,
+                             boolean backupPreviouslyGeneratedFiles,
+                             boolean inlineRuntimeClasspath) {
+        this(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, inlineRuntimeClasspath, false);
+    }
+
+    /**
+     * A constructor
+     *
+     * @param forceTargetJdk                 a value of corresponding option
+     * @param generateSingleFile             a value of corresponding option
+     * @param enableFormCompiler             a value of corresponding option
+     * @param backupPreviouslyGeneratedFiles a value of corresponding option
+     */
+    @Deprecated
+    public GenerationOptions(boolean forceTargetJdk,
+                             boolean generateSingleFile,
+                             boolean enableFormCompiler,
+                             boolean backupPreviouslyGeneratedFiles) {
+        this(forceTargetJdk, generateSingleFile, enableFormCompiler, backupPreviouslyGeneratedFiles, false);
+    }
+
+    /**
+     * Substitute path prefix with macro reference if it matches some macro.
+     *
+     * @param path a path to update
+     * @return an updated path or argument
+     */
+    public abstract String subsitutePathWithMacros(String path);
+
+    /**
+     * Get property reference for the specified url of module output directory
+     *
+     * @param url an URL to map
+     * @return the property reference in the form ${..}
+     */
+    public abstract String getPropertyRefForUrl(String url);
+
+    /**
+     * @return an array of module chunks. an array must not be modified by the clients.
+     */
+    public abstract ModuleChunk[] getModuleChunks();
+
+    /**
+     * Get the chunk that contains the specified module.
+     *
+     * @param module the module to find
+     * @return the chunk that contains specifid module
+     */
+    public abstract ModuleChunk getChunkByModule(Module module);
+
+    /**
+     * @return a set of custom compilers, each compiler is used at least once in some chunk.
+     */
+    public abstract ChunkCustomCompilerExtension[] getCustomCompilers();
+
+    /**
+     * @return true if the idea home property must be generated
+     */
+    public abstract boolean isIdeaHomeGenerated();
+
+
+  public abstract String getBuildFileName();
+  
+  public abstract String getPropertiesFileName();
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java
new file mode 100644
index 0000000..527d913
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/GenerationUtils.java
@@ -0,0 +1,130 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class GenerationUtils {
+    private GenerationUtils() {
+    }
+
+    /**
+     * Get relative file
+     *
+     * @param file       a valid file (must be either belong to {@link com.intellij.openapi.vfs.LocalFileSystem}  or to point to the root entry on
+     *                   {@link com.intellij.openapi.vfs.JarFileSystem}.
+     * @param chunk      a module chunk.
+     * @param genOptions generation options
+     * @return a relative path
+     */
+    @Nullable
+    public static String toRelativePath(final VirtualFile file, final ModuleChunk chunk, final GenerationOptions genOptions) {
+        final Module module = chunk.getModules()[0];
+        final File moduleBaseDir = chunk.getBaseDir();
+        return toRelativePath(file, moduleBaseDir, BuildProperties.getModuleBasedirProperty(module), genOptions);
+    }
+
+    public static String toRelativePath(final String file, final File baseDir, final Module module, final GenerationOptions genOptions) {
+        return toRelativePath(file, baseDir, BuildProperties.getModuleBasedirProperty(module), genOptions);
+    }
+
+    public static String toRelativePath(final String path, final ModuleChunk chunk, final GenerationOptions genOptions) {
+        return toRelativePath(path, chunk.getBaseDir(), BuildProperties.getModuleChunkBasedirProperty(chunk), genOptions);
+    }
+
+    /**
+     * Get relative file
+     *
+     * @param file                          a valid file (must be either belong to {@link com.intellij.openapi.vfs.LocalFileSystem}  or to point to the root entry on
+     *                                      {@link com.intellij.openapi.vfs.JarFileSystem}.
+     * @param baseDir                       base director for relative path calculation
+     * @param baseDirPropertyName           property name for the base directory
+     * @param genOptions                    generation options
+     * @return a relative path
+     */
+    @Nullable
+    public static String toRelativePath(final VirtualFile file,
+                                        final File baseDir,
+                                        final String baseDirPropertyName,
+                                        final GenerationOptions genOptions) {
+        final String localPath = PathUtil.getLocalPath(file);
+        if (localPath == null) {
+            return null;
+        }
+        return toRelativePath(localPath, baseDir, baseDirPropertyName, genOptions);
+    }
+
+    public static String toRelativePath(String path,
+                                        File baseDir,
+                                        @NonNls final String baseDirPropertyName,
+                                        GenerationOptions genOptions) {
+        path = normalizePath(path);
+        if(path.length() == 0) {
+            return path;
+        }
+        final String substitutedPath = genOptions.subsitutePathWithMacros(path);
+        if (!substitutedPath.equals(path)) {
+            // path variable substitution has highest priority
+            return substitutedPath;
+        }
+        if (baseDir != null) {
+            File base;
+            try {
+                // use canonical paths in order to resolve symlinks
+                base = baseDir.getCanonicalFile();
+            }
+            catch (IOException e) {
+                base = baseDir;
+            }
+            final String relativepath = FileUtil.getRelativePath(base, new File(path));
+            if (relativepath != null) {
+              final String _relativePath = relativepath.replace(File.separatorChar, '/');
+              final String root = BuildProperties.propertyRef(baseDirPropertyName);
+              return ".".equals(_relativePath) ? root : root + "/" + _relativePath;
+            }
+        }
+        return substitutedPath;
+    }
+
+    /**
+     * Normalize path by ensuring that only "/" is used as file name separator.
+     *
+     * @param path the path to normalize
+     * @return the normalized path
+     */
+    public static String normalizePath(String path) {
+        return path.replace(File.separatorChar, '/');
+    }
+
+    public static String trimJarSeparator(final String path) {
+        return path.endsWith(JarFileSystem.JAR_SEPARATOR) ? path.substring(0, path.length() - JarFileSystem.JAR_SEPARATOR.length()) : path;
+    }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.java
new file mode 100644
index 0000000..40c143b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/Generator.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.compiler.ant;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+public abstract class Generator {
+  private static int ourIndent = 0;
+  private static final int INDENT_SHIFT = 2;
+
+  public abstract void generate(PrintWriter out) throws IOException;
+
+  protected static void crlf(PrintWriter out) throws IOException {
+    out.println();
+    indent(out);
+  }
+
+  protected static void shiftIndent() {
+    ourIndent += INDENT_SHIFT;
+  }
+
+  protected static void unshiftIndent() {
+    ourIndent -= INDENT_SHIFT;
+  }
+
+  protected static void indent(PrintWriter out) throws IOException {
+    for (int idx = 0; idx < ourIndent; idx++) {
+      out.print(" ");
+    }
+  }
+
+  /**
+   * Write XML header
+   * @param out a writer
+   * @throws IOException in case of IO problem
+   */
+  protected static void writeXmlHeader(final PrintWriter out) throws IOException {
+    //noinspection HardCodedStringLiteral
+    out.print("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
+    crlf(out);
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java b/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java
new file mode 100644
index 0000000..0665dd2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/ModuleChunk.java
@@ -0,0 +1,134 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * Module chunk consists of interdependent modules.
+ *
+ * @author Eugene Zhuravlev
+ *         Date: Nov 19, 2004
+ */
+public class ModuleChunk {
+  /**
+   * Modules in the chunk
+   */
+  private final Module[] myModules;
+  /**
+   * A array of custom compilation providers.
+   */
+  private final ChunkCustomCompilerExtension[] myCustomCompilers;
+  /**
+   * The main module in the chunck (guessed by heuristic or selected by user)
+   */
+  private Module myMainModule;
+  /**
+   * Chucnk dependendencies
+   */
+  private ModuleChunk[] myDependentChunks;
+  private File myBaseDir = null;
+
+  public ModuleChunk(Module[] modules) {
+    myModules = modules;
+    Arrays.sort(myModules, new Comparator<Module>() {
+      public int compare(final Module o1, final Module o2) {
+        return o1.getName().compareToIgnoreCase(o2.getName());
+      }
+    });
+    myMainModule = myModules[0];
+    myCustomCompilers = ChunkCustomCompilerExtension.getCustomCompile(this);
+  }
+
+  public String getName() {
+    return myMainModule.getName();
+  }
+
+  /**
+   * @return an array of custom compilers for the module chunk
+   */
+  public ChunkCustomCompilerExtension[] getCustomCompilers() {
+    return myCustomCompilers;
+  }
+
+  public Module[] getModules() {
+    return myModules;
+  }
+
+  @Nullable
+  public String getOutputDirUrl() {
+    return CompilerModuleExtension.getInstance(myMainModule).getCompilerOutputUrl();
+  }
+
+  @Nullable
+  public String getTestsOutputDirUrl() {
+    return CompilerModuleExtension.getInstance(myMainModule).getCompilerOutputUrlForTests();
+  }
+
+  public boolean isJdkInherited() {
+    return ModuleRootManager.getInstance(myMainModule).isSdkInherited();
+  }
+
+  @Nullable
+  public Sdk getJdk() {
+    return ModuleRootManager.getInstance(myMainModule).getSdk();
+  }
+
+  public ModuleChunk[] getDependentChunks() {
+    return myDependentChunks;
+  }
+
+  public void setDependentChunks(ModuleChunk[] dependentChunks) {
+    myDependentChunks = dependentChunks;
+  }
+
+  public File getBaseDir() {
+    if (myBaseDir != null) {
+      return myBaseDir;
+    }
+    return new File(myMainModule.getModuleFilePath()).getParentFile();
+  }
+
+  public void setBaseDir(File baseDir) {
+    myBaseDir = baseDir;
+  }
+
+  public void setMainModule(Module module) {
+    myMainModule = module;
+  }
+
+  public Project getProject() {
+    return myMainModule.getProject();
+  }
+
+  public boolean contains(final Module module) {
+    for (Module chunkModule : myModules) {
+      if (chunkModule.equals(module)) {
+        return true;
+      }
+    }
+    return false;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.java b/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.java
new file mode 100644
index 0000000..86c65d7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/PropertyFileGenerator.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.compiler.ant;
+
+/**
+ * @author nik
+ */
+public abstract class PropertyFileGenerator extends Generator {
+  /**
+   * Add property. Note that property name and value
+   * are automatically escaped when the property file
+   * is generated.
+   *
+   * @param name a property name
+   * @param value a property value
+   */
+  public abstract void addProperty(String name, String value);
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java b/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java
new file mode 100644
index 0000000..aa08438
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/Tag.java
@@ -0,0 +1,87 @@
+/*
+ * 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.compiler.ant;
+
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.PrintWriter;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Tag extends CompositeGenerator {
+  public static final Tag[] EMPTY_ARRAY = new Tag[0];
+  private final String myTagName;
+  private final Pair[] myTagOptions;
+
+  public Tag(@NonNls String tagName, Pair... tagOptions) {
+    myTagName = tagName;
+    myTagOptions = tagOptions;
+  }
+
+  public void generate(PrintWriter out) throws IOException {
+    out.print("<");
+    out.print(myTagName);
+    if (myTagOptions != null && myTagOptions.length > 0) {
+      out.print(" ");
+      int generated = 0;
+      for (final Pair option : myTagOptions) {
+        if (option == null) {
+          continue;
+        }
+        if (generated > 0) {
+          out.print(" ");
+        }
+        out.print((String)option.getFirst());
+        out.print("=\"");
+        out.print(StringUtil.escapeXml((String)option.getSecond()));
+        out.print("\"");
+        generated += 1;
+      }
+    }
+    if (getGeneratorCount() > 0) {
+      out.print(">");
+      shiftIndent();
+      try {
+        super.generate(out);
+      }
+      finally {
+        unshiftIndent();
+      }
+      crlf(out);
+      out.print("</");
+      out.print(myTagName);
+      out.print(">");
+    }
+    else {
+      out.print("/>");
+    }
+  }
+
+  @Nullable
+  protected static Pair<String, String> pair(@NonNls String v1, @Nullable @NonNls String v2) {
+    if (v2 == null) {
+      return null;
+    }
+    return new Pair<String, String>(v1, v2);
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java
new file mode 100644
index 0000000..4768d5f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntCall.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public class AntCall extends Tag{
+
+  public AntCall(final String target) {
+    super("antcall", new Pair[] {new Pair<String, String>("target", target)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java
new file mode 100644
index 0000000..3aa3eee
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/AntProject.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 25, 2004
+ */
+public class AntProject extends Tag {
+  public AntProject(@NonNls String name, @NonNls String defaultTarget) {
+    //noinspection HardCodedStringLiteral
+    super("project", new Pair[]{new Pair<String, String>("name", name), new Pair<String, String>("default", defaultTarget)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java
new file mode 100644
index 0000000..d6098db
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Attribute.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Attribute extends Tag{
+  public Attribute(@NonNls String name, String value) {
+    //noinspection HardCodedStringLiteral
+    super("attribute", new Pair[] {Pair.create("name", name),Pair.create("value", value)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java
new file mode 100644
index 0000000..c95348b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Copy.java
@@ -0,0 +1,36 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 23, 2004
+ */
+public class Copy extends Tag {
+  public Copy(@NonNls String toDir) {
+    //noinspection HardCodedStringLiteral
+    super("copy", new Pair[] {new Pair<String, String>("todir", toDir)});
+  }
+  public Copy(@NonNls String file, @NonNls String toFile) {
+    //noinspection HardCodedStringLiteral
+    super("copy", new Pair[] {new Pair<String, String>("file", file), new Pair<String, String>("tofile", toFile)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java
new file mode 100644
index 0000000..2dfe0d3
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Delete.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Delete extends Tag{
+  public Delete(@NonNls String dir) {
+    //noinspection HardCodedStringLiteral
+    super("delete", new Pair[] {Pair.create("dir", dir)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java
new file mode 100644
index 0000000..b4cba08
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/DirSet.java
@@ -0,0 +1,33 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class DirSet extends Tag{
+
+  public DirSet(@NonNls final String dir) {
+    //noinspection HardCodedStringLiteral
+    super("dirset", new Pair[] {new Pair<String, String>("dir", dir)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java
new file mode 100644
index 0000000..f833f58
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Dirname.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 25, 2004
+ */
+public class Dirname extends Tag{
+  public Dirname(@NonNls String property, @NonNls String file) {
+    //noinspection HardCodedStringLiteral
+    super("dirname", new Pair[] {new Pair<String, String>("property", property), new Pair<String, String>("file", file)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.java
new file mode 100644
index 0000000..42e7a6a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Exclude.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Exclude extends Tag {
+
+  public Exclude(@NonNls final String name) {
+    //noinspection HardCodedStringLiteral
+    super("exclude", new Pair[] {new Pair<String, String>("name", name)});
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java
new file mode 100644
index 0000000..5db6e0d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/FileSet.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class FileSet extends Tag{
+
+  public FileSet(@NonNls final String dir) {
+    super("fileset", pair("dir", dir));
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.java
new file mode 100644
index 0000000..2c6e23c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Import.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 24, 2004
+ */
+public class Import extends Tag{
+  public Import(@NonNls String file, boolean optional) {
+    //noinspection HardCodedStringLiteral
+    super("import", new Pair[] {new Pair<String, String>("file", file), new Pair<String, String>("optional", optional? "true" : "false")});
+  }
+
+  public Import(@NonNls String file) {
+    //noinspection HardCodedStringLiteral
+    super("import", new Pair[] {new Pair<String, String>("file", file)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java
new file mode 100644
index 0000000..73352a2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Include.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Include extends Tag {
+
+  public Include(@NonNls final String name) {
+    super("include", pair("name", name));
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.java
new file mode 100644
index 0000000..423faa9
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Jar.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Jar extends Tag {
+  public Jar(@NonNls final String destFile, @NonNls String duplicate) {
+    this(destFile, duplicate, false);
+  }
+
+  public Jar(@NonNls final String destFile, @NonNls String duplicate, final boolean useManifestFromFileSets) {
+    super("jar", pair("destfile", destFile), pair("duplicate", duplicate), useManifestFromFileSets ? pair("filesetmanifest", "mergewithoutmain") : null);
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java
new file mode 100644
index 0000000..c64884e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Javac.java
@@ -0,0 +1,70 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.BuildProperties;
+import com.intellij.compiler.ant.GenerationOptions;
+import com.intellij.compiler.ant.ModuleChunk;
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 16, 2004
+ */
+public class Javac extends Tag {
+
+    public Javac(GenerationOptions genOptions, ModuleChunk moduleChunk, final String outputDir) {
+        super(getTagName(genOptions, moduleChunk), getAttributes(genOptions, outputDir, moduleChunk));
+    }
+
+    private static String getTagName(GenerationOptions genOptions, ModuleChunk moduleChunk) {
+        if (moduleChunk.getCustomCompilers().length > 0) {
+            return "instrumentIdeaExtensions";
+        }
+        return genOptions.enableFormCompiler ? "javac2" : "javac";
+    }
+
+    private static Pair[] getAttributes(GenerationOptions genOptions, String outputDir, ModuleChunk moduleChunk) {
+        final List<Pair> pairs = new ArrayList<Pair>();
+        pairs.add(pair("destdir", outputDir));
+        if (moduleChunk.getCustomCompilers().length == 0) {
+            pairs.add(pair("debug", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_DEBUG_INFO)));
+            pairs.add(pair("nowarn", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_GENERATE_NO_WARNINGS)));
+            pairs.add(pair("memorymaximumsize", BuildProperties.propertyRef(BuildProperties.PROPERTY_COMPILER_MAX_MEMORY)));
+            pairs.add(pair("fork", "true"));
+            if (genOptions.forceTargetJdk) {
+                pairs.add(pair("executable", getExecutable(moduleChunk.getName())));
+            }
+        }
+        return pairs.toArray(new Pair[pairs.size()]);
+    }
+
+    @Nullable
+    @NonNls
+    private static String getExecutable(String moduleName) {
+        if (moduleName == null) {
+            return null;
+        }
+        return BuildProperties.propertyRef(BuildProperties.getModuleChunkJdkBinProperty(moduleName)) + "/javac";
+    }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java
new file mode 100644
index 0000000..da0ac1c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Manifest.java
@@ -0,0 +1,53 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.compiler.make.ManifestBuilder;
+import com.intellij.openapi.util.Pair;
+
+import java.util.jar.Attributes;
+import java.util.*;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Manifest extends Tag{
+  public Manifest() {
+    super("manifest", new Pair[] {});
+  }
+
+  public void applyAttributes(final java.util.jar.Manifest manifest) {
+    ManifestBuilder.setGlobalAttributes(manifest.getMainAttributes());
+    final Attributes mainAttributes = manifest.getMainAttributes();
+
+    List<Object> keys = new ArrayList<Object>(mainAttributes.keySet());
+    Collections.sort(keys, new Comparator<Object>() {
+      public int compare(final Object o1, final Object o2) {
+        Attributes.Name name1 = (Attributes.Name)o1;
+        Attributes.Name name2 = (Attributes.Name)o2;
+        return name1.toString().compareTo(name2.toString());
+      }
+    });
+    for (final Object o : keys) {
+      Attributes.Name name = (Attributes.Name)o;
+      String value = (String)mainAttributes.get(name);
+      add(new Attribute(name.toString(), value));
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java
new file mode 100644
index 0000000..ef15e5c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Mkdir.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 17, 2004
+ */
+public class Mkdir extends Tag {
+  public Mkdir(@NonNls String directory) {
+    //noinspection HardCodedStringLiteral
+    super("mkdir", new Pair[] {new Pair<String, String>("dir", directory)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java
new file mode 100644
index 0000000..19649e0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Param.java
@@ -0,0 +1,36 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Param extends Tag {
+  public Param(@NonNls final String name, final String value) {
+    //noinspection HardCodedStringLiteral
+    super("param", new Pair[] {
+      new Pair<String, String>("name", name),
+      new Pair<String, String>("value", value)
+    });
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.java
new file mode 100644
index 0000000..925c187
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Path.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Path extends Tag {
+
+    public Path(@NonNls final String id) {
+        super("path", pair("id", id));
+    }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.java
new file mode 100644
index 0000000..f48c1a5
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathElement.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class PathElement extends Tag {
+
+    public PathElement(@NonNls String dir) {
+        //noinspection HardCodedStringLiteral
+        super("pathelement", pair("location", dir));
+    }
+
+}
+
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java
new file mode 100644
index 0000000..1f8d658
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PathRef.java
@@ -0,0 +1,33 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class PathRef extends Tag{
+
+  public PathRef(@NonNls final String refid) {
+    super("path", new Pair[] {pair("refid", refid)});
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java
new file mode 100644
index 0000000..6a1d237
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSet.java
@@ -0,0 +1,30 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class PatternSet extends Tag{
+  public PatternSet(@NonNls final String id) {
+    super("patternset", pair("id", id));
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java
new file mode 100644
index 0000000..1055016
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/PatternSetRef.java
@@ -0,0 +1,32 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class PatternSetRef extends Tag{
+  public PatternSetRef(@NonNls final String refid) {
+    //noinspection HardCodedStringLiteral
+    super("patternset", new Pair[] {new Pair<String, String>("refid", refid)});
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java
new file mode 100644
index 0000000..f28d127
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Property.java
@@ -0,0 +1,44 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Property extends Tag {
+
+  public Property(@NonNls final String name, final String value) {
+    //noinspection HardCodedStringLiteral
+    super("property", new Pair[] {
+      new Pair<String, String>("name", name),
+      new Pair<String, String>("value", value)
+    });
+  }
+
+  public Property(@NonNls final String filePath) {
+    //noinspection HardCodedStringLiteral
+    super("property", new Pair[] {
+      new Pair<String, String>("file", filePath),
+    });
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.java
new file mode 100644
index 0000000..26f35bd
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Target.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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class Target extends Tag{
+  public Target(@NonNls String name, @Nullable String depends, @Nullable String description, @Nullable String unlessCondition) {
+    super("target", getOptions(name, depends, description, unlessCondition));
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  private static Pair[] getOptions(@NonNls String name, @Nullable @NonNls String depends, @Nullable String description, @Nullable @NonNls String unlessCondition) {
+    final List<Pair> options = new ArrayList<Pair>();
+    options.add(new Pair<String, String>("name", name));
+    if (depends != null && depends.length() > 0) {
+      options.add(new Pair<String, String>("depends", depends));
+    }
+    if (description != null && description.length() > 0) {
+      options.add(new Pair<String, String>("description", description));
+    }
+    if (unlessCondition != null && unlessCondition.length() > 0) {
+      options.add(new Pair<String, String>("unless", unlessCondition));
+    }
+    return options.toArray(new Pair[options.size()]);
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java
new file mode 100644
index 0000000..8e3a4e7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Unzip.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2010 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+
+/**
+ * @author nik
+ */
+public class Unzip extends Tag {
+  public Unzip(String archivePath, String dest) {
+    super("unzip", pair("src", archivePath), pair("dest", dest));
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java
new file mode 100644
index 0000000..a79ee96
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/Zip.java
@@ -0,0 +1,32 @@
+/*
+ * 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.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2006
+ */
+package com.intellij.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.NonNls;
+
+public class Zip extends Tag {
+  public Zip(@NonNls final String destFile) {
+    //noinspection HardCodedStringLiteral
+    super("zip", new Pair[] {Pair.create("destfile", destFile)});
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java
new file mode 100644
index 0000000..a11b951
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/compiler/ant/taskdefs/ZipFileSet.java
@@ -0,0 +1,68 @@
+/*
+ * 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.compiler.ant.taskdefs;
+
+import com.intellij.compiler.ant.Tag;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Mar 19, 2004
+ */
+public class ZipFileSet extends Tag{
+  public static final ZipFileSet[] EMPTY_ARRAY = new ZipFileSet[0];
+
+  private ZipFileSet(@NonNls String tagName, Pair... tagOptions) {
+    super(tagName, tagOptions);
+  }
+
+  public ZipFileSet(@NonNls String fileOrDir, @NonNls final String relativePath, boolean isDir) {
+    super("zipfileset",
+          pair(isDir ? "dir" : "file", fileOrDir),
+          pair("prefix", prefix(isDir, relativePath)));
+  }
+
+  public static ZipFileSet createUnpackedSet(@NonNls String zipFilePath, @NotNull String relativePath, final boolean isDir) {
+    return new ZipFileSet("zipfileset",
+                          pair("src", zipFilePath),
+                          pair("prefix", prefix(isDir, relativePath)));
+  }
+
+  @Nullable
+  private static String prefix(final boolean isDir, final String relativePath) {
+    String path;
+    if (isDir) {
+      path = relativePath;
+    }
+    else {
+      final String parent = new File(relativePath).getParent();
+      path = parent == null ? "" : FileUtil.toSystemIndependentName(parent);
+    }
+    if (path != null) {
+      path = StringUtil.trimStart(path, "/");
+    }
+    return !StringUtil.isEmpty(path) ? path : null;
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java
new file mode 100644
index 0000000..cfcf337
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassInstrumentingCompiler.java
@@ -0,0 +1,26 @@
+/*
+ * 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.openapi.compiler;
+
+
+/**
+ * A tag interface indicating that the compiler will instrument java classes.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface ClassInstrumentingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java
new file mode 100644
index 0000000..203facd
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ClassPostProcessingCompiler.java
@@ -0,0 +1,26 @@
+/*
+ * 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.openapi.compiler;
+
+
+/**
+ * A tag interface indicating that the compiler will take Java classes and perform some activities on them.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface ClassPostProcessingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java
new file mode 100644
index 0000000..2639194
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusAdapter.java
@@ -0,0 +1,24 @@
+/*
+ * 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.openapi.compiler;
+
+public class CompilationStatusAdapter implements CompilationStatusListener {
+  public void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext) {
+  }
+
+  public void fileGenerated(String outputRoot, String relativePath) {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.java
new file mode 100644
index 0000000..0675098
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilationStatusListener.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.openapi.compiler;
+
+import java.util.EventListener;
+
+/**
+ * A listener for compiler events.
+ *
+ * @see CompilerManager#addCompilationStatusListener(CompilationStatusListener)
+ */
+public interface CompilationStatusListener extends EventListener {
+  /**
+   * Invoked in a Swing dispatch thread after the compilation is finished.
+   *
+   * @param aborted  true if compilatioin has been cancelled
+   * @param errors   error count
+   * @param warnings warning count
+   * @param compileContext context for the finished compilation
+   */
+  void compilationFinished(boolean aborted, int errors, int warnings, final CompileContext compileContext);
+
+  void fileGenerated(String outputRoot, String relativePath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java
new file mode 100644
index 0000000..0f93063
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileContext.java
@@ -0,0 +1,157 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * An interface allowing access and modification of the data associated with the current compile session.
+ */
+public interface CompileContext extends UserDataHolder {
+  /**
+   * Allows to add a message to be shown in Compiler message view.
+   * If correct url, line and column numbers are supplied, the navigation to the specified file is available from the view.
+   *
+   * @param category  the category of a message (information, error, warning).
+   * @param message   the text of the message.
+   * @param url       a url to the file to which the message applies, null if not available.
+   * @param lineNum   a line number, -1 if not available.
+   * @param columnNum a column number, -1 if not available.
+   */
+  void addMessage(CompilerMessageCategory category, String message, @Nullable String url, int lineNum, int columnNum);
+
+  /**
+   * Allows to add a message to be shown in Compiler message view, with a specified Navigatable
+   * that is used to navigate to the error location.
+   *
+   * @param category    the category of a message (information, error, warning).
+   * @param message     the text of the message.
+   * @param url         a url to the file to which the message applies, null if not available.
+   * @param lineNum     a line number, -1 if not available.
+   * @param columnNum   a column number, -1 if not available.
+   * @param navigatable the navigatable pointing to the error location.
+   * @since 6.0
+   */
+  void addMessage(CompilerMessageCategory category, String message, @Nullable String url, int lineNum, int columnNum,
+                  Navigatable navigatable);
+
+  /**
+   * Returns all messages of the specified category added during the current compile session.
+   *
+   * @param category the category for which messages are requested.
+   * @return all compiler messages of the specified category
+   */
+  CompilerMessage[] getMessages(CompilerMessageCategory category);
+
+  /**
+   * Returns the count of messages of the specified category added during the current compile session.
+   *
+   * @param category the category for which messages are requested.
+   * @return the number of messages of the specified category
+   */
+  int getMessageCount(CompilerMessageCategory category);
+
+  /**
+   * Returns the progress indicator of the compilation process.
+   *
+   * @return the progress indicator instance.
+   */
+  @NotNull
+  ProgressIndicator getProgressIndicator();
+
+  /**
+   * Returns the current compile scope.
+   *
+   * @return current compile scope
+   */
+  CompileScope getCompileScope();
+
+  /**
+   * Returns the compile scope which would be used if the entire project was rebuilt.
+   * {@link #getCompileScope()} may return the scope, that is more narrow than ProjectCompileScope.
+   *
+   * @return project-wide compile scope.
+   */
+  CompileScope getProjectCompileScope();
+
+  /**
+   * A compiler may call this method in order to request complete project rebuild.
+   * This may be necessary, for example, when compiler caches are corrupted.
+   */
+  void requestRebuildNextTime(String message);
+
+  /**
+   * Returns the module to which the specified file belongs. This method is aware of the file->module mapping
+   * for generated files.
+   *
+   * @param file the file to check.
+   * @return the module to which the file belongs
+   */
+  Module getModuleByFile(VirtualFile file);
+
+  /**
+   * Returns the source roots for the specified module.
+   *
+   * @return module's source roots as well as source roots for generated sources that are attributed to the module
+   */
+  VirtualFile[] getSourceRoots(Module module);
+
+  /**
+   * Returns the list of all output directories.
+   *
+   * @return a list of all configured output directories from all modules (including output directories for tests)
+   */
+  VirtualFile[] getAllOutputDirectories();
+
+  /**
+   * Returns the output directory for the specified module.
+   *
+   * @param module the module to check.
+   * @return the output directory for the module specified, null if corresponding VirtualFile is not valid or directory not specified
+   */
+  @Nullable
+  VirtualFile getModuleOutputDirectory(Module module);
+
+  /**
+   * Returns the test output directory for the specified module.
+   *
+   * @param module the module to check.
+   * @return the tests output directory the module specified, null if corresponding VirtualFile is not valid. If in Paths settings
+   *         output directory for tests is not configured explicitly, but the output path is present, the output path will be returned.
+   */
+  @Nullable
+  VirtualFile getModuleOutputDirectoryForTests(Module module);
+
+  /**
+   * Checks if the compilation is incremental, i.e. triggered by one of "Make" actions.
+   *
+   * @return true if compilation is incremental. 
+   */
+  boolean isMake();
+
+  boolean isRebuild();
+
+  Project getProject();
+
+  boolean isAnnotationProcessorsEnabled();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java
new file mode 100644
index 0000000..5e1c304
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileScope.java
@@ -0,0 +1,59 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Interface describing the current compilation scope.
+ * Only sources that belong to the scope are compiled.
+ *
+ * @see CompilerManager#compile(CompileScope, CompileStatusNotification)
+ */
+public interface CompileScope extends ExportableUserDataHolder {
+  CompileScope[] EMPTY_ARRAY = new CompileScope[0];
+  /**
+   * Returns the list of files within the scope.
+   *
+   * @param fileType     the type of the files. Null should be passed if all available files are needed.
+   * @param inSourceOnly if true, files are searched only in directories within the scope that are marked as "sources" or "test sources" in module settings.
+   *                     Otherwise files are searched in all directories that belong to the scope.
+   * @return a list of files of given type that belong to this scope.
+   */
+  @NotNull
+  VirtualFile[] getFiles(@Nullable FileType fileType, boolean inSourceOnly);
+
+  /**
+   * Checks if the file with the specified URL belongs to the scope.
+   *
+   * @param url an VFS url. Note that actual file may not exist on the disk.
+   * @return true if the url specified belongs to the scope, false otherwise.
+   *         Note: the method may be time-consuming.
+   */
+  boolean belongs(String url);
+
+  /**
+   * Returns the list of modules files in which belong to the scope.
+   *
+   * @return a list of modules this scope affects.
+   */
+  @NotNull
+  Module[] getAffectedModules();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.java
new file mode 100644
index 0000000..9a8d7f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileStatusNotification.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.openapi.compiler;
+
+/**
+ * A callback interface passed to ComplerManager methods. Provides notification similar to
+ * {@link CompilationStatusListener}.
+ *
+ * @see CompilerManager#compile(CompileScope, CompileStatusNotification)
+ */
+public interface CompileStatusNotification {
+  /**
+   * Invoked in a Swing dispatch thread after the compilation is finished.
+   *
+   * @param aborted  true if compilation has been cancelled.
+   * @param errors   error count
+   * @param warnings warning count
+   * @param compileContext context for the finished compilation
+   */
+  void finished(boolean aborted, int errors, int warnings, final CompileContext compileContext);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.java
new file mode 100644
index 0000000..e3bd1df
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompileTask.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.openapi.compiler;
+
+/**
+ * Describes a task to be executed before or after compilation.
+ *
+ * @see CompilerManager#addAfterTask(CompileTask)
+ * @see CompilerManager#addBeforeTask(CompileTask)
+ */
+public interface CompileTask {
+  /**
+   * Executes the task.
+   *
+   * @param context current compile context
+   * @return true if execution succeeded, false otherwise. If the task returns false, the compilation
+   *         is aborted, and it's expected that the task adds a message defining the reason for the failure
+   *         to the compile context.
+   */
+  boolean execute(CompileContext context);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java
new file mode 100644
index 0000000..77f77f4
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/Compiler.java
@@ -0,0 +1,45 @@
+/*
+ * 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.openapi.compiler;
+
+import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+/**
+ * Base interface for a custom compiler which participates in the IDEA build process.
+ *
+ * @see CompilerManager#addCompiler(Compiler)
+ * @see CompilerManager#removeCompiler(Compiler)
+ */
+public interface Compiler {
+  ExtensionPointName<Compiler> EP_NAME = ExtensionPointName.create("com.intellij.compiler");
+  
+  /**
+   * Returns the description of the compiler. All registered compilers should have unique description.
+   *
+   * @return the description string.
+   */
+  @NotNull
+  String getDescription();
+
+  /**
+   * Called before compilation starts. If at least one of registered compilers returned false, compilation won't start.
+   * 
+   * @param scope the scope on which the compilation is started.
+   * @return true if everything is ok, false otherwise
+   */
+  boolean validateConfiguration(CompileScope scope);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java
new file mode 100644
index 0000000..eac8c80
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerBundle.java
@@ -0,0 +1,56 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.CommonBundle;
+import com.intellij.openapi.projectRoots.Sdk;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.PropertyKey;
+
+import java.lang.ref.Reference;
+import java.lang.ref.SoftReference;
+import java.util.ResourceBundle;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Sep 9, 2005
+ */
+public class CompilerBundle {
+  private static Reference<ResourceBundle> ourBundle;
+
+  @NonNls private static final String BUNDLE = "messages.CompilerBundle";
+
+  private CompilerBundle() {
+  }
+
+  public static String jdkHomeNotFoundMessage(final Sdk jdk) {
+    return message("javac.error.jdk.home.missing", jdk.getName(), jdk.getHomePath());
+  }
+
+  public static String message(@PropertyKey(resourceBundle = BUNDLE)String key, Object... params) {
+    return CommonBundle.message(getBundle(), key, params);
+  }
+
+  private static ResourceBundle getBundle() {
+    ResourceBundle bundle = null;
+    if (ourBundle != null) bundle = ourBundle.get();
+    if (bundle == null) {
+      bundle = ResourceBundle.getBundle(BUNDLE);
+      ourBundle = new SoftReference<ResourceBundle>(bundle);
+    }
+    return bundle;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java
new file mode 100644
index 0000000..8147e0b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFactory.java
@@ -0,0 +1,28 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public interface CompilerFactory {
+  ExtensionPointName<CompilerFactory> EP_NAME = ExtensionPointName.create("com.intellij.compilerFactory");
+  
+  Compiler[] createCompilers(@NotNull CompilerManager compilerManager);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java
new file mode 100644
index 0000000..c7a9f7f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerFilter.java
@@ -0,0 +1,33 @@
+/*
+ * 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.openapi.compiler;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jul 9, 2009
+ */
+public interface CompilerFilter {
+  CompilerFilter ALL = new CompilerFilter() {
+    public boolean acceptCompiler(Compiler compiler) {
+      return true;
+    }
+  };
+  /**
+   * @param compiler
+   * @return true if this compiler can be executed
+   */
+  boolean acceptCompiler(Compiler compiler);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java
new file mode 100644
index 0000000..4456665
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerManager.java
@@ -0,0 +1,294 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.notification.NotificationGroup;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Set;
+
+/**
+ * A "root" class in compiler subsystem - allows one to register a custom compiler or a compilation task, register/unregister a compilation listener
+ * and invoke various types of compilations (make, compile, rebuild)
+ */
+public abstract class CompilerManager {
+  public static final Key<Key> CONTENT_ID_KEY = Key.create("COMPILATION_CONTENT_ID_CUSTOM_KEY");
+  public static final NotificationGroup NOTIFICATION_GROUP = NotificationGroup.logOnlyGroup("Compiler");
+
+  /**
+   * Returns the compiler manager instance for the specified project.
+   *
+   * @param project the project for which the manager is requested.
+   * @return the manager instance.
+   */
+  public static CompilerManager getInstance(Project project) {
+    return ServiceManager.getService(project, CompilerManager.class);
+  }
+  
+  public abstract boolean isCompilationActive();
+  
+  /**
+   * Registers a custom compiler.
+   *
+   * @param compiler the compiler to register.
+   */
+  public abstract void addCompiler(@NotNull Compiler compiler);
+
+  /**
+   * Registers a custom translating compiler. Input and output filetype sets allow compiler manager
+   * to sort translating compilers so that output of one compiler will be used as input for another one
+   * 
+   * @param compiler compiler implementation 
+   * @param inputTypes a set of filetypes that compiler accepts as input
+   * @param outputTypes a set of filetypes that compiler can generate
+   */
+  public abstract void addTranslatingCompiler(@NotNull TranslatingCompiler compiler, Set<FileType> inputTypes, Set<FileType> outputTypes);
+
+  @NotNull
+  public abstract Set<FileType> getRegisteredInputTypes(@NotNull TranslatingCompiler compiler);
+  
+  @NotNull
+  public abstract Set<FileType> getRegisteredOutputTypes(@NotNull TranslatingCompiler compiler);
+  
+  /**
+   * Unregisters a custom compiler.
+   *
+   * @param compiler the compiler to unregister.
+   */
+  public abstract void removeCompiler(@NotNull Compiler compiler);
+
+  /**
+   * Returns all registered compilers of the specified class.
+   *
+   * @param compilerClass the class for which the compilers should be returned.
+   * @return all registered compilers of the specified class.
+   */
+  @NotNull
+  public abstract <T  extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass);
+
+  /**
+   * Returns all registered compilers of the specified class that the filter accepts
+   *
+   * @param compilerClass the class for which the compilers should be returned.
+   * @param filter additional filter to restrict compiler instances
+   * @return all registered compilers of the specified class.
+   */
+  @NotNull
+  public abstract <T  extends Compiler> T[] getCompilers(@NotNull Class<T> compilerClass, CompilerFilter filter);
+
+  /**
+   * Registers the type as a compilable type so that Compile action will be enabled on files of this type.
+   *
+   * @param type the type for which the Compile action is enabled.
+   */
+  public abstract void addCompilableFileType(@NotNull FileType type);
+
+  /**
+   * Unregisters the type as a compilable type so that Compile action will be disabled on files of this type.
+   *
+   * @param type the type for which the Compile action is disabled.
+   */
+  public abstract void removeCompilableFileType(@NotNull FileType type);
+
+  /**
+   * Checks if files of the specified type can be compiled by one of registered compilers.
+   * If the compiler can process files of certain type, it should register this file type within
+   * the CompilerManager as a compilable file type.
+   *
+   * @param type the type to check.
+   * @return true if the file type is compilable, false otherwise.
+   * @see com.intellij.openapi.compiler.CompilerManager#addCompilableFileType(FileType)
+   */
+  public abstract boolean isCompilableFileType(@NotNull FileType type);
+
+  /**
+   * Registers a compiler task that will be executed before the compilation.
+   *
+   * @param task the task to register.
+   */
+  public abstract void addBeforeTask(@NotNull CompileTask task);
+
+  /**
+   * Registers a compiler task  that will be executed after the compilation.
+   *
+   * @param task the task to register.
+   */
+  public abstract void addAfterTask(@NotNull CompileTask task);
+
+  /**
+   * Returns the list of all tasks to be executed before compilation.
+   *
+   * @return all tasks to be executed before compilation.
+   */
+  @NotNull
+  public abstract CompileTask[] getBeforeTasks();
+
+  /**
+   * Returns the list of all tasks to be executed after compilation.
+   *
+   * @return all tasks to be executed after compilation.
+   */
+  @NotNull
+  public abstract CompileTask[] getAfterTasks();
+
+  /**
+   * Compile a set of files.
+   *
+   * @param files             a list of files to compile. If a VirtualFile is a directory, all containing files are processed.
+   *                          Compiler excludes are not honored.
+   * @param callback          a notification callback, or null if no notifications needed.
+   */
+  public abstract void compile(@NotNull VirtualFile[] files, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all sources (including test sources) from the module. Compiler excludes are not honored.
+   *
+   * @param module            a module which sources are to be compiled
+   * @param callback          a notification callback, or null if no notifications needed
+   */
+  public abstract void compile(@NotNull Module module, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all files from the scope given.  Compiler excludes are not honored.
+   *
+   * @param scope             a scope to be compiled
+   * @param callback          a notification callback, or null if no notifications needed
+   */
+  public abstract void compile(@NotNull CompileScope scope, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all modified files and all files that depend on them all over the project.
+   * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored.
+   *
+   * @param callback a notification callback, or null if no notifications needed
+   */
+  public abstract void make(@Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all modified files and all files that depend on them from the given module and all modules this module depends on recursively.
+   * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored.
+   *
+   * @param module   a module which sources are to be compiled.
+   * @param callback a notification callback, or null if no notifications needed.
+   */
+  public abstract void make(@NotNull Module module, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all modified files and all files that depend on them from the modules and all modules these modules depend on recursively.
+   * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project.
+   *
+   * @param project  a project modules belong to
+   * @param modules  modules to compile
+   * @param callback a notification callback, or null if no notifications needed.
+   */
+  public abstract void make(@NotNull Project project, @NotNull Module[] modules, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all modified files and all files that depend on them from the scope given.
+   * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project
+   *
+   * @param scope    a scope to be compiled
+   * @param callback a notification callback, or null if no notifications needed
+   */
+  public abstract void make(@NotNull CompileScope scope, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Compile all modified files and all files that depend on them from the scope given.
+   * Files are compiled according to dependencies between the modules they belong to. Compiler excludes are honored. All modules must belong to the same project
+   *
+   * @param scope    a scope to be compiled
+   * @param filter filter allowing choose what compilers should be executed
+   * @param callback a notification callback, or null if no notifications needed
+   */
+  public abstract void make(@NotNull CompileScope scope, CompilerFilter filter, @Nullable CompileStatusNotification callback);
+
+  /**
+   * Checks if compile scope given is up-to-date
+   * @param scope
+   * @return true if make on the scope specified wouldn't do anything or false if something is to be compiled or deleted 
+   */
+  public abstract boolean isUpToDate(@NotNull CompileScope scope);
+  /**
+   * Rebuild the whole project from scratch. Compiler excludes are honored.
+   *
+   * @param callback a notification callback, or null if no notifications needed
+   */
+  public abstract void rebuild(@Nullable CompileStatusNotification callback);
+
+  /**
+   * Execute a custom compile task.
+   *
+   * @param task           the task to execute.
+   * @param scope          compile scope for which the task is executed.
+   * @param contentName    the name of a tab in message view where the execution results will be displayed.
+   * @param onTaskFinished a runnable to be executed when the task finishes, null if nothing should be executed.
+   */
+  public abstract void executeTask(@NotNull CompileTask task, @NotNull CompileScope scope, String contentName,
+                                   @Nullable Runnable onTaskFinished);
+
+  /**
+   * Register a listener to track compilation events.
+   *
+   * @param listener the listener to be registered.
+   */
+  public abstract void addCompilationStatusListener(@NotNull CompilationStatusListener listener);
+  public abstract void addCompilationStatusListener(@NotNull CompilationStatusListener listener, @NotNull Disposable parentDisposable);
+
+  /**
+   * Unregister a compilation listener.
+   *
+   * @param listener the listener to be unregistered.
+   */
+  public abstract void removeCompilationStatusListener(@NotNull CompilationStatusListener listener);
+
+  /**
+   * Checks if the specified file is excluded from compilation.
+   *
+   * @param file the file to check.
+   * @return true if the file is excluded from compilation, false otherwise
+   */
+  public abstract boolean isExcludedFromCompilation(@NotNull VirtualFile file);
+
+  @NotNull
+  public abstract OutputToSourceMapping getJavaCompilerOutputMapping();
+
+  /*
+   * Convetience methods for creating frequently-used compile scopes
+   */
+  @NotNull
+  public abstract CompileScope createFilesCompileScope(@NotNull VirtualFile[] files);
+  @NotNull
+  public abstract CompileScope createModuleCompileScope(@NotNull Module module, final boolean includeDependentModules);
+  @NotNull
+  public abstract CompileScope createModulesCompileScope(@NotNull Module[] modules, final boolean includeDependentModules);
+  @NotNull
+  public abstract CompileScope createModuleGroupCompileScope(@NotNull Project project, @NotNull Module[] modules, final boolean includeDependentModules);
+  @NotNull
+  public abstract CompileScope createProjectCompileScope(@NotNull Project project);
+
+  public abstract void setValidationEnabled(ModuleType moduleType, boolean enabled);
+
+  public abstract boolean isValidationEnabled(Module moduleType);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java
new file mode 100644
index 0000000..3afd6a6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessage.java
@@ -0,0 +1,75 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Describes a single compiler message that is shown in compiler message view.
+ *
+ * @see CompileContext#addMessage(CompilerMessageCategory, String, String, int, int)
+ */
+public interface CompilerMessage {
+  /**
+   * An empty array of compiler messages which can be reused to avoid unnecessary allocations.
+   */
+  CompilerMessage[] EMPTY_ARRAY = new CompilerMessage[0];
+
+  /**
+   * Returns the category of the message.
+   *
+   * @return a category this message belongs to (error, warning, information).
+   */
+  CompilerMessageCategory getCategory();
+
+  /**
+   * Returs the message text.
+   *
+   * @return message text
+   */
+  String getMessage();
+
+  /**
+   * Returns the navigatable object allowing to navigate to the message source.
+   *
+   * @return the instance.
+   */
+  @Nullable
+  Navigatable getNavigatable();
+
+  /**
+   * Returns the file to which the message applies.
+   *
+   * @return the file to which the message applies.
+   */
+  VirtualFile getVirtualFile();
+
+  /**
+   * Returns the location prefix prepended to message while exporting compilation results to text.
+   *
+   * @return location prefix prepended to message while exporting compilation results to text.
+   */
+  String getExportTextPrefix();
+
+  /**
+   * Returns the location prefix prepended to message while exporting compilation results to text.
+   *
+   * @return location prefix prepended to message while rendering compilation results in UI.
+   */
+  String getRenderTextPrefix();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java
new file mode 100644
index 0000000..708184f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerMessageCategory.java
@@ -0,0 +1,59 @@
+/*
+ * 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.openapi.compiler;
+
+/**
+ * A set of constants describing possible message categories.
+ *
+ * @see CompilerMessage#getCategory()
+ * @see CompileContext#addMessage(CompilerMessageCategory, String, String, int, int) 
+ */
+public enum CompilerMessageCategory {
+  ERROR {
+    public String toString() {
+      return CompilerBundle.message("message.category.error");
+    }
+    public String getPresentableText() {
+      return toString();
+    }
+  },
+  WARNING {
+    public String toString() {
+      return CompilerBundle.message("message.category.warning");
+    }
+    public String getPresentableText() {
+      return toString();
+    }
+  },
+  INFORMATION {
+    public String toString() {
+      return CompilerBundle.message("message.category.information");
+    }
+    public String getPresentableText() {
+      return toString();
+    }
+  },
+  STATISTICS {
+    public String toString() {
+      return CompilerBundle.message("message.category.statistics");
+    }
+    public String getPresentableText() {
+      return toString();
+    }
+  };
+
+  public abstract String getPresentableText();
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java
new file mode 100644
index 0000000..f02820f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerPaths.java
@@ -0,0 +1,245 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.openapi.application.Application;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.PathUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.jps.model.java.compiler.AnnotationProcessingConfiguration;
+
+import java.io.File;
+import java.util.Arrays;
+import java.util.Comparator;
+import java.util.Locale;
+
+/**
+ * A set of utility methods for working with paths
+ */
+public class CompilerPaths {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.compiler.CompilerPaths");
+  private static volatile String ourSystemPath;
+  private static final Comparator<String> URLS_COMPARATOR = new Comparator<String>() {
+    public int compare(String o1, String o2) {
+      return o1.compareTo(o2);
+    }
+  };
+  private static final String DEFAULT_GENERATED_DIR_NAME = "generated";
+
+  /**
+   * Returns a directory
+   * @param project
+   * @param compiler
+   * @return a directory where compiler may generate files. All generated files are not deleted when the application exits
+   */
+  public static File getGeneratedDataDirectory(Project project, Compiler compiler) {
+    //noinspection HardCodedStringLiteral
+    return new File(getGeneratedDataDirectory(project), compiler.getDescription().replaceAll("\\s+", "_"));
+  }
+
+  /**
+   * @param project
+   * @return a root directory where generated files for various compilers are stored
+   */
+  public static File getGeneratedDataDirectory(Project project) {
+    //noinspection HardCodedStringLiteral
+    return new File(getCompilerSystemDirectory(project), ".generated");
+  }
+
+  /**
+   * @param project
+   * @return a root directory where compiler caches for the given project are stored
+   */
+  public static File getCacheStoreDirectory(final Project project) {
+    //noinspection HardCodedStringLiteral
+    return new File(getCompilerSystemDirectory(project), ".caches");
+  }
+
+  public static File getCacheStoreDirectory(String compilerProjectDirName) {
+    //noinspection HardCodedStringLiteral
+    return new File(getCompilerSystemDirectory(compilerProjectDirName), ".caches");
+  }
+
+  public static File getRebuildMarkerFile(Project project) {
+    return new File(getCompilerSystemDirectory(project), "rebuild_required");
+  }
+
+  /**
+   * @param project
+   * @return a directory under IDEA "system" directory where all files related to compiler subsystem are stored (such as compiler caches or generated files)
+   */
+  public static File getCompilerSystemDirectory(Project project) {
+    return getCompilerSystemDirectory(getCompilerSystemDirectoryName(project));
+  }
+
+  public static File getCompilerSystemDirectory(String compilerProjectDirName) {
+    return new File(getCompilerSystemDirectory(), compilerProjectDirName);
+  }
+
+  public static String getCompilerSystemDirectoryName(Project project) {
+    return getPresentableName(project) + "." + project.getLocationHash();
+  }
+
+  @Nullable
+  private static String getPresentableName(final Project project) {
+    if (project.isDefault()) {
+      return project.getName();
+    }
+
+    String location = project.getPresentableUrl();
+    if (location == null) {
+      return null;
+    }
+
+    String projectName = FileUtil.toSystemIndependentName(location);
+    if (projectName.endsWith("/")) {
+      projectName = projectName.substring(0, projectName.length() - 1);
+    }
+
+    final int lastSlash = projectName.lastIndexOf('/');
+    if (lastSlash >= 0 && lastSlash + 1 < projectName.length()) {
+      projectName = projectName.substring(lastSlash + 1);
+    }
+
+    if (StringUtil.endsWithIgnoreCase(projectName, ProjectFileType.DOT_DEFAULT_EXTENSION)) {
+      projectName = projectName.substring(0, projectName.length() - ProjectFileType.DOT_DEFAULT_EXTENSION.length());
+    }
+    
+    projectName = projectName.toLowerCase(Locale.US).replace(':', '_'); // replace ':' from windows drive names
+    return projectName;
+  }
+
+  public static File getCompilerSystemDirectory() {
+    //noinspection HardCodedStringLiteral
+    final String systemPath = ourSystemPath != null? ourSystemPath : (ourSystemPath = PathUtil.getCanonicalPath(PathManager.getSystemPath()));
+    return new File(systemPath, "compiler");
+  }
+
+  /**
+   * @param module
+   * @param forTestClasses true if directory for test sources, false - for sources.
+   * @return a directory to which the sources (or test sources depending on the second partameter) should be compiled.
+   * Null is returned if output directory is not specified or is not valid
+   */
+  @Nullable
+  public static VirtualFile getModuleOutputDirectory(final Module module, boolean forTestClasses) {
+    final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+    VirtualFile outPath;
+    if (forTestClasses) {
+      final VirtualFile path = compilerModuleExtension.getCompilerOutputPathForTests();
+      if (path != null) {
+        outPath = path;
+      }
+      else {
+        outPath = compilerModuleExtension.getCompilerOutputPath();
+      }
+    }
+    else {
+      outPath = compilerModuleExtension.getCompilerOutputPath();
+    }
+    if (outPath == null) {
+      return null;
+    }
+    if (!outPath.isValid()) {
+      LOG.info("Requested output path for module " + module.getName() + " is not valid");
+      return null;
+    }
+    return outPath;
+  }
+
+  /**
+   * The same as {@link #getModuleOutputDirectory} but returns String.
+   * The method still returns a non-null value if the output path is specified in Settings but does not exist on disk.
+   */
+  @Nullable
+  public static String getModuleOutputPath(final Module module, boolean forTestClasses) {
+    final String outPathUrl;
+    final Application application = ApplicationManager.getApplication();
+    final CompilerModuleExtension extension = CompilerModuleExtension.getInstance(module);
+    if (forTestClasses) {
+      if (application.isDispatchThread()) {
+        final String url = extension.getCompilerOutputUrlForTests();
+        outPathUrl = url != null ? url : extension.getCompilerOutputUrl();
+      }
+      else {
+        outPathUrl = application.runReadAction(new Computable<String>() {
+          public String compute() {
+            final String url = extension.getCompilerOutputUrlForTests();
+            return url != null ? url : extension.getCompilerOutputUrl();
+          }
+        });
+      }
+    }
+    else { // for ordinary classes
+      if (application.isDispatchThread()) {
+        outPathUrl = extension.getCompilerOutputUrl();
+      }
+      else {
+        outPathUrl = application.runReadAction(new Computable<String>() {
+          public String compute() {
+            return extension.getCompilerOutputUrl();
+          }
+        });
+      }
+    }
+    return outPathUrl != null? VirtualFileManager.extractPath(outPathUrl) : null;
+  }
+
+  @Nullable
+  public static String getAnnotationProcessorsGenerationPath(Module module) {
+    final AnnotationProcessingConfiguration config = CompilerConfiguration.getInstance(module.getProject()).getAnnotationProcessingConfiguration(module);
+    final String sourceDirName = config.getGeneratedSourcesDirectoryName(false);
+    if (config.isOutputRelativeToContentRoot()) {
+      final String[] roots = ModuleRootManager.getInstance(module).getContentRootUrls();
+      if (roots.length == 0) {
+        return null;
+      }
+      if (roots.length > 1) {
+        Arrays.sort(roots, URLS_COMPARATOR);
+      }
+      return StringUtil.isEmpty(sourceDirName)? VirtualFileManager.extractPath(roots[0]): VirtualFileManager.extractPath(roots[0]) + "/" + sourceDirName;
+    }
+
+
+    final String path = getModuleOutputPath(module, false);
+    if (path == null) {
+      return null;
+    }
+    return StringUtil.isEmpty(sourceDirName)? path : path + "/" + sourceDirName;
+  }
+  
+  @NonNls
+  public static String getGenerationOutputPath(IntermediateOutputCompiler compiler, Module module, final boolean forTestSources) {
+    final String generatedCompilerDirectoryPath = getGeneratedDataDirectory(module.getProject(), compiler).getPath();
+    //noinspection HardCodedStringLiteral
+    final String moduleDir = module.getName().replaceAll("\\s+", "_") + "." + Integer.toHexString(module.getModuleFilePath().hashCode());
+    return generatedCompilerDirectoryPath.replace(File.separatorChar, '/') + "/" + moduleDir + "/" + (forTestSources? "test" : "production");
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java
new file mode 100644
index 0000000..a3b8c46
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CompilerTopics.java
@@ -0,0 +1,28 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.util.messages.Topic;
+
+/**
+ * @author yole
+ */
+public class CompilerTopics {
+  public static final Topic<CompilationStatusListener> COMPILATION_STATUS = new Topic<CompilationStatusListener>("compilation status", CompilationStatusListener.class);
+
+  private CompilerTopics() {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java
new file mode 100644
index 0000000..7d80c21
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/CopyingCompiler.java
@@ -0,0 +1,151 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.io.IOUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * Compiler which copies the compiled files to a different directory.
+ */
+public abstract class CopyingCompiler implements PackagingCompiler{
+  public abstract VirtualFile[] getFilesToCopy(CompileContext context);
+  public abstract String getDestinationPath(VirtualFile sourceFile);
+
+  public final void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state) {
+    if (state != null) {
+      final String destinationPath = ((DestinationFileInfo)state).getDestinationPath();
+      new File(destinationPath).delete();
+    }
+  }
+
+  @NotNull
+  public final ProcessingItem[] getProcessingItems(final CompileContext context) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<ProcessingItem[]>() {
+      public ProcessingItem[] compute() {
+        final VirtualFile[] filesToCopy = getFilesToCopy(context);
+        final ProcessingItem[] items = new ProcessingItem[filesToCopy.length];
+        for (int idx = 0; idx < filesToCopy.length; idx++) {
+          final VirtualFile file = filesToCopy[idx];
+          items[idx] = new CopyItem(file, getDestinationPath(file));
+        }
+        return items;
+      }
+    });
+  }
+
+  public ProcessingItem[] process(CompileContext context, ProcessingItem[] items) {
+    final List<ProcessingItem> successfullyProcessed = new ArrayList<ProcessingItem>(items.length);
+    for (ProcessingItem item : items) {
+      final CopyItem copyItem = (CopyItem)item;
+      final String fromPath = copyItem.getSourcePath();
+      final String toPath = copyItem.getDestinationPath();
+      try {
+        FileUtil.copy(new File(fromPath), new File(toPath));
+        successfullyProcessed.add(copyItem);
+      }
+      catch (IOException e) {
+        context.addMessage(
+          CompilerMessageCategory.ERROR,
+          CompilerBundle.message("error.copying", fromPath, toPath, e.getMessage()),
+          null, -1, -1
+        );
+      }
+    }
+    return successfullyProcessed.toArray(new ProcessingItem[successfullyProcessed.size()]);
+  }
+
+  @NotNull
+  public String getDescription() {
+    return CompilerBundle.message("file.copying.compiler.description");
+  }
+
+  public boolean validateConfiguration(CompileScope scope) {
+    return true;
+  }
+
+  public ValidityState createValidityState(DataInput in) throws IOException {
+    return new DestinationFileInfo(IOUtil.readString(in), true);
+  }
+
+  private static class CopyItem implements FileProcessingCompiler.ProcessingItem {
+    private final VirtualFile myFile;
+    private final DestinationFileInfo myInfo;
+    private final String mySourcePath;
+
+    public CopyItem(VirtualFile file, String destinationPath) {
+      myFile = file;
+      mySourcePath = file.getPath().replace('/', File.separatorChar);
+      myInfo = new DestinationFileInfo(destinationPath, new File(destinationPath).exists());
+    }
+
+    @NotNull
+    public VirtualFile getFile() {
+      return myFile;
+    }
+
+    public ValidityState getValidityState() {
+      return myInfo;
+    }
+
+    public String getSourcePath() {
+      return mySourcePath;
+    }
+
+    public String getDestinationPath() {
+      return myInfo.getDestinationPath();
+    }
+  }
+
+  private static class DestinationFileInfo implements ValidityState {
+    private final String destinationPath;
+    private final boolean myFileExists;
+
+    public DestinationFileInfo(String destinationPath, boolean fileExists) {
+      this.destinationPath = destinationPath;
+      myFileExists = fileExists;
+    }
+
+    public boolean equalsTo(ValidityState otherState) {
+      if (!(otherState instanceof DestinationFileInfo)) {
+        return false;
+      }
+      DestinationFileInfo destinationFileInfo = (DestinationFileInfo)otherState;
+      return (myFileExists == destinationFileInfo.myFileExists) && (destinationPath.equals(destinationFileInfo.destinationPath));
+    }
+
+    public void save(DataOutput out) throws IOException {
+      IOUtil.writeString(destinationPath, out);
+    }
+
+    public String getDestinationPath() {
+      return destinationPath;
+    }
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java
new file mode 100644
index 0000000..85b0156
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/DummyCompileContext.java
@@ -0,0 +1,121 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressIndicator;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.Navigatable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class DummyCompileContext implements CompileContext {
+  protected DummyCompileContext() {
+  }
+
+  private static final DummyCompileContext OUR_INSTANCE = new DummyCompileContext();
+
+  public static DummyCompileContext getInstance() {
+    return OUR_INSTANCE;
+  }
+
+  public Project getProject() {
+    return null;
+  }
+
+  public void addMessage(CompilerMessageCategory category, String message, String url, int lineNum, int columnNum) {
+  }
+
+
+  public void addMessage(CompilerMessageCategory category,
+                         String message,
+                         @Nullable String url,
+                         int lineNum,
+                         int columnNum,
+                         Navigatable navigatable) {
+  }
+
+  public CompilerMessage[] getMessages(CompilerMessageCategory category) {
+    return CompilerMessage.EMPTY_ARRAY;
+  }
+
+  public int getMessageCount(CompilerMessageCategory category) {
+    return 0;
+  }
+
+  public ProgressIndicator getProgressIndicator() {
+    return null;
+  }
+
+  public CompileScope getCompileScope() {
+    return null;
+  }
+
+  public CompileScope getProjectCompileScope() {
+    return null;
+  }
+
+  public void requestRebuildNextTime(String message) {
+  }
+
+  public Module getModuleByFile(VirtualFile file) {
+    return null;
+  }
+
+  public boolean isAnnotationProcessorsEnabled() {
+    return false;
+  }
+
+  public VirtualFile[] getSourceRoots(Module module) {
+    return VirtualFile.EMPTY_ARRAY;
+  }
+
+  public VirtualFile[] getAllOutputDirectories() {
+    return VirtualFile.EMPTY_ARRAY;
+  }
+
+  public VirtualFile getModuleOutputDirectory(final Module module) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<VirtualFile>() {
+      public VirtualFile compute() {
+        return CompilerModuleExtension.getInstance(module).getCompilerOutputPath();
+      }
+    });
+  }
+
+  public VirtualFile getModuleOutputDirectoryForTests(Module module) {
+    return null;
+  }
+
+  public <T> T getUserData(@NotNull Key<T> key) {
+    return null;
+  }
+
+  public <T> void putUserData(@NotNull Key<T> key, T value) {
+  }
+
+  public boolean isMake() {
+    return false; // stub implementation
+  }
+
+  public boolean isRebuild() {
+    return false;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java
new file mode 100644
index 0000000..fdcf405
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/EmptyValidityState.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2010 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.openapi.compiler;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Empty validity state for force recompilation
+ *
+ * @author Konstantin Bulenkov
+ */
+public final class EmptyValidityState implements ValidityState {
+  /**
+   * In most cases this method returns false to force recompile
+   *
+   * @param otherState the state to compare with.
+   * @return true if and only if otherState == this
+   */
+  public boolean equalsTo(ValidityState otherState) {
+      return otherState == this;
+  }
+
+  /**
+   * Do nothing here
+   */
+  public void save(DataOutput dataOutput) throws IOException {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java
new file mode 100644
index 0000000..1dda010
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolder.java
@@ -0,0 +1,33 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolder;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Map;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: 2/21/12
+ */
+public interface ExportableUserDataHolder extends UserDataHolder{
+
+  @NotNull
+  Map<Key, Object> exportUserData();
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java
new file mode 100644
index 0000000..4f4e20d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ExportableUserDataHolderBase.java
@@ -0,0 +1,53 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.UserDataHolderBase;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+public class ExportableUserDataHolderBase extends UserDataHolderBase implements ExportableUserDataHolder{
+  private final Set<Key> myKeys = Collections.synchronizedSet(new HashSet<Key>());
+
+  @NotNull
+  public final Map<Key, Object> exportUserData() {
+    final Map<Key, Object> result = new HashMap<Key, Object>();
+    synchronized (myKeys) {
+      for (Key<?> k : myKeys) {
+        final Object data = getUserData(k);
+        if (data != null) {
+          result.put(k, data);
+        }
+      }
+    }
+    return result;
+  }
+
+  @Override
+  public final <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
+    if (value != null) {
+      myKeys.add(key);
+    }
+    else {
+      myKeys.remove(key);
+    }
+    super.putUserData(key, value);
+  }
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java
new file mode 100644
index 0000000..733514c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/FileProcessingCompiler.java
@@ -0,0 +1,77 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A base interface describing shared functionality for various types of file processing compilers.
+ * Actual compiler implementation should implement one of these:
+ * {@link ClassInstrumentingCompiler}, {@link ClassPostProcessingCompiler},
+ * {@link SourceInstrumentingCompiler}.
+ */
+public interface FileProcessingCompiler extends Compiler, ValidityStateFactory {
+  /**
+   * Describes a processing unit for this compiler - a virtual file with associated state.
+   */
+  interface ProcessingItem {
+    /**
+     * A utility constant used to return empty arrays of ProcessingItem objects
+     */
+    ProcessingItem[] EMPTY_ARRAY = new ProcessingItem[0];
+
+    /**
+     * Returns the file to be processed.
+     *
+     * @return a file to be processed; cannot be null
+     */
+    @NotNull
+    VirtualFile getFile();
+
+    /**
+     * @return an object describing dependencies of the instrumented file (can be null).
+     *         For example, if the file "A" should be processed whenever file "B" or file "C" is changed, the ValidityState object can
+     *         be composed of a pair [timestamp("B"), timestamp("C")]. Thus, whenever a timestamp of any of these files is changed,
+     *         the current ValidityState won't be equal to the stored ValidityState and the item will be picked up by the make for recompilation.
+     */
+    @Nullable
+    ValidityState getValidityState();
+  }
+
+  /**
+   * Returns the items which will be processed in the current compile operation.
+   * The method is called before the call to {@link #process} method
+   *
+   * @param context the current compilation context.
+   * @return a non-null array of all items that potentially can be processed at the moment of method call. Even if
+   *         the file is not changed, it should be returned if it _can_ be processed by the compiler implementing the interface.
+   */
+  @NotNull
+  ProcessingItem[] getProcessingItems(CompileContext context);
+
+  /**
+   * Compiles the specified items.
+   *
+   * @param context the current compilation context.
+   * @param items items to be processed, selected by make subsystem. The items are selected from the list returned by the
+   *              {@link #getProcessingItems} method.
+   * @return successfully processed items.
+   */
+  ProcessingItem[] process(CompileContext context, ProcessingItem[] items);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java
new file mode 100644
index 0000000..962bcb2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/GeneratingCompiler.java
@@ -0,0 +1,79 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * A base interface for all compilers that generate new files. The generated files may be processed by other compilers.
+ * Actual implementation should implement one of its subinterfaces. Currently only {@link SourceGeneratingCompiler} is available.
+ */
+public interface GeneratingCompiler extends Compiler, ValidityStateFactory, IntermediateOutputCompiler {
+  /**
+   * Represents a single item generated by the compiler.
+   */
+  interface GenerationItem {
+    /**
+     * Returns the path of the generated file.
+     *
+     * @return path of a generated file, relative to output directory.
+     */
+    String getPath();
+
+    /**
+     * Returns the object describing dependencies of the generated file.
+     *
+     * @return a serializable object describing dependencies of the generated file.
+     */
+    ValidityState getValidityState();
+
+    /**
+     * Returns the module to which the generated item belongs. This affects the sequence
+     * of compiling the generated files.
+     *
+     * @return the module to which the generated item belongs.
+     */
+    Module getModule();
+
+    /**
+     * @return true if the generated item is supposed to be located in test sources, false otherwise
+     */
+    boolean isTestSource();
+  }
+
+  /**
+   * Returns the list of all the files this compiler can generate.
+   *
+   * @param context the current compile context.
+   * @return items describing all the files this compiler can generate.
+   */
+  GenerationItem[] getGenerationItems(CompileContext context);
+
+  /**
+   * Invokes the generation process.
+   *
+   * @param context             the current compile context.
+   * @param items               what items to generate.
+   * @param outputRootDirectory the root directory under which the items are generated (the paths
+   *                            in {@link GenerationItem#getPath()} are relative to that directory).
+   *                            All files generated by the compiler must be placed in that directory or
+   *                            its subdirectories, otherwise they will not be compiled properly on
+   *                            subsequent build steps.
+   * @return successfully generated items
+   */
+  GenerationItem[] generate(CompileContext context, GenerationItem[] items, VirtualFile outputRootDirectory);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.java
new file mode 100644
index 0000000..a289393
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/IntermediateOutputCompiler.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.openapi.compiler;
+
+/**
+ * A tag interface denoting that compiler's output should go into 'intermediate' directory 
+ * and can be used as input to another compiler 
+ */
+public interface IntermediateOutputCompiler extends Compiler{
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java
new file mode 100644
index 0000000..27a3975
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/JavaSourceTransformingCompiler.java
@@ -0,0 +1,53 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * This compiler is called right before the java sources compiler.
+ */
+public interface JavaSourceTransformingCompiler extends Compiler {
+
+  /**
+   * Checks if the file can be transformed by the compiler.
+   *
+   * @param file an original file that is about to be compiled with java compiler
+   * @return true if compiler would like to transform the file, false otherwise.
+   *         If true is returned, a copy of original file will be made and {@link #transform(CompileContext,com.intellij.openapi.vfs.VirtualFile,com.intellij.openapi.vfs.VirtualFile)}
+   *         method will be called on it. If transformation succeeded, the transformed copy will be passed to java compiler instead of original file.
+   */
+  boolean isTransformable(VirtualFile file);
+
+  /**
+   * Transforms the specified file.
+   *
+   * @param context      the current compile context.
+   * @param file         a copy of original file to be transformed. If there are more than one transformer registered, this copy may already contain transformations made by other transformers which were called before this one
+   * @param originalFile an original file. Since the copy that is supposed to be modified is located outside the project, it is not possible to use PSI for analysis.
+   *                     So the original file is provided. Note that it is passed for reference purposes only. It MUST NOT be transformed or changed in any way.
+   *                     For example, it is possible to obtain a PsiFile for the original file:<br><br>
+   *                     <code>PsiJavaFile originalPsiJavaFile = (PsiJavaFile)PsiManager.getInstance(project).findFile(originalFile)</code>;<br><br>
+   *                     The obtained originalPsiJavaFile can be analysed, searched etc. For transforming the file by the means of PSI, there should be created a copy of the originalPsiJavaFile:<br><br>
+   *                     <code>PsiJavaFile psiFileCopy = (PsiJavaFile)originalPsiJavaFile.copy();</code><br><br>
+   *                     The psiFileCopy can then be transformed, and its text saved to the first "file" argument:<br><br>
+   *                     <code>String text = psiFileCopy.getText();</code><br><br>
+   *                     <p/>
+   *                     <b>Note that transforming files by the means of PSI may considerably slow down the overall make performance.</b>
+   * @return true if transform succeeded, false otherwise.
+   */
+  boolean transform(CompileContext context, VirtualFile file, VirtualFile originalFile);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.java
new file mode 100644
index 0000000..0e1afed
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/OutputToSourceMapping.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.openapi.compiler;
+
+import org.jetbrains.annotations.Nullable;
+
+public interface OutputToSourceMapping {
+  @Nullable
+  String getSourcePath(String outputPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java
new file mode 100644
index 0000000..e7e1350
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/PackagingCompiler.java
@@ -0,0 +1,38 @@
+/*
+ * 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.openapi.compiler;
+
+import org.jetbrains.annotations.Nullable;
+
+
+/**
+ * A tag interface indicating that the compiler will package the compiled Java classes.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface PackagingCompiler extends FileProcessingCompiler{
+  /**
+   * Called when the compiler detects that an item in the output directory is outdated
+   * and will be recompiled. Note that this method will be called before, and independently from,
+   * subsequent calls to {@link #process}.
+   *
+   * @param context the current compile context.
+   * @param url     the URL of a file in the output directory which will be recompiled.
+   * @param state   the validity state of the file specified by <code>url</code>.
+   */
+  void processOutdatedItem(CompileContext context, String url, @Nullable ValidityState state);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java
new file mode 100644
index 0000000..4c0b646
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceGeneratingCompiler.java
@@ -0,0 +1,42 @@
+/*
+ * 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.openapi.compiler;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+
+/**
+ * A tag interface indicating that the compiler will generate Java sources.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface SourceGeneratingCompiler extends GeneratingCompiler {
+  
+  /**
+   * Used by make subsystem to obtain the file that should be opened in the editor instead of generated file if there were errors found 
+   * while compiling the generated file
+   * 
+   *
+   * @param context current compile context
+   * @param module the module to which the generated file was attributed
+   * @param outputRoot the compiler output root 
+   * @param generatedFile - the file that was generated by this compiler
+   * @return substituting file that should be used for navigation in UI or null if no such substitutor is available 
+   *
+   */
+  VirtualFile getPresentableFile(CompileContext context, Module module, VirtualFile outputRoot, VirtualFile generatedFile);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java
new file mode 100644
index 0000000..e8d07f1
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceInstrumentingCompiler.java
@@ -0,0 +1,25 @@
+/*
+ * 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.openapi.compiler;
+
+/**
+ * A tag interface indicating that the compiler will instrument java sources.
+ * This affects the order of compiler calls:
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> Validator
+ */
+public interface SourceInstrumentingCompiler extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java
new file mode 100644
index 0000000..8392fdc
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/SourceProcessingCompiler.java
@@ -0,0 +1,19 @@
+/*
+ * 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.openapi.compiler;
+
+public interface SourceProcessingCompiler extends FileProcessingCompiler, IntermediateOutputCompiler {
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java
new file mode 100644
index 0000000..d5841ba
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TimestampValidityState.java
@@ -0,0 +1,65 @@
+/*
+ * 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.openapi.compiler;
+
+import java.io.DataInput;
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * A simple implementation of ValidityState that is enough for most cases.
+ * The file is considered modified if its timestamp is changed.
+ */
+public final class TimestampValidityState implements ValidityState {
+  private final long myTimestamp;
+
+  /**
+   * Creates a validity state with the specified timestamp.
+   *
+   * @param timestamp the timestamp for the validity state.
+   */
+  public TimestampValidityState(long timestamp) {
+    myTimestamp = timestamp;
+  }
+
+  public boolean equalsTo(ValidityState otherState) {
+    if (!(otherState instanceof TimestampValidityState)) {
+      return false;
+    }
+    return myTimestamp == ((TimestampValidityState)otherState).myTimestamp;
+  }
+
+  /**
+   * Saves the validity state to the specified stream.
+   *
+   * @param out
+   * @throws IOException if the stream write fails.
+   */
+  public void save(DataOutput out) throws IOException {
+    out.writeLong(myTimestamp);
+  }
+
+  /**
+   * Loads the validity state from the specified stream.
+   *
+   * @param is the stream to load the validity state from.
+   * @throws IOException if the stream read fails.
+   * @since 5.0.2
+   */
+  public static TimestampValidityState load(DataInput is) throws IOException {
+    return new TimestampValidityState(is.readLong());
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.java
new file mode 100644
index 0000000..3c56f8d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/TranslatingCompiler.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.openapi.compiler;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Chunk;
+
+import java.util.Collection;
+
+/**
+ * A tag interface indicating that the compiler will translate one type of files into another (e.g. .java -> .class).
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface TranslatingCompiler extends Compiler {
+
+  /**
+   * Defines a single file compiled by the compiler.
+   */
+  interface OutputItem {
+    /**
+     * Returns the path to the output file.
+     *
+     * @return absolute path of the output file ('/' slashes used)
+     */
+    String getOutputPath();
+
+    /**
+     * Returns the path to the source file.
+     *
+     * @return the source file to be compiled
+     */
+    VirtualFile getSourceFile();
+  }
+
+  interface OutputSink {
+    /**
+     *
+     * @param outputRoot output directory
+     * @param items output items that were successfully compiled.
+     * @param filesToRecompile virtual files that should be considered as "modified" next time compilation is invoked.
+     */
+    void add(String outputRoot, Collection<OutputItem> items, VirtualFile[] filesToRecompile);
+  }
+
+
+  /**
+   * Checks if the compiler can compile the specified file.
+   *
+   * @param file    the file to check.
+   * @param context the context for the current compile operation.
+   * @return true if can compile the file, false otherwise. If the method returns false, <code>file</code>
+   *         will not be included in the list of files passed to {@link #compile(CompileContext,Chunk<Module>,com.intellij.openapi.vfs.VirtualFile[], com.intellij.openapi.compiler.TranslatingCompiler.OutputSink)}.
+   */
+  boolean isCompilableFile(VirtualFile file, CompileContext context);
+
+  /**
+   * Compiles the specified files.
+   *
+   * @param context the context for the current compile operation.
+   * @param moduleChunk contains modules that form a cycle. If project module graph has no cycles, a chunk corresponds to a single module
+   * @param files   the source files to compile that correspond to the module chunk
+   * @param sink storage that accepts compiler output results
+   */
+  void compile(CompileContext context, Chunk<Module> moduleChunk, VirtualFile[] files, OutputSink sink);
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java
new file mode 100644
index 0000000..560ef8a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/Validator.java
@@ -0,0 +1,26 @@
+/*
+ * 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.openapi.compiler;
+
+/**
+ * A tag interface indicating that the compiler will perform any validation on the files in given compile scope.
+ * Error/Warning messages should be added to the CompileContext object.
+ * This affects the order of compiler calls.
+ * The sequence in which compilers are called:
+ * SourceGeneratingCompiler -> SourceInstrumentingCompiler -> TranslatingCompiler ->  ClassInstrumentingCompiler -> ClassPostProcessingCompiler -> PackagingCompiler -> Validator
+ */
+public interface Validator extends FileProcessingCompiler {
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java
new file mode 100644
index 0000000..65d12e6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityState.java
@@ -0,0 +1,41 @@
+/*
+ * 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.openapi.compiler;
+
+import java.io.DataOutput;
+import java.io.IOException;
+
+/**
+ * Instances of this class are associated with the files processed by compilers.
+ * A file is considered modified if currently associated ValidityState differs from the previously stored ValiditySate for this file.
+ */
+public interface ValidityState {
+  /**
+   * Compares this validity state to other ValidityState.
+   *
+   * @param otherState the state to compare with.
+   * @return true if states can be considered equal, false otherwise.
+   */
+  boolean equalsTo(ValidityState otherState);
+  /**
+   * Invoked by make subsystem in order to store the state.
+   *
+   * @param out the output to which the state should be stored.
+   * @throws IOException if the save operation failed because of an I/O error.
+   * @see TimestampValidityState#load(java.io.DataInputStream)
+   */
+  void save(DataOutput out) throws IOException;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.java
new file mode 100644
index 0000000..626f8db
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ValidityStateFactory.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.openapi.compiler;
+
+import java.io.DataInput;
+import java.io.IOException;
+
+/**
+ * A factory for creating {@link ValidityState} objects.
+ */
+public interface ValidityStateFactory {
+  /**
+   * Used for deserialization of ValidityState objects from compiler internal caches.
+   * @see ValidityState
+   * @param in
+   */ 
+  ValidityState createValidityState(DataInput in) throws IOException;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java
new file mode 100644
index 0000000..0f40216
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/ex/CompilerPathsEx.java
@@ -0,0 +1,125 @@
+/*
+ * 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.openapi.compiler.ex;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.compiler.CompilerPaths;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.progress.ProgressManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileManager;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.containers.OrderedSet;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Set;
+
+public class CompilerPathsEx extends CompilerPaths {
+  public static final Key<Boolean> CLEAR_ALL_OUTPUTS_KEY = Key.create("_should_clear_all_outputs_");
+
+  public static File getZippedOutputPath(Project project, String outputDirectoryPath) {
+    final File outputDir = new File(outputDirectoryPath);
+    return new File(getZipStoreDirectory(project), "_" + outputDir.getName() + Integer.toHexString(outputDirectoryPath.hashCode()) + ".zip");
+  }
+
+  public static File getZipStoreDirectory(Project project) {
+    return new File(getCompilerSystemDirectory(project), ".zip");
+  }
+
+  public static class FileVisitor {
+    protected void accept(final VirtualFile file, final String fileRoot, final String filePath) {
+      if (file.isDirectory()) {
+        acceptDirectory(file, fileRoot, filePath);
+      }
+      else {
+        acceptFile(file, fileRoot, filePath);
+      }
+    }
+
+    protected void acceptFile(VirtualFile file, String fileRoot, String filePath) {
+    }
+
+    protected void acceptDirectory(final VirtualFile file, final String fileRoot, final String filePath) {
+      ProgressManager.checkCanceled();
+      final VirtualFile[] children = file.getChildren();
+      for (final VirtualFile child : children) {
+        final String name = child.getName();
+        final String _filePath;
+        final StringBuilder buf = StringBuilderSpinAllocator.alloc();
+        try {
+          buf.append(filePath).append("/").append(name);
+          _filePath = buf.toString();
+        }
+        finally {
+          StringBuilderSpinAllocator.dispose(buf);
+        }
+        accept(child, fileRoot, _filePath);
+      }
+    }
+  }
+
+  public static void visitFiles(final Collection<VirtualFile> directories, final FileVisitor visitor) {
+    for (final VirtualFile outputDir : directories) {
+      ApplicationManager.getApplication().runReadAction(new Runnable() {
+        public void run() {
+          final String path = outputDir.getPath();
+          visitor.accept(outputDir, path, path);
+        }
+      });
+    }
+  }
+
+  public static String[] getOutputPaths(Module[] modules) {
+    final Set<String> outputPaths = new OrderedSet<String>();
+    for (Module module : modules) {
+      final CompilerModuleExtension compilerModuleExtension = CompilerModuleExtension.getInstance(module);
+      if (compilerModuleExtension == null) {
+        continue;
+      }
+      String outputPathUrl = compilerModuleExtension.getCompilerOutputUrl();
+      if (outputPathUrl != null) {
+        outputPaths.add(VirtualFileManager.extractPath(outputPathUrl).replace('/', File.separatorChar));
+      }
+
+      String outputPathForTestsUrl = compilerModuleExtension.getCompilerOutputUrlForTests();
+      if (outputPathForTestsUrl != null) {
+        outputPaths.add(VirtualFileManager.extractPath(outputPathForTestsUrl).replace('/', File.separatorChar));
+      }
+    }
+    return ArrayUtil.toStringArray(outputPaths);
+  }
+
+  public static VirtualFile[] getOutputDirectories(final Module[] modules) {
+    final Set<VirtualFile> dirs = new OrderedSet<VirtualFile>();
+    for (Module module : modules) {
+      final VirtualFile outputDir = getModuleOutputDirectory(module, false);
+      if (outputDir != null) {
+        dirs.add(outputDir);
+      }
+      VirtualFile testsOutputDir = getModuleOutputDirectory(module, true);
+      if (testsOutputDir != null) {
+        dirs.add(testsOutputDir);
+      }
+    }
+    return VfsUtil.toVirtualFileArray(dirs);
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java
new file mode 100644
index 0000000..148e152
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstruction.java
@@ -0,0 +1,22 @@
+/*
+ * 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.openapi.compiler.make;
+
+public interface BuildInstruction {
+  String getOutputRelativePath();
+
+  boolean accept(BuildInstructionVisitor visitor) throws Exception;
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java
new file mode 100644
index 0000000..6ae9b33
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildInstructionVisitor.java
@@ -0,0 +1,26 @@
+/*
+ * 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.openapi.compiler.make;
+
+
+public abstract class BuildInstructionVisitor {
+  public boolean visitInstruction(BuildInstruction instruction) throws Exception {
+    return true;
+  }
+  public boolean visitFileCopyInstruction(FileCopyInstruction instruction) throws Exception {
+    return visitInstruction(instruction);
+  }
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.java
new file mode 100644
index 0000000..48022b6
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipant.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.openapi.compiler.make;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead
+ */
+public abstract class BuildParticipant {
+  public static final BuildParticipant[] EMPTY_ARRAY = new BuildParticipant[0];
+
+  @Nullable
+  public abstract Artifact createArtifact(CompileContext context);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java
new file mode 100644
index 0000000..a0f46da
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildParticipantProvider.java
@@ -0,0 +1,35 @@
+/*
+ * 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.openapi.compiler.make;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.module.Module;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ *
+ * @deprecated use interfaces from {@link com.intellij.openapi.compiler.Compiler}'s hierarchy instead
+ */
+public abstract class BuildParticipantProvider {
+  public static final ExtensionPointName<BuildParticipantProvider> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.compiler.buildParticipantProvider");
+
+
+  public abstract Collection<? extends BuildParticipant> getParticipants(Module module);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java
new file mode 100644
index 0000000..ad30291
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/BuildRecipe.java
@@ -0,0 +1,30 @@
+/*
+ * 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.openapi.compiler.make;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+@Deprecated
+public interface BuildRecipe {
+  void addInstruction(BuildInstruction instruction);
+
+  boolean visitInstructions(BuildInstructionVisitor visitor, boolean reverseOrder);
+  boolean visitInstructionsWithExceptions(BuildInstructionVisitor visitor, boolean reverseOrder) throws Exception;
+
+  void addFileCopyInstruction(@NotNull File file, boolean isDirectory, String outputRelativePath);
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.java
new file mode 100644
index 0000000..4109410
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/FileCopyInstruction.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.openapi.compiler.make;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public interface FileCopyInstruction extends BuildInstruction {
+  File getFile();
+
+  boolean isDirectory();
+
+}
\ No newline at end of file
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java
new file mode 100644
index 0000000..3f645d0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/ManifestBuilder.java
@@ -0,0 +1,44 @@
+/*
+ * 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.openapi.compiler.make;
+
+import com.intellij.openapi.application.ApplicationNamesInfo;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.jar.Attributes;
+
+public class ManifestBuilder {
+  @NonNls private static final String NAME = "Created-By";
+  private static final Attributes.Name CREATED_BY = new Attributes.Name(NAME);
+
+  private ManifestBuilder() {
+  }
+
+  public static void setGlobalAttributes(Attributes mainAttributes) {
+    setVersionAttribute(mainAttributes);
+    setIfNone(mainAttributes, CREATED_BY, ApplicationNamesInfo.getInstance().getFullProductName());
+  }
+
+  public static void setVersionAttribute(Attributes mainAttributes) {
+    setIfNone(mainAttributes, Attributes.Name.MANIFEST_VERSION, "1.0");
+  }
+
+  private static void setIfNone(Attributes mainAttributes, Attributes.Name attrName, String value) {
+    if (mainAttributes.getValue(attrName) == null) {
+      mainAttributes.put(attrName, value);
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html
new file mode 100644
index 0000000..839258a
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/make/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 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.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for extending the build process.
+</body></html>
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.java
new file mode 100644
index 0000000..b752e8e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludeEntryDescription.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.
+ */
+
+/**
+ * created at Jan 3, 2002
+ * @author Jeka
+ */
+package com.intellij.openapi.compiler.options;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointer;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import org.jetbrains.annotations.Nullable;
+
+public class ExcludeEntryDescription implements Disposable {
+  private boolean myIsFile;
+  private boolean myIncludeSubdirectories;
+  private VirtualFilePointer myFilePointer;
+  private final Disposable myParentDisposable;
+
+  public ExcludeEntryDescription(String url, boolean includeSubdirectories, boolean isFile, Disposable parent) {
+    myParentDisposable = parent;
+    myFilePointer = VirtualFilePointerManager.getInstance().create(url, parent, null);
+    myIncludeSubdirectories = includeSubdirectories;
+    myIsFile = isFile;
+  }
+
+  public ExcludeEntryDescription(VirtualFile virtualFile, boolean includeSubdirectories, boolean isFile, Disposable parent) {
+    this(virtualFile.getUrl(), includeSubdirectories, isFile, parent);
+  }
+
+  public ExcludeEntryDescription copy(Disposable parent) {
+    return new ExcludeEntryDescription(getUrl(), myIncludeSubdirectories, myIsFile,parent);
+  }
+
+  public void setPresentableUrl(String newUrl) {
+    myFilePointer = VirtualFilePointerManager.getInstance().create(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(newUrl)), myParentDisposable, null);
+    final VirtualFile file = getVirtualFile();
+    if (file != null) {
+      myIsFile = !file.isDirectory();
+    }
+  }
+
+  public boolean isFile() {
+    return myIsFile;
+  }
+
+  public String getUrl() {
+    return myFilePointer.getUrl();
+  }
+
+  public String getPresentableUrl() {
+    return myFilePointer.getPresentableUrl();
+  }
+
+  public boolean isIncludeSubdirectories() {
+    return myIncludeSubdirectories;
+  }
+
+  public void setIncludeSubdirectories(boolean includeSubdirectories) {
+    myIncludeSubdirectories = includeSubdirectories;
+  }
+
+  @Nullable
+  public VirtualFile getVirtualFile() {
+    return myFilePointer.getFile();
+  }
+
+  public boolean isValid() {
+    return myFilePointer.isValid();
+  }
+
+  public boolean equals(Object obj) {
+    if(!(obj instanceof ExcludeEntryDescription)) {
+      return false;
+    }
+    ExcludeEntryDescription entryDescription = (ExcludeEntryDescription)obj;
+    if(entryDescription.myIsFile != myIsFile) {
+      return false;
+    }
+    if(entryDescription.myIncludeSubdirectories != myIncludeSubdirectories) {
+      return false;
+    }
+    return Comparing.equal(entryDescription.getUrl(), getUrl());
+  }
+
+  public int hashCode() {
+    int result = (myIsFile ? 1 : 0);
+    result = 31 * result + (myIncludeSubdirectories ? 1 : 0);
+    result = 31 * result + getUrl().hashCode();
+    return result;
+  }
+
+  public void dispose() {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java
new file mode 100644
index 0000000..6a2cd87
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfigurable.java
@@ -0,0 +1,385 @@
+/*
+ * 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.openapi.compiler.options;
+
+import com.intellij.compiler.CompilerConfiguration;
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.compiler.CompilerBundle;
+import com.intellij.openapi.fileChooser.FileChooser;
+import com.intellij.openapi.fileChooser.FileChooserDescriptor;
+import com.intellij.openapi.options.UnnamedConfigurable;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vcs.FileStatusManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import javax.swing.table.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.ArrayList;
+import java.util.Arrays;
+
+public class ExcludedEntriesConfigurable implements UnnamedConfigurable {
+  private final Project myProject;
+  private final ArrayList<ExcludeEntryDescription> myExcludeEntryDescriptions = new ArrayList<ExcludeEntryDescription>();
+  private final FileChooserDescriptor myDescriptor;
+  private final ExcludedEntriesConfiguration myConfiguration;
+  private ExcludedEntriesPanel myExcludedEntriesPanel;
+
+  public ExcludedEntriesConfigurable(Project project) {
+    this(project, new FileChooserDescriptor(true, true, false, false, false, true),
+         CompilerConfiguration.getInstance(project).getExcludedEntriesConfiguration());
+  }
+
+  public ExcludedEntriesConfigurable(Project project, FileChooserDescriptor descriptor, final ExcludedEntriesConfiguration configuration) {
+    myDescriptor = descriptor;
+    myConfiguration = configuration;
+    myProject = project;
+  }
+
+  public void reset() {
+    ExcludeEntryDescription[] descriptions = myConfiguration.getExcludeEntryDescriptions();
+    disposeMyDescriptions();
+    for (ExcludeEntryDescription description : descriptions) {
+      myExcludeEntryDescriptions.add(description.copy(myProject));
+    }
+    ((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
+  }
+
+  public void addEntry(ExcludeEntryDescription description) {
+    myExcludeEntryDescriptions.add(description);
+    ((AbstractTableModel)myExcludedEntriesPanel.myExcludedTable.getModel()).fireTableDataChanged();
+  }
+
+  private void disposeMyDescriptions() {
+    for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+      Disposer.dispose(description);
+    }
+    myExcludeEntryDescriptions.clear();
+  }
+
+  public void apply() {
+    myConfiguration.removeAllExcludeEntryDescriptions();
+    for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+      myConfiguration.addExcludeEntryDescription(description.copy(myProject));
+    }
+    FileStatusManager.getInstance(myProject).fileStatusesChanged(); // refresh exclude from compile status
+  }
+
+  public boolean isModified() {
+    ExcludeEntryDescription[] excludeEntryDescriptions = myConfiguration.getExcludeEntryDescriptions();
+    if(excludeEntryDescriptions.length != myExcludeEntryDescriptions.size()) {
+      return true;
+    }
+    for(int i = 0; i < excludeEntryDescriptions.length; i++) {
+      ExcludeEntryDescription description = excludeEntryDescriptions[i];
+      if(!Comparing.equal(description, myExcludeEntryDescriptions.get(i))) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public JComponent createComponent() {
+    if (myExcludedEntriesPanel == null) {
+      myExcludedEntriesPanel = new ExcludedEntriesPanel();
+    }
+    return myExcludedEntriesPanel;
+  }
+
+  public void disposeUIResources() {
+    myExcludedEntriesPanel = null;
+  }
+
+  private class ExcludedEntriesPanel extends PanelWithButtons {
+    private JButton myRemoveButton;
+    private JBTable myExcludedTable;
+
+    public ExcludedEntriesPanel() {
+      initPanel();
+    }
+
+    protected String getLabelText(){
+      return null;
+    }
+
+    protected JButton[] createButtons(){
+      final JButton addButton = new JButton(IdeBundle.message("button.add"));
+      addButton.addActionListener(
+        new ActionListener() {
+          public void actionPerformed(ActionEvent e){
+            addPath(myDescriptor);
+          }
+        }
+      );
+
+      myRemoveButton = new JButton(IdeBundle.message("button.remove"));
+      myRemoveButton.addActionListener(
+        new ActionListener(){
+          public void actionPerformed(ActionEvent e){
+            removePaths();
+          }
+        }
+      );
+      myRemoveButton.setEnabled(false);
+      myRemoveButton.getModel().addChangeListener(new ChangeListener() {
+        public void stateChanged(ChangeEvent e) {
+          if (myExcludedTable.getSelectedRow() == -1) {
+            myRemoveButton.setEnabled(false);
+          }
+        }
+      });
+
+      return new JButton[]{/*addButton, myRemoveButton*/};
+    }
+
+    private void addPath(FileChooserDescriptor descriptor) {
+      int selected = -1 /*myExcludedTable.getSelectedRow() + 1*/;
+      if(selected < 0) {
+        selected = myExcludeEntryDescriptions.size();
+      }
+      int savedSelected = selected;
+      VirtualFile[] chosen = FileChooser.chooseFiles(descriptor, myProject, null);
+      for (final VirtualFile chosenFile : chosen) {
+        if (isFileExcluded(chosenFile)) {
+          continue;
+        }
+        ExcludeEntryDescription description;
+        if (chosenFile.isDirectory()) {
+          description = new ExcludeEntryDescription(chosenFile, true, false, myProject);
+        }
+        else {
+          description = new ExcludeEntryDescription(chosenFile, false, true, myProject);
+        }
+        myExcludeEntryDescriptions.add(selected, description);
+        selected++;
+      }
+      if (selected > savedSelected) { // actually added something
+        AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
+        model.fireTableRowsInserted(savedSelected, selected-1);
+        myExcludedTable.setRowSelectionInterval(savedSelected, selected - 1);
+      }
+    }
+
+    private boolean isFileExcluded(VirtualFile file) {
+      for (final ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+        final VirtualFile descriptionFile = description.getVirtualFile();
+        if (descriptionFile == null) {
+          continue;
+        }
+        if (file.equals(descriptionFile)) {
+          return true;
+        }
+      }
+      return false;
+    }
+
+    private void removePaths() {
+      int[] selected = myExcludedTable.getSelectedRows();
+      if(selected == null || selected.length <= 0) {
+        return;
+      }
+      if(myExcludedTable.isEditing()) {
+        TableCellEditor editor = myExcludedTable.getCellEditor();
+        if (editor != null) {
+          editor.stopCellEditing();
+        }
+      }
+      AbstractTableModel model = (AbstractTableModel)myExcludedTable.getModel();
+      Arrays.sort(selected);
+      int indexToSelect = selected[selected.length - 1];
+      int removedCount = 0;
+      for (int indexToRemove : selected) {
+        final int row = indexToRemove - removedCount;
+        ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+        Disposer.dispose(description);
+        myExcludeEntryDescriptions.remove(row);
+        model.fireTableRowsDeleted(row, row);
+        removedCount += 1;
+      }
+      if(indexToSelect >= myExcludeEntryDescriptions.size()) {
+        indexToSelect = myExcludeEntryDescriptions.size() - 1;
+      }
+      if(indexToSelect >= 0) {
+        myExcludedTable.setRowSelectionInterval(indexToSelect, indexToSelect);
+      }
+      myExcludedTable.requestFocus();
+    }
+
+    protected JComponent createMainComponent(){
+      final String[] names = {
+        CompilerBundle.message("exclude.from.compile.table.path.column.name"),
+        CompilerBundle.message("exclude.from.compile.table.recursively.column.name")
+      };
+      // Create a model of the data.
+      TableModel dataModel = new AbstractTableModel() {
+        public int getColumnCount() {
+          return names.length;
+        }
+
+        public int getRowCount() {
+          return myExcludeEntryDescriptions.size();
+        }
+
+        public Object getValueAt(int row, int col) {
+          ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+          if(col == 0) {
+            return description.getPresentableUrl();
+          }
+          if(col == 1) {
+            if(!description.isFile()) {
+              return description.isIncludeSubdirectories() ? Boolean.TRUE : Boolean.FALSE;
+            }
+            else {
+              return null;
+            }
+          }
+          return null;
+        }
+
+        public String getColumnName(int column) {
+          return names[column];
+        }
+
+        public Class getColumnClass(int c) {
+          if(c == 0) {
+            return String.class;
+          }
+          if(c == 1) {
+            return Boolean.class;
+          }
+          return null;
+        }
+
+        public boolean isCellEditable(int row, int col) {
+          if(col == 1) {
+            ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+            return !description.isFile();
+          }
+          return true;
+        }
+
+        public void setValueAt(Object aValue, int row, int col) {
+          ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+          if (col == 1) {
+            description.setIncludeSubdirectories(aValue.equals(Boolean.TRUE));
+          } else {
+            final String path = (String)aValue;
+            description.setPresentableUrl(path);
+          }
+        }
+      };
+
+      myExcludedTable = new JBTable(dataModel);
+      myExcludedTable.setEnableAntialiasing(true);
+
+      myExcludedTable.getEmptyText().setText(CompilerBundle.message("no.excludes"));
+      myExcludedTable.setPreferredScrollableViewportSize(new Dimension(300, myExcludedTable.getRowHeight() * 6));
+      myExcludedTable.setDefaultRenderer(Boolean.class, new BooleanRenderer());
+      myExcludedTable.setDefaultRenderer(Object.class, new MyObjectRenderer());
+      myExcludedTable.getColumn(names[0]).setPreferredWidth(350);
+      final int cbWidth = 15 + myExcludedTable.getTableHeader().getFontMetrics(myExcludedTable.getTableHeader().getFont()).stringWidth(names[1]);
+      final TableColumn cbColumn = myExcludedTable.getColumn(names[1]);
+      cbColumn.setPreferredWidth(cbWidth);
+      cbColumn.setMaxWidth(cbWidth);
+      myExcludedTable.getSelectionModel().setSelectionMode(ListSelectionModel.MULTIPLE_INTERVAL_SELECTION);
+      myExcludedTable.getSelectionModel().addListSelectionListener(new ListSelectionListener() {
+        public void valueChanged(ListSelectionEvent e) {
+          myRemoveButton.setEnabled(myExcludedTable.getSelectedRow() >= 0);
+        }
+      });
+      TableCellEditor editor = myExcludedTable.getDefaultEditor(String.class);
+      if(editor instanceof DefaultCellEditor) {
+        ((DefaultCellEditor)editor).setClickCountToStart(1);
+      }
+
+      return ToolbarDecorator.createDecorator(myExcludedTable)
+        .disableUpAction()
+        .disableDownAction()
+        .setAddAction(new AnActionButtonRunnable() {
+          @Override
+          public void run(AnActionButton anActionButton) {
+            addPath(myDescriptor);
+          }
+        })
+        .setRemoveAction(new AnActionButtonRunnable() {
+          @Override
+          public void run(AnActionButton anActionButton) {
+            removePaths();
+          }
+        }).createPanel();
+
+
+      //return ScrollPaneFactory.createScrollPane(myExcludedTable);
+    }
+  }
+
+  private static class BooleanRenderer extends JCheckBox implements TableCellRenderer {
+    private final JPanel myPanel = new JPanel();
+
+    public BooleanRenderer() {
+      setHorizontalAlignment(CENTER);
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected, boolean hasFocus,
+                                                   int row, int column) {
+      if(value == null) {
+        if(isSelected) {
+          myPanel.setBackground(table.getSelectionBackground());
+        }
+        else {
+          myPanel.setBackground(table.getBackground());
+        }
+        return myPanel;
+      }
+      if(isSelected) {
+        setForeground(table.getSelectionForeground());
+        super.setBackground(table.getSelectionBackground());
+      }
+      else {
+        setForeground(table.getForeground());
+        setBackground(table.getBackground());
+      }
+      setSelected(((Boolean)value).booleanValue());
+      return this;
+    }
+  }
+
+  private class MyObjectRenderer extends DefaultTableCellRenderer {
+    public MyObjectRenderer() {
+      setUI(new RightAlignedLabelUI());
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value, boolean isSelected, boolean hasFocus, int row, int column) {
+      final Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      final ExcludeEntryDescription description = myExcludeEntryDescriptions.get(row);
+      component.setForeground(!description.isValid() ? JBColor.RED : isSelected ? table.getSelectionForeground() : table.getForeground());
+      component.setBackground(isSelected ? table.getSelectionBackground() : table.getBackground());
+      return component;
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java
new file mode 100644
index 0000000..67e8745
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/options/ExcludedEntriesConfiguration.java
@@ -0,0 +1,145 @@
+/*
+ * 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.openapi.compiler.options;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.Collection;
+import java.util.LinkedHashSet;
+
+/**
+ * @author nik
+ */
+public class ExcludedEntriesConfiguration implements PersistentStateComponent<ExcludedEntriesConfiguration>, JDOMExternalizable, Disposable {
+  @NonNls private static final String FILE = "file";
+  @NonNls private static final String DIRECTORY = "directory";
+  @NonNls private static final String URL = "url";
+  @NonNls private static final String INCLUDE_SUBDIRECTORIES = "includeSubdirectories";
+  private final Collection<ExcludeEntryDescription> myExcludeEntryDescriptions = new LinkedHashSet<ExcludeEntryDescription>();
+  private ExcludeEntryDescription[] myCachedDescriptions = null;
+
+  public synchronized ExcludeEntryDescription[] getExcludeEntryDescriptions() {
+    if (myCachedDescriptions == null) {
+      myCachedDescriptions = myExcludeEntryDescriptions.toArray(new ExcludeEntryDescription[myExcludeEntryDescriptions.size()]);
+    }
+    return myCachedDescriptions;
+  }
+
+  public synchronized void addExcludeEntryDescription(ExcludeEntryDescription description) {
+    myExcludeEntryDescriptions.add(description);
+    myCachedDescriptions = null;
+  }
+
+  public synchronized void removeExcludeEntryDescription(ExcludeEntryDescription description) {
+    myExcludeEntryDescriptions.remove(description);
+    myCachedDescriptions = null;
+  }
+
+  public synchronized void removeAllExcludeEntryDescriptions() {
+    myExcludeEntryDescriptions.clear();
+    myCachedDescriptions = null;
+  }
+
+  public synchronized boolean containsExcludeEntryDescription(ExcludeEntryDescription description) {
+    return myExcludeEntryDescriptions.contains(description);
+  }
+
+  public void readExternal(final Element node) {
+    for (final Object o : node.getChildren()) {
+      Element element = (Element)o;
+      String url = element.getAttributeValue(URL);
+      if (url == null) continue;
+      if (FILE.equals(element.getName())) {
+        ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, false, true, this);
+        addExcludeEntryDescription(excludeEntryDescription);
+      }
+      if (DIRECTORY.equals(element.getName())) {
+        boolean includeSubdirectories = Boolean.parseBoolean(element.getAttributeValue(INCLUDE_SUBDIRECTORIES));
+        ExcludeEntryDescription excludeEntryDescription = new ExcludeEntryDescription(url, includeSubdirectories, false,this);
+        addExcludeEntryDescription(excludeEntryDescription);
+      }
+    }
+  }
+
+  public void writeExternal(final Element element) {
+    for (final ExcludeEntryDescription description : getExcludeEntryDescriptions()) {
+      if (description.isFile()) {
+        Element entry = new Element(FILE);
+        entry.setAttribute(URL, description.getUrl());
+        element.addContent(entry);
+      }
+      else {
+        Element entry = new Element(DIRECTORY);
+        entry.setAttribute(URL, description.getUrl());
+        entry.setAttribute(INCLUDE_SUBDIRECTORIES, Boolean.toString(description.isIncludeSubdirectories()));
+        element.addContent(entry);
+      }
+    }
+  }
+
+  public boolean isExcluded(VirtualFile virtualFile) {
+    for (final ExcludeEntryDescription entryDescription : getExcludeEntryDescriptions()) {
+      VirtualFile descriptionFile = entryDescription.getVirtualFile();
+      if (descriptionFile == null) {
+        continue;
+      }
+      if (entryDescription.isFile()) {
+        if (descriptionFile.equals(virtualFile)) {
+          return true;
+        }
+      }
+      else if (entryDescription.isIncludeSubdirectories()) {
+        if (VfsUtil.isAncestor(descriptionFile, virtualFile, false)) {
+          return true;
+        }
+      }
+      else {
+        if (virtualFile.isDirectory()) {
+          continue;
+        }
+        if (descriptionFile.equals(virtualFile.getParent())) {
+          return true;
+        }
+      }
+    }
+    return false;
+  }
+
+  public void dispose() {
+    for (ExcludeEntryDescription description : myExcludeEntryDescriptions) {
+      Disposer.dispose(description);
+    }
+  }
+
+  public ExcludedEntriesConfiguration getState() {
+    return this;
+  }
+
+  public void loadState(final ExcludedEntriesConfiguration state) {
+    for (ExcludeEntryDescription description : state.getExcludeEntryDescriptions()) {
+      addExcludeEntryDescription(description.copy(this));
+    }
+    Disposer.dispose(state);
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html b/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html
new file mode 100644
index 0000000..b938f8e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 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.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for invoking the compiler, listening to compilation events and implementing
+custom compilers or compilation steps.
+</body></html>
diff --git a/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java b/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java
new file mode 100644
index 0000000..64088c8
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/compiler/util/InspectionValidator.java
@@ -0,0 +1,95 @@
+/*
+ * 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.openapi.compiler.util;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInspection.InspectionToolProvider;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.CompileScope;
+import com.intellij.openapi.compiler.CompilerMessageCategory;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Map;
+
+/**
+ * @author peter
+ */
+public abstract class InspectionValidator {
+  public static final ExtensionPointName<InspectionValidator> EP_NAME = ExtensionPointName.create("com.intellij.compiler.inspectionValidator");
+  private final String myDescription;
+  private final String myProgressIndicatorText;
+  private final Class<? extends LocalInspectionTool>[] myInspectionToolClasses;
+
+  protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final Class<? extends LocalInspectionTool>... inspectionToolClasses) {
+    myDescription = description;
+    myProgressIndicatorText = progressIndicatorText;
+    myInspectionToolClasses = inspectionToolClasses;
+  }
+
+  protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final InspectionToolProvider provider) {
+    //noinspection unchecked
+    this(description, progressIndicatorText, provider.getInspectionClasses());
+  }
+
+  protected InspectionValidator(@NotNull final String description, @NotNull final String progressIndicatorText, final Class<? extends InspectionToolProvider> providerClass)
+    throws IllegalAccessException, InstantiationException {
+    this(description, progressIndicatorText, providerClass.newInstance());
+  }
+
+
+  public abstract boolean isAvailableOnScope(@NotNull CompileScope scope);
+
+  public abstract Collection<VirtualFile> getFilesToProcess(final Project project, final CompileContext context);
+
+  @NotNull
+  public Collection<? extends PsiElement> getDependencies(final PsiFile psiFile) {
+    return Collections.emptyList();
+  }
+
+  @NotNull
+  public Class<? extends LocalInspectionTool>[] getInspectionToolClasses(final CompileContext context) {
+    return myInspectionToolClasses;
+  }
+
+  public final String getDescription() {
+    return myDescription;
+  }
+
+  public final String getProgressIndicatorText() {
+    return myProgressIndicatorText;
+  }
+
+  public CompilerMessageCategory getCategoryByHighlightDisplayLevel(@NotNull final HighlightDisplayLevel severity, @NotNull final VirtualFile virtualFile, @NotNull final CompileContext context) {
+    if (severity == HighlightDisplayLevel.ERROR) return CompilerMessageCategory.ERROR;
+    if (severity == HighlightDisplayLevel.WARNING) return CompilerMessageCategory.WARNING;
+    return CompilerMessageCategory.INFORMATION;
+  }
+
+  @NotNull
+  public Map<ProblemDescriptor, HighlightDisplayLevel> checkAdditionally(PsiFile file) {
+    return Collections.emptyMap();
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java b/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java
new file mode 100644
index 0000000..dc1ff57
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/openapi/deployment/DeploymentUtil.java
@@ -0,0 +1,131 @@
+/*
+ * 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.openapi.deployment;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.compiler.make.BuildRecipe;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.StringBuilderSpinAllocator;
+import com.intellij.util.descriptors.ConfigFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.FileFilter;
+import java.io.IOException;
+import java.util.Set;
+
+public abstract class DeploymentUtil {
+  public static DeploymentUtil getInstance() {
+    return ServiceManager.getService(DeploymentUtil.class);
+  }
+
+  public abstract void copyFile(@NotNull File fromFile,
+                                @NotNull File toFile,
+                                @NotNull CompileContext context,
+                                @Nullable Set<String> writtenPaths,
+                                @Nullable FileFilter fileFilter) throws IOException;
+
+  @Deprecated
+  public abstract boolean addItemsRecursively(@NotNull BuildRecipe items, @NotNull File root, String outputRelativePath);
+
+  public static String trimForwardSlashes(@NotNull String path) {
+    while (path.length() != 0 && (path.charAt(0) == '/' || path.charAt(0) == File.separatorChar)) {
+      path = path.substring(1);
+    }
+    return path;
+  }
+
+  public abstract void reportDeploymentDescriptorDoesNotExists(ConfigFile descriptor, CompileContext context, Module module);
+
+  public static String concatPaths(String... paths) {
+    final StringBuilder builder = new StringBuilder();
+    for (String path : paths) {
+      if (path.length() == 0) continue;
+
+      final int len = builder.length();
+      if (len > 0 && builder.charAt(len - 1) != '/' && builder.charAt(len - 1) != File.separatorChar) {
+        builder.append('/');
+      }
+      builder.append(len != 0 ? trimForwardSlashes(path) : path);
+    }
+    return builder.toString();
+  }
+
+  public static String appendToPath(@NotNull String basePath, @NotNull String relativePath) {
+    final boolean endsWithSlash = StringUtil.endsWithChar(basePath, '/') || StringUtil.endsWithChar(basePath, '\\');
+    final boolean startsWithSlash = StringUtil.startsWithChar(relativePath, '/') || StringUtil.startsWithChar(relativePath, '\\');
+    String tail;
+    if (endsWithSlash && startsWithSlash) {
+      tail = trimForwardSlashes(relativePath);
+    }
+    else if (!endsWithSlash && !startsWithSlash && basePath.length() > 0 && relativePath.length() > 0) {
+      tail = "/" + relativePath;
+    }
+    else {
+      tail = relativePath;
+    }
+    return basePath + tail;
+  }
+
+  @Deprecated
+  public abstract BuildRecipe createBuildRecipe();
+
+  @Nullable
+  public abstract String getConfigFileErrorMessage(ConfigFile configFile);
+
+  /**
+   * @deprecated use {@link com.intellij.openapi.util.io.FileUtil#getRelativePath}
+   */
+  @Nullable
+  public static String getRelativePath(@NotNull String basePath, @NotNull final String filePath) {
+    if (basePath.equals(filePath)) return "";
+    if (!basePath.endsWith(File.separator)) basePath += File.separatorChar;
+
+    int len = 0;
+    int lastSeparatorIndex = 0; // need this for cases like this: base="/temp/abcde/baseDir" and file="/temp/ab"
+    while (len < filePath.length() && len < basePath.length() && filePath.charAt(len) == basePath.charAt(len)) {
+      if (basePath.charAt(len) == File.separatorChar) {
+        lastSeparatorIndex = len;
+      }
+      len++;
+    }
+
+    if (len == 0) {
+      return null;
+    }
+    final StringBuilder relativePath = StringBuilderSpinAllocator.alloc();
+    try {
+      for (int i=len; i < basePath.length(); i++) {
+        if (basePath.charAt(i) == File.separatorChar) {
+          relativePath.append("..");
+          relativePath.append(File.separatorChar);
+        }
+      }
+      relativePath.append(filePath.substring(lastSeparatorIndex + 1));
+
+      return relativePath.toString();
+    }
+    finally {
+      StringBuilderSpinAllocator.dispose(relativePath);
+    }
+  }
+
+  public abstract void checkConfigFile(final ConfigFile descriptor, final CompileContext compileContext, final Module module);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.java
new file mode 100644
index 0000000..8155cf0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/Artifact.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.packaging.artifacts;
+
+import com.intellij.openapi.util.UserDataHolder;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface Artifact extends UserDataHolder {
+  @NotNull
+  ArtifactType getArtifactType();
+
+  String getName();
+
+  boolean isBuildOnMake();
+
+  @NotNull
+  CompositePackagingElement<?> getRootElement();
+
+  @Nullable
+  String getOutputPath();
+
+  Collection<? extends ArtifactPropertiesProvider> getPropertiesProviders();
+
+  ArtifactProperties<?> getProperties(@NotNull ArtifactPropertiesProvider propertiesProvider);
+
+  @Nullable
+  VirtualFile getOutputFile();
+
+  @Nullable
+  String getOutputFilePath();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java
new file mode 100644
index 0000000..34b91f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactAdapter.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ArtifactAdapter implements ArtifactListener {
+  public void artifactAdded(@NotNull Artifact artifact) {
+  }
+
+  public void artifactRemoved(@NotNull Artifact artifact) {
+  }
+
+  public void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName) {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java
new file mode 100644
index 0000000..88dddea
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactListener.java
@@ -0,0 +1,33 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface ArtifactListener extends EventListener {
+
+  void artifactAdded(@NotNull Artifact artifact);
+
+  void artifactRemoved(@NotNull Artifact artifact);
+
+  void artifactChanged(@NotNull Artifact artifact, @NotNull String oldName);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.java
new file mode 100644
index 0000000..9610bfa
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactManager.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.packaging.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.util.messages.Topic;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactManager implements ArtifactModel {
+  public static final Topic<ArtifactListener> TOPIC = Topic.create("artifacts changes", ArtifactListener.class);
+  public static final Comparator<Artifact> ARTIFACT_COMPARATOR = new Comparator<Artifact>() {
+    public int compare(Artifact o1, Artifact o2) {
+      return o1.getName().compareToIgnoreCase(o2.getName());
+    }
+  };
+
+  public static ArtifactManager getInstance(@NotNull Project project) {
+    return project.getComponent(ArtifactManager.class);
+  }
+
+  public abstract Artifact[] getSortedArtifacts();
+
+  public abstract ModifiableArtifactModel createModifiableModel();
+
+  public abstract PackagingElementResolvingContext getResolvingContext();
+
+  @NotNull
+  public abstract Artifact addArtifact(@NonNls @NotNull String name, @NotNull ArtifactType type, @Nullable CompositePackagingElement<?> root);
+
+  public abstract void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath,
+                                              @NotNull Collection<? extends PackagingElement<?>> elements);
+
+  public abstract void addElementsToDirectory(@NotNull Artifact artifact, @NotNull String relativePath,
+                                              @NotNull PackagingElement<?> element);
+
+  public abstract ModificationTracker getModificationTracker();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java
new file mode 100644
index 0000000..91f3ae7
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactModel.java
@@ -0,0 +1,43 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactModel {
+  @NotNull
+  Artifact[] getArtifacts();
+
+  @Nullable
+  Artifact findArtifact(@NotNull String name);
+
+  @NotNull
+  Artifact getArtifactByOriginal(@NotNull Artifact artifact);
+
+  @NotNull
+  Artifact getOriginalArtifact(@NotNull Artifact artifact);
+
+  Collection<? extends Artifact> getArtifactsByType(@NotNull ArtifactType type);
+
+  List<? extends Artifact> getAllArtifactsIncludingInvalid();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java
new file mode 100644
index 0000000..ee1ed1c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointer.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.artifacts;
+
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ArtifactPointer {
+
+  @NotNull
+  String getArtifactName();
+
+  @Nullable
+  Artifact getArtifact();
+
+  @NotNull
+  String getArtifactName(@NotNull ArtifactModel artifactModel);
+
+  @Nullable
+  Artifact findArtifact(@NotNull ArtifactModel artifactModel);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java
new file mode 100644
index 0000000..c5f32f4
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPointerManager.java
@@ -0,0 +1,35 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.components.ServiceManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPointerManager {
+  public static ArtifactPointerManager getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, ArtifactPointerManager.class);
+  }
+
+  public abstract ArtifactPointer createPointer(@NotNull String name);
+
+  public abstract ArtifactPointer createPointer(@NotNull Artifact artifact);
+
+  public abstract ArtifactPointer createPointer(@NotNull Artifact artifact, @NotNull ArtifactModel artifactModel);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java
new file mode 100644
index 0000000..65d590b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactProperties.java
@@ -0,0 +1,36 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.compiler.CompileContext;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.ArtifactPropertiesEditor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactProperties<S> implements PersistentStateComponent<S> {
+
+  public void onBuildStarted(@NotNull Artifact artifact, @NotNull CompileContext compileContext) {
+  }
+
+  public void onBuildFinished(@NotNull Artifact artifact, @NotNull CompileContext compileContext) {
+  }
+
+  public abstract ArtifactPropertiesEditor createEditor(@NotNull ArtifactEditorContext context);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java
new file mode 100644
index 0000000..bb3c162
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactPropertiesProvider.java
@@ -0,0 +1,59 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPropertiesProvider {
+  public static final ExtensionPointName<ArtifactPropertiesProvider> EP_NAME = ExtensionPointName.create("com.intellij.packaging.artifactPropertiesProvider");
+  private final String myId;
+
+  protected ArtifactPropertiesProvider(@NotNull @NonNls String id) {
+    myId = id;
+  }
+
+  public final String getId() {
+    return myId;
+  }
+
+  public boolean isAvailableFor(@NotNull ArtifactType type) {
+    return true;
+  } 
+
+  @NotNull 
+  public abstract ArtifactProperties<?> createProperties(@NotNull ArtifactType artifactType);
+
+  public static ArtifactPropertiesProvider[] getProviders() {
+    return Extensions.getExtensions(EP_NAME);
+  }
+
+  @Nullable
+  public static ArtifactPropertiesProvider findById(@NotNull @NonNls String id) {
+    for (ArtifactPropertiesProvider provider : getProviders()) {
+      if (provider.getId().equals(id)) {
+        return provider;
+      }
+    }
+    return null;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java
new file mode 100644
index 0000000..f1b8827
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactTemplate.java
@@ -0,0 +1,78 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactTemplate {
+
+  public abstract String getPresentableName();
+
+  /**
+   * @deprecated override {@link #createArtifact()} instead
+   */
+  @Deprecated
+  public CompositePackagingElement<?> createRootElement(@NotNull String artifactName) {
+    return null;
+  }
+
+  /**
+   * @deprecated override {@link #createArtifact()} instead
+   */
+  @Deprecated
+  @NotNull
+  public String suggestArtifactName() {
+    return "unnamed";
+  }
+
+  @Nullable
+  public NewArtifactConfiguration createArtifact() {
+    final String name = suggestArtifactName();
+    return new NewArtifactConfiguration(createRootElement(name), name, null);
+  }
+
+  public void setUpArtifact(@NotNull Artifact artifact, @NotNull NewArtifactConfiguration configuration) {
+  }
+
+  public static class NewArtifactConfiguration {
+    private final CompositePackagingElement<?> myRootElement;
+    private final String myArtifactName;
+    private final ArtifactType myArtifactType;
+
+    public NewArtifactConfiguration(CompositePackagingElement<?> rootElement, String artifactName, ArtifactType artifactType) {
+      myRootElement = rootElement;
+      myArtifactName = artifactName;
+      myArtifactType = artifactType;
+    }
+
+    public CompositePackagingElement<?> getRootElement() {
+      return myRootElement;
+    }
+
+    public String getArtifactName() {
+      return myArtifactName;
+    }
+
+    public ArtifactType getArtifactType() {
+      return myArtifactType;
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java
new file mode 100644
index 0000000..130d0e2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ArtifactType.java
@@ -0,0 +1,100 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import com.intellij.packaging.ui.ArtifactProblemsHolder;
+import com.intellij.packaging.ui.PackagingSourceItem;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactType {
+  public static final ExtensionPointName<ArtifactType> EP_NAME = ExtensionPointName.create("com.intellij.packaging.artifactType");
+  private final String myId;
+  private final String myTitle;
+
+  protected ArtifactType(@NonNls String id, String title) {
+    myId = id;
+    myTitle = title;
+  }
+
+  public final String getId() {
+    return myId;
+  }
+
+  public String getPresentableName() {
+    return myTitle;
+  }                                
+
+  @NotNull
+  public abstract Icon getIcon();
+
+  @Nullable
+  public String getDefaultPathFor(@NotNull PackagingSourceItem sourceItem) {
+    return getDefaultPathFor(sourceItem.getKindOfProducedElements());
+  }
+
+  @Nullable
+  public abstract String getDefaultPathFor(@NotNull PackagingElementOutputKind kind);
+
+  public boolean isSuitableItem(@NotNull PackagingSourceItem sourceItem) {
+    return true;
+  }
+
+  public static ArtifactType[] getAllTypes() {
+    return Extensions.getExtensions(EP_NAME);
+  }
+
+  @Nullable
+  public static ArtifactType findById(@NotNull @NonNls String id) {
+    for (ArtifactType type : getAllTypes()) {
+      if (id.equals(type.getId())) {
+        return type;
+      }
+    }
+    return null;
+  }
+
+  @NotNull
+  public abstract CompositePackagingElement<?> createRootElement(@NotNull String artifactName);
+
+  @NotNull
+  public List<? extends ArtifactTemplate> getNewArtifactTemplates(@NotNull PackagingElementResolvingContext context) {
+    return Collections.emptyList();
+  }
+
+  public void checkRootElement(@NotNull CompositePackagingElement<?> rootElement, @NotNull Artifact artifact, @NotNull ArtifactProblemsHolder manager) {
+  }
+
+  @Nullable
+  public List<? extends PackagingElement<?>> getSubstitution(@NotNull Artifact artifact, @NotNull PackagingElementResolvingContext context,
+                                                             @NotNull ArtifactType parentType) {
+    return null;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.java
new file mode 100644
index 0000000..0b3f245
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifact.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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ModifiableArtifact extends Artifact {
+
+  void setBuildOnMake(boolean enabled);
+
+  void setOutputPath(String outputPath);
+
+  void setName(@NotNull String name);
+
+  void setRootElement(CompositePackagingElement<?> root);
+
+  void setProperties(ArtifactPropertiesProvider provider, ArtifactProperties<?> properties);
+
+  void setArtifactType(@NotNull ArtifactType selected);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java
new file mode 100644
index 0000000..5e6172f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/artifacts/ModifiableArtifactModel.java
@@ -0,0 +1,51 @@
+/*
+ * 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.packaging.artifacts;
+
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ModifiableArtifactModel extends ArtifactModel {
+
+  @NotNull
+  ModifiableArtifact addArtifact(final @NotNull String name, @NotNull ArtifactType artifactType);
+
+  @NotNull
+  ModifiableArtifact addArtifact(final @NotNull String name, @NotNull ArtifactType artifactType, CompositePackagingElement<?> rootElement);
+
+  void removeArtifact(@NotNull Artifact artifact);
+
+  @NotNull
+  ModifiableArtifact getOrCreateModifiableArtifact(@NotNull Artifact artifact);
+
+  @Nullable
+  Artifact getModifiableCopy(Artifact artifact);
+
+  void addListener(@NotNull ArtifactListener listener);
+
+  void removeListener(@NotNull ArtifactListener listener);
+
+
+  boolean isModified();
+
+  void commit();
+
+  void dispose();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java b/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java
new file mode 100644
index 0000000..fc0eb03
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/AntCopyInstructionCreator.java
@@ -0,0 +1,42 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.compiler.ant.Tag;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface AntCopyInstructionCreator {
+
+  @NotNull
+  Tag createDirectoryContentCopyInstruction(@NotNull String dirPath);
+
+  @NotNull
+  Tag createFileCopyInstruction(@NotNull String filePath, String outputFileName);
+
+  @NotNull
+  AntCopyInstructionCreator subFolder(@NotNull String directoryName);
+
+  @Nullable
+  Generator createSubFolderCommand(@NotNull String directoryName);
+
+  @NotNull
+  Generator createExtractedDirectoryInstruction(@NotNull String jarPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java
new file mode 100644
index 0000000..46864f3
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactAntGenerationContext.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.GenerationOptions;
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public interface ArtifactAntGenerationContext {
+
+  void runBeforeCurrentArtifact(Generator generator);
+
+  void runBeforeBuild(Generator generator);
+
+  void runAfterBuild(Generator generator);
+
+  String createNewTempFileProperty(@NonNls String basePropertyName, @NonNls String fileName);
+
+  String getModuleOutputPath(@NonNls String moduleName);
+
+  String getModuleTestOutputPath(@NonNls String moduleName);
+
+  String getSubstitutedPath(@NonNls String path);
+
+  String getArtifactOutputProperty(@NotNull Artifact artifact);
+
+  Project getProject();
+
+  GenerationOptions getGenerationOptions();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java
new file mode 100644
index 0000000..6ee65f5
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactIncrementalCompilerContext.java
@@ -0,0 +1,22 @@
+/*
+ * 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.packaging.elements;
+
+/**
+ * @author nik
+ */
+public interface ArtifactIncrementalCompilerContext {
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java
new file mode 100644
index 0000000..37da8ba
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ArtifactRootElement.java
@@ -0,0 +1,32 @@
+/*
+ * 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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactRootElement<S> extends CompositePackagingElement<S> {
+  protected ArtifactRootElement(PackagingElementType type) {
+    super(type);
+  }
+
+  @Override
+  public boolean isEqualTo(@NotNull PackagingElement<?> element) {
+    return false;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java
new file mode 100644
index 0000000..5a09569
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElement.java
@@ -0,0 +1,72 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.ArrayList;
+import java.util.Collections;
+
+/**
+ * @author nik
+ */
+public abstract class ComplexPackagingElement<S> extends PackagingElement<S> {
+  protected ComplexPackagingElement(PackagingElementType type) {
+    super(type);
+  }
+
+  @Override
+  public List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                          @NotNull ArtifactAntGenerationContext generationContext,
+                                                          @NotNull ArtifactType artifactType) {
+    final List<? extends PackagingElement<?>> substitution = getSubstitution(resolvingContext, artifactType);
+    if (substitution == null) {
+      return Collections.emptyList();
+    }
+
+    final List<Generator> fileSets = new ArrayList<Generator>();
+    for (PackagingElement<?> element : substitution) {
+      fileSets.addAll(element.computeAntInstructions(resolvingContext, creator, generationContext, artifactType));
+    }
+    return fileSets;
+  }
+
+  @Override
+  public void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                                     @NotNull PackagingElementResolvingContext resolvingContext,
+                                                     @NotNull ArtifactIncrementalCompilerContext compilerContext, @NotNull ArtifactType artifactType) {
+    final List<? extends PackagingElement<?>> substitution = getSubstitution(resolvingContext, artifactType);
+    if (substitution == null) return;
+
+    for (PackagingElement<?> element : substitution) {
+      element.computeIncrementalCompilerInstructions(creator, resolvingContext, compilerContext,
+                                                     getArtifactTypeForSubstitutedElements(resolvingContext, artifactType));
+    }
+  }
+
+  protected ArtifactType getArtifactTypeForSubstitutedElements(PackagingElementResolvingContext resolvingContext, ArtifactType artifactType) {
+    return artifactType;
+  }
+
+
+  @Nullable
+  public abstract List<? extends PackagingElement<?>> getSubstitution(@NotNull PackagingElementResolvingContext context, @NotNull ArtifactType artifactType);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java
new file mode 100644
index 0000000..7fd3d99
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ComplexPackagingElementType.java
@@ -0,0 +1,39 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.ModificationTracker;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ComplexPackagingElementType<E extends ComplexPackagingElement<?>> extends PackagingElementType<E> {
+  protected ComplexPackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+    super(id, presentableName);
+  }
+
+  public abstract String getShowContentActionText();
+
+  @Nullable
+  public ModificationTracker getAllSubstitutionsModificationTracker(@NotNull Project project) {
+    return null;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java
new file mode 100644
index 0000000..fbfa5e0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElement.java
@@ -0,0 +1,140 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class CompositePackagingElement<S> extends PackagingElement<S> implements RenameablePackagingElement {
+  private final List<PackagingElement<?>> myChildren = new ArrayList<PackagingElement<?>>();
+  private List<PackagingElement<?>> myUnmodifiableChildren;
+
+  protected CompositePackagingElement(PackagingElementType type) {
+    super(type);
+  }
+
+  public <T extends PackagingElement<?>> T addOrFindChild(@NotNull T child) {
+    for (PackagingElement<?> element : myChildren) {
+      if (element.isEqualTo(child)) {
+        if (element instanceof CompositePackagingElement) {
+          final List<PackagingElement<?>> children = ((CompositePackagingElement<?>)child).getChildren();
+          ((CompositePackagingElement<?>)element).addOrFindChildren(children);
+        }
+        //noinspection unchecked
+        return (T) element;
+      }
+    }
+    myChildren.add(child);
+    return child;
+  }
+
+  public void addFirstChild(@NotNull PackagingElement<?> child) {
+    myChildren.add(0, child);
+    for (int i = 1; i < myChildren.size(); i++) {
+      PackagingElement<?> element = myChildren.get(i);
+      if (element.isEqualTo(child)) {
+        if (element instanceof CompositePackagingElement<?>) {
+          ((CompositePackagingElement<?>)child).addOrFindChildren(((CompositePackagingElement<?>)element).getChildren());
+        }
+        myChildren.remove(i);
+        break;
+      }
+    }
+  }
+
+  public List<? extends PackagingElement<?>> addOrFindChildren(Collection<? extends PackagingElement<?>> children) {
+    List<PackagingElement<?>> added = new ArrayList<PackagingElement<?>>();
+    for (PackagingElement<?> child : children) {
+      added.add(addOrFindChild(child));
+    }
+    return added;
+  }
+
+  @Nullable
+  public PackagingElement<?> moveChild(int index, int direction) {
+    int target = index + direction;
+    if (0 <= index && index < myChildren.size() && 0 <= target && target < myChildren.size()) {
+      final PackagingElement<?> element1 = myChildren.get(index);
+      final PackagingElement<?> element2 = myChildren.get(target);
+      myChildren.set(index, element2);
+      myChildren.set(target, element1);
+      return element1;
+    }
+    return null;
+  }
+
+  public void removeChild(@NotNull PackagingElement<?> child) {
+    myChildren.remove(child);
+  }
+
+  public void removeChildren(@NotNull Collection<? extends PackagingElement<?>> children) {
+    myChildren.removeAll(children);
+  }
+
+  @NotNull
+  public List<PackagingElement<?>> getChildren() {
+    if (myUnmodifiableChildren == null) {
+      myUnmodifiableChildren = Collections.unmodifiableList(myChildren);
+    }
+    return myUnmodifiableChildren;
+  }
+
+  public boolean canBeRenamed() {
+    return true;
+  }
+
+  protected List<? extends Generator> computeChildrenGenerators(PackagingElementResolvingContext resolvingContext,
+                                                                final AntCopyInstructionCreator copyInstructionCreator,
+                                                                final ArtifactAntGenerationContext generationContext, ArtifactType artifactType) {
+    final List<Generator> generators = new ArrayList<Generator>();
+    for (PackagingElement<?> child : myChildren) {
+      generators.addAll(child.computeAntInstructions(resolvingContext, copyInstructionCreator, generationContext, artifactType));
+    }
+    return generators;
+  }
+
+  protected void computeChildrenInstructions(@NotNull IncrementalCompilerInstructionCreator creator,
+                                             @NotNull PackagingElementResolvingContext resolvingContext,
+                                             @NotNull ArtifactIncrementalCompilerContext compilerContext, ArtifactType artifactType) {
+    for (PackagingElement<?> child : myChildren) {
+      child.computeIncrementalCompilerInstructions(creator, resolvingContext, compilerContext, artifactType);
+    }
+  }
+
+  public void removeAllChildren() {
+    myChildren.clear();
+  }
+
+  @Nullable
+  public CompositePackagingElement<?> findCompositeChild(@NotNull String name) {
+    for (PackagingElement<?> child : myChildren) {
+      if (child instanceof CompositePackagingElement && name.equals(((CompositePackagingElement)child).getName())) {
+        return (CompositePackagingElement)child;
+      }
+    }
+    return null;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java
new file mode 100644
index 0000000..92af59d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/CompositePackagingElementType.java
@@ -0,0 +1,49 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class CompositePackagingElementType<E extends CompositePackagingElement<?>> extends PackagingElementType<E> {
+  protected CompositePackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+    super(id, presentableName);
+  }
+
+  @Override
+  public boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact) {
+    return true;
+  }
+
+
+  @Nullable
+  public abstract CompositePackagingElement<?> createComposite(CompositePackagingElement<?> parent, @Nullable String baseName, @NotNull ArtifactEditorContext context);
+
+  @NotNull
+  public List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact, @NotNull CompositePackagingElement<?> parent) {
+    final PackagingElement<?> composite = createComposite(parent, null, context);
+    return composite != null ? Collections.singletonList(composite) : Collections.<E>emptyList();
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java b/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java
new file mode 100644
index 0000000..7c1f1d0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/IncrementalCompilerInstructionCreator.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface IncrementalCompilerInstructionCreator {
+
+  void addFileCopyInstruction(@NotNull VirtualFile file, @NotNull String outputFileName);
+
+  void addDirectoryCopyInstructions(@NotNull VirtualFile directory);
+
+  void addDirectoryCopyInstructions(@NotNull VirtualFile directory, @Nullable PackagingFileFilter filter);
+
+  IncrementalCompilerInstructionCreator subFolder(@NotNull String directoryName);
+
+  IncrementalCompilerInstructionCreator archive(@NotNull String archiveFileName);
+
+  IncrementalCompilerInstructionCreator subFolderByRelativePath(@NotNull String relativeDirectoryPath);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java
new file mode 100644
index 0000000..599c07f
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/ManifestFileProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2011 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.packaging.elements;
+
+import com.intellij.packaging.artifacts.ArtifactType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ManifestFileProvider {
+  @Nullable
+  List<String> getClasspathFromManifest(@NotNull CompositePackagingElement<?> archiveRoot, @NotNull ArtifactType artifactType);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java
new file mode 100644
index 0000000..377616b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElement.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.compiler.ant.Generator;
+import com.intellij.openapi.components.PersistentStateComponent;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPresentation;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElement<S> implements PersistentStateComponent<S> {
+  private final PackagingElementType myType;
+
+  protected PackagingElement(PackagingElementType type) {
+    myType = type;
+  }
+
+  public abstract PackagingElementPresentation createPresentation(@NotNull ArtifactEditorContext context);
+
+  public final PackagingElementType getType() {
+    return myType;
+  }
+
+  public abstract List<? extends Generator> computeAntInstructions(@NotNull PackagingElementResolvingContext resolvingContext, @NotNull AntCopyInstructionCreator creator,
+                                                                   @NotNull ArtifactAntGenerationContext generationContext,
+                                                                   @NotNull ArtifactType artifactType);
+
+  public abstract void computeIncrementalCompilerInstructions(@NotNull IncrementalCompilerInstructionCreator creator, @NotNull PackagingElementResolvingContext resolvingContext,
+                                                              @NotNull ArtifactIncrementalCompilerContext compilerContext,
+                                                              @NotNull ArtifactType artifactType);
+
+  public abstract boolean isEqualTo(@NotNull PackagingElement<?> element);
+
+  @NotNull
+  public PackagingElementOutputKind getFilesKind(PackagingElementResolvingContext context) {
+    return PackagingElementOutputKind.OTHER;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java
new file mode 100644
index 0000000..d6574fa
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementFactory.java
@@ -0,0 +1,124 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactPointer;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementFactory {
+
+  public static PackagingElementFactory getInstance() {
+    return ServiceManager.getService(PackagingElementFactory.class);
+  }
+
+  @NotNull
+  public abstract ArtifactRootElement<?> createArtifactRootElement();
+
+  @NotNull
+  public abstract CompositePackagingElement<?> createDirectory(@NotNull @NonNls String directoryName);
+
+  @NotNull
+  public abstract CompositePackagingElement<?> createArchive(@NotNull @NonNls String archiveFileName);
+
+  public abstract PackagingElement<?> createFileCopy(@NotNull String filePath, @Nullable String outputFileName);
+
+  @NotNull
+  public abstract PackagingElement<?> createModuleOutput(@NotNull String moduleName, @NotNull Project project);
+
+  @NotNull
+  public abstract PackagingElement<?> createModuleOutput(@NotNull Module module);
+
+  @NotNull
+  public abstract PackagingElement<?> createTestModuleOutput(@NotNull Module module);
+
+  @NotNull
+  public abstract List<? extends PackagingElement<?>> createLibraryElements(@NotNull Library library);
+
+  @NotNull
+  public abstract PackagingElement<?> createArtifactElement(@NotNull ArtifactPointer artifactPointer, @NotNull Project project);
+
+  @NotNull
+  public abstract PackagingElement<?> createArtifactElement(@NotNull Artifact artifact, @NotNull Project project);
+
+  @NotNull
+  public abstract PackagingElement<?> createLibraryFiles(@NotNull String libraryName, @NotNull String level, String moduleName);
+
+
+  @NotNull
+  public abstract PackagingElement<?> createDirectoryCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath);
+
+  @NotNull
+  public abstract PackagingElement<?> createExtractedDirectoryWithParentDirectories(@NotNull String jarPath, @NotNull String pathInJar,
+                                                                                    @NotNull String relativeOutputPath);
+
+  @NotNull
+  public abstract PackagingElement<?> createExtractedDirectory(@NotNull VirtualFile jarEntry);
+
+  @NotNull
+  public abstract PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath,
+                                                                          @Nullable String outputFileName);
+  
+  @NotNull
+  public abstract PackagingElement<?> createFileCopyWithParentDirectories(@NotNull String filePath, @NotNull String relativeOutputPath);
+  
+
+  @NotNull
+  public abstract CompositePackagingElement<?> getOrCreateDirectory(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath);
+
+  @NotNull
+  public abstract CompositePackagingElement<?> getOrCreateArchive(@NotNull CompositePackagingElement<?> parent, @NotNull String relativePath);
+
+  public abstract void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath,
+                                   final String outputFileName);
+
+  public abstract void addFileCopy(@NotNull CompositePackagingElement<?> root, @NotNull String outputDirectoryPath, @NotNull String sourceFilePath);
+
+  @NotNull
+  public abstract PackagingElement<?> createParentDirectories(@NotNull String relativeOutputPath, @NotNull PackagingElement<?> element);
+
+
+  @NotNull
+  public abstract List<? extends PackagingElement<?>> createParentDirectories(@NotNull String relativeOutputPath, @NotNull List<? extends PackagingElement<?>> elements);
+
+  @NotNull
+  
+  public abstract CompositePackagingElementType<?>[] getCompositeElementTypes();
+
+  @Nullable
+  public abstract PackagingElementType<?> findElementType(String id);
+
+  @NotNull
+  public abstract PackagingElementType<?>[] getNonCompositeElementTypes();
+
+  @NotNull
+  public abstract PackagingElementType[] getAllElementTypes();
+
+  @NotNull
+  public abstract ComplexPackagingElementType<?>[] getComplexElementTypes();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.java
new file mode 100644
index 0000000..4ba42df
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementOutputKind.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.packaging.elements;
+
+/**
+ * @author nik
+ */
+public class PackagingElementOutputKind {
+  public static final PackagingElementOutputKind DIRECTORIES_WITH_CLASSES = new PackagingElementOutputKind(true, false);
+  public static final PackagingElementOutputKind JAR_FILES = new PackagingElementOutputKind(false, true);
+  public static final PackagingElementOutputKind OTHER = new PackagingElementOutputKind(false, false);
+  private final boolean myContainsDirectoriesWithClasses;
+  private final boolean myContainsJarFiles;
+
+  public PackagingElementOutputKind(boolean containsDirectoriesWithClasses, boolean containsJarFiles) {
+    myContainsDirectoriesWithClasses = containsDirectoriesWithClasses;
+    myContainsJarFiles = containsJarFiles;
+  }
+
+  public boolean containsDirectoriesWithClasses() {
+    return myContainsDirectoriesWithClasses;
+  }
+
+  public boolean containsJarFiles() {
+    return myContainsJarFiles;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java
new file mode 100644
index 0000000..a033d3c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementResolvingContext.java
@@ -0,0 +1,47 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.ui.configuration.FacetsProvider;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.packaging.artifacts.ArtifactModel;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface PackagingElementResolvingContext {
+  @NotNull
+  Project getProject();
+
+  @NotNull
+  ArtifactModel getArtifactModel();
+
+  @NotNull
+  ModulesProvider getModulesProvider();
+
+  @NotNull
+  FacetsProvider getFacetsProvider();
+
+  @Nullable
+  Library findLibrary(@NotNull String level, @NotNull String libraryName);
+
+  @NotNull
+  ManifestFileProvider getManifestFileProvider();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java
new file mode 100644
index 0000000..48cc0c2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingElementType.java
@@ -0,0 +1,79 @@
+/*
+ * 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.packaging.elements;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.project.Project;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.ui.ArtifactEditorContext;
+import com.intellij.packaging.ui.PackagingElementPropertiesPanel;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementType<E extends PackagingElement<?>> {
+  public static final ExtensionPointName<PackagingElementType> EP_NAME = ExtensionPointName.create("com.intellij.packaging.elementType");
+  private final String myId;
+  private final String myPresentableName;
+
+  protected PackagingElementType(@NotNull @NonNls String id, @NotNull String presentableName) {
+    myId = id;
+    myPresentableName = presentableName;
+  }
+
+  public final String getId() {
+    return myId;
+  }
+
+  public String getPresentableName() {
+    return myPresentableName;
+  }
+
+  @Nullable
+  public Icon getCreateElementIcon() {
+    return null;
+  }
+
+  public abstract boolean canCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact);
+
+  @NotNull 
+  public abstract List<? extends PackagingElement<?>> chooseAndCreate(@NotNull ArtifactEditorContext context, @NotNull Artifact artifact,
+                                                                      @NotNull CompositePackagingElement<?> parent);
+
+  @NotNull
+  public abstract E createEmpty(@NotNull Project project);
+
+  protected static <T extends PackagingElementType<?>> T getInstance(final Class<T> aClass) {
+    for (PackagingElementType type : Extensions.getExtensions(EP_NAME)) {
+      if (aClass.isInstance(type)) {
+        return aClass.cast(type);
+      }
+    }
+    throw new AssertionError();
+  }
+
+  @Nullable
+  public PackagingElementPropertiesPanel createElementPropertiesPanel(@NotNull E element, @NotNull ArtifactEditorContext context) {
+    return null;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java
new file mode 100644
index 0000000..363b391
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/PackagingFileFilter.java
@@ -0,0 +1,30 @@
+/*
+ * 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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.compiler.CompileContext;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingFileFilter {
+
+  public abstract boolean accept(@NotNull VirtualFile virtualFile, @NotNull CompileContext context);
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.java b/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.java
new file mode 100644
index 0000000..d34fb89
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/elements/RenameablePackagingElement.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.packaging.elements;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface RenameablePackagingElement {
+  String getName();
+
+  boolean canBeRenamed();
+
+  void rename(@NotNull String newName);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java
new file mode 100644
index 0000000..144bda2
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditor.java
@@ -0,0 +1,38 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactEditor {
+  void updateLayoutTree();
+
+  void putLibraryIntoDefaultLocation(@NotNull Library library);
+
+  void putModuleIntoDefaultLocation(@NotNull Module module);
+
+  void addToClasspath(CompositePackagingElement<?> element, List<String> classpath);
+
+  boolean isDisposed();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java
new file mode 100644
index 0000000..7ede5be
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactEditorContext.java
@@ -0,0 +1,80 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.facet.Facet;
+import com.intellij.openapi.module.ModifiableModuleModel;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.packaging.artifacts.ArtifactType;
+import com.intellij.packaging.artifacts.ModifiableArtifactModel;
+import com.intellij.packaging.elements.CompositePackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactEditorContext extends PackagingElementResolvingContext {
+
+  void queueValidation();
+
+  @NotNull
+  ArtifactType getArtifactType();
+
+  @NotNull
+  ModifiableArtifactModel getOrCreateModifiableArtifactModel();
+
+  @Nullable
+  ModifiableModuleModel getModifiableModuleModel();
+
+  @NotNull
+  ModifiableRootModel getOrCreateModifiableRootModel(@NotNull Module module);
+
+  @Nullable
+  ManifestFileConfiguration getManifestFile(CompositePackagingElement<?> element, ArtifactType artifactType);
+
+
+  CompositePackagingElement<?> getRootElement(@NotNull Artifact artifact);
+
+  void editLayout(@NotNull Artifact artifact, Runnable runnable);
+
+  ArtifactEditor getOrCreateEditor(Artifact originalArtifact);
+
+  ArtifactEditor getThisArtifactEditor();
+
+  void selectArtifact(@NotNull Artifact artifact);
+
+  void selectFacet(@NotNull Facet<?> facet);
+
+  void selectModule(@NotNull Module module);
+
+  void selectLibrary(@NotNull Library library);
+
+
+  List<Artifact> chooseArtifacts(List<? extends Artifact> artifacts, String title);
+
+  List<Module> chooseModules(List<Module> modules, final String title);
+
+  List<Library> chooseLibraries(String title);
+
+  Artifact getArtifact();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.java
new file mode 100644
index 0000000..851ce79
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemQuickFix.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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactProblemQuickFix {
+  private String myActionName;
+
+  protected ArtifactProblemQuickFix() {
+    this("Fix");
+  }
+
+  protected ArtifactProblemQuickFix(String actionName) {
+    myActionName = actionName;
+  }
+
+  public String getActionName() {
+    return myActionName;
+  }
+
+  public abstract void performFix(ArtifactEditorContext artifactEditorContext);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java
new file mode 100644
index 0000000..abe8229
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactProblemsHolder.java
@@ -0,0 +1,39 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementResolvingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public interface ArtifactProblemsHolder {
+  @NotNull
+  PackagingElementResolvingContext getContext();
+
+  void registerError(@NotNull String message, @NotNull String problemTypeId);
+
+  void registerError(@NotNull String message, @NotNull String problemTypeId, @Nullable List<PackagingElement<?>> pathToPlace,
+                     @NotNull ArtifactProblemQuickFix... quickFixes);
+
+  void registerWarning(@NotNull String message, @NotNull String problemTypeId, @Nullable List<PackagingElement<?>> pathToPlace,
+                       @NotNull ArtifactProblemQuickFix... quickFixes);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
new file mode 100644
index 0000000..220b079
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.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.packaging.ui;
+
+import com.intellij.openapi.options.UnnamedConfigurable;
+
+/**
+ * @author nik
+ */
+public abstract class ArtifactPropertiesEditor implements UnnamedConfigurable {
+  public static final String VALIDATION_TAB = "Validation";  
+  public static final String POST_PROCESSING_TAB = "Post-processing";
+  public static final String PRE_PROCESSING_TAB = "Pre-processing";
+
+  public abstract String getTabName();
+
+  public abstract void apply();
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.java
new file mode 100644
index 0000000..116d68d
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ManifestFileConfiguration.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.packaging.ui;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.ArrayList;
+
+/**
+ * @author nik
+ */
+public class ManifestFileConfiguration {
+  private final boolean myWritable;
+  private List<String> myClasspath = new ArrayList<String>();
+  private String myMainClass;
+  private String myManifestFilePath;
+
+  public ManifestFileConfiguration(@NotNull ManifestFileConfiguration configuration) {
+    myWritable = configuration.isWritable();
+    myClasspath.addAll(configuration.getClasspath());
+    myMainClass = configuration.getMainClass();
+    myManifestFilePath = configuration.getManifestFilePath();
+  }
+
+  public ManifestFileConfiguration(@NotNull String manifestFilePath, @Nullable List<String> classpath, @Nullable String mainClass, boolean isWritable) {
+    myWritable = isWritable;
+    if (classpath != null) {
+      myClasspath.addAll(classpath);
+    }
+    myMainClass = mainClass;
+    myManifestFilePath = manifestFilePath;
+  }
+
+  public List<String> getClasspath() {
+    return myClasspath;
+  }
+
+  public boolean isWritable() {
+    return myWritable;
+  }
+
+  public void setClasspath(List<String> classpath) {
+    myClasspath = classpath;
+  }
+
+  public String getMainClass() {
+    return myMainClass;
+  }
+
+  public void setMainClass(String mainClass) {
+    myMainClass = mainClass;
+  }
+
+  public String getManifestFilePath() {
+    return myManifestFilePath;
+  }
+
+  public void setManifestFilePath(String manifestFilePath) {
+    myManifestFilePath = manifestFilePath;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ManifestFileConfiguration)) return false;
+
+    ManifestFileConfiguration that = (ManifestFileConfiguration)o;
+
+    if (!myClasspath.equals(that.myClasspath)) return false;
+    if (myMainClass != null ? !myMainClass.equals(that.myMainClass) : that.myMainClass != null) return false;
+    if (myManifestFilePath != null ? !myManifestFilePath.equals(that.myManifestFilePath) : that.myManifestFilePath != null) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    throw new UnsupportedOperationException();
+  }
+
+  public void addToClasspath(List<String> classpath) {
+    for (String path : classpath) {
+      if (!myClasspath.contains(path)) {
+        myClasspath.add(path);
+      }
+    }
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.java
new file mode 100644
index 0000000..d26375c
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPresentation.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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementPresentation extends TreeNodePresentation {
+
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.java
new file mode 100644
index 0000000..739677e
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementPropertiesPanel.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.packaging.ui;
+
+import com.intellij.openapi.options.UnnamedConfigurable;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingElementPropertiesPanel implements UnnamedConfigurable {
+
+  public abstract void apply();
+
+  public void disposeUIResources() {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java
new file mode 100644
index 0000000..f193e9b
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingElementWeights.java
@@ -0,0 +1,33 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public class PackagingElementWeights {
+  public static final int ARTIFACT = 100;
+  public static final int DIRECTORY = 50;
+  public static final int DIRECTORY_COPY = 40;
+  public static final int EXTRACTED_DIRECTORY = 39;
+  public static final int LIBRARY = 30;
+  public static final int MODULE = 20;
+  public static final int FACET = 10;
+  public static final int FILE_COPY = 0;
+
+  private PackagingElementWeights() {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java
new file mode 100644
index 0000000..d222876
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItem.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.ui;
+
+import com.intellij.packaging.elements.PackagingElement;
+import com.intellij.packaging.elements.PackagingElementOutputKind;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingSourceItem {
+  private boolean myProvideElements;
+
+  protected PackagingSourceItem() {
+    this(true);
+  }
+
+  protected PackagingSourceItem(boolean provideElements) {
+    myProvideElements = provideElements;
+  }
+
+  @Override
+  public abstract boolean equals(Object obj);
+
+  @Override
+  public abstract int hashCode();
+
+  public abstract SourceItemPresentation createPresentation(@NotNull ArtifactEditorContext context);
+
+  @NotNull
+  public abstract List<? extends PackagingElement<?>> createElements(@NotNull ArtifactEditorContext context);
+
+  public boolean isProvideElements() {
+    return myProvideElements;
+  }
+
+  @NotNull
+  public PackagingElementOutputKind getKindOfProducedElements() {
+    return PackagingElementOutputKind.OTHER;
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.java b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.java
new file mode 100644
index 0000000..3b62092
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/PackagingSourceItemsProvider.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.packaging.ui;
+
+import com.intellij.packaging.artifacts.Artifact;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public abstract class PackagingSourceItemsProvider {
+  public static final ExtensionPointName<PackagingSourceItemsProvider> EP_NAME = ExtensionPointName.create("com.intellij.packaging.sourceItemProvider");
+
+  @NotNull
+  public abstract Collection<? extends PackagingSourceItem> getSourceItems(@NotNull ArtifactEditorContext editorContext, @NotNull Artifact artifact,
+                                                                                 @Nullable PackagingSourceItem parent);
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java
new file mode 100644
index 0000000..42de0ae
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemPresentation.java
@@ -0,0 +1,22 @@
+/*
+ * 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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public abstract class SourceItemPresentation extends TreeNodePresentation {
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.java b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.java
new file mode 100644
index 0000000..70e05f0
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/SourceItemWeights.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.packaging.ui;
+
+/**
+ * @author nik
+ */
+public class SourceItemWeights {
+  public static final int ARTIFACTS_GROUP_WEIGHT = 200;
+  public static final int ARTIFACT_WEIGHT = 150;
+  public static final int MODULE_GROUP_WEIGHT = 100;
+  public static final int MODULE_WEIGHT = 50;
+  public static final int MODULE_OUTPUT_WEIGHT = 30;
+  public static final int LIBRARY_WEIGHT = 10;
+
+  private SourceItemWeights() {
+  }
+}
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java b/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java
new file mode 100644
index 0000000..96fe6ec
--- /dev/null
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/TreeNodePresentation.java
@@ -0,0 +1,57 @@
+/*
+ * 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.packaging.ui;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import com.intellij.ide.projectView.PresentationData;
+import com.intellij.ui.SimpleTextAttributes;
+
+/**
+ * @author nik
+ */
+public abstract class TreeNodePresentation {
+  public abstract String getPresentableName();
+
+  public String getSearchName() {
+    return getPresentableName();
+  }
+
+  public abstract void render(@NotNull PresentationData presentationData, SimpleTextAttributes mainAttributes,
+                              SimpleTextAttributes commentAttributes);
+
+  @Nullable
+  public String getTooltipText() {
+    return null;
+  }
+
+  public boolean canNavigateToSource() {
+    return false;
+  }
+
+  public void navigateToSource() {
+  }
+
+  /**
+   * @deprecated this method is not used and will be removed in the future
+   */
+  @Nullable
+  public Object getSourceObject() {
+    return null;
+  }
+
+  public abstract int getWeight();
+}
