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;
+  }
+}
