Snapshot 9e6329d622cc9649c9c035f28faddc29564a5b7a from idea/133.696 of git://git.jetbrains.org/idea/community.git

9e6329d: IDEA-119035 Select All shortcut for any table on mac with Darcula
7642139: [log] IDEA-116322 Fix structure filter for multiple roots
5fe2227: [log] refactor: group filters before passing them to providers
a9bda1e: Problem with several users in log filter fixed.
bb353f3: [log] IDEA-119316 Fix "go to commit" if there are log filters
2825dd1: IDEA-119467 Gradle: auto discovery of buildSrc project (cherry picked from commit 3cb5420)
ca05350: Gradle: respect the order of dependencies (cherry picked from commit dca7107)
8a1d099: IDEA-115351 Idea UI hangs after performing Move Module to group (cherry picked from commit 673ed61) [r=Maxim.Mossienko]
9f006a4: NPE fix (cherry picked from commit 1eb3644)
2089b40: Gradle: test data fix (cherry picked from commit c864c4b)
6208324: IDEA-119336 Gradle build files: build.gradle scripts are checkout from Perforce even if the file is not changed (cherry picked from commit 3234c0b)
d1d776c: IDEA-119467 Gradle: auto discovery of buildSrc project IDEA-98930 IDEA does not resolve dependencies in Gradle buildSrc/ project (cherry picked from commit 0982afc)
6f6c403: Gradle: dependencies scope merge and sourceSets type handling updated related issues: IDEA-119365 Gradle import does not respect model customisations IDEA-118280 Gradle import: IDEA detect java folder as a resource folder IDEA-117668 IDEA v13 spontaneously changes additional test source root to source root (cherry picked from commit 68bfa5e)
a7f9d6f: Gradle: respect module build classpath for build scripts resolving review: http://crucible.labs.intellij.net/cru/CR-IC-4038
742c670: isEAP = false, time to release 13.0.2
3a5cfc7: add profiling parameters to the right part of the classpath (has been broken after Launcher was introduced)
ca42a66: fixed empty headers and import (dependant in language level) for qt, gtk... skeletons.
ba68876: update copyright in artworks
7c12cb3: IDEA-119619 Settings / Language Injections: project level XML tag injection loses Sub-Tags value on IDE restart
f7bd727: don't call robot on alt on Windows and when window is inactive (cherry picked from commit 0fe2cac)
8b62b1e: add WinXP definition (cherry picked from commit dde1494)
62c528a: consume Alt events on WinXP in default handler to avoid WindowsRootPaneUI.AltProcessor (cherry picked from commit f14aab9)
20c7faa: support table decoration on IntelliJ laf (cherry picked from commit 04425c9)
7dc2f34: IDEA-118211 (cherry picked from commit 55ee980) [r=Peter.Gromov]
b15f65d: fixed PY-11823 Test Runner detection in settings doesn't pick up just installed test runner
7a2bec9: Fixed dedent in case of tabs ( PY-10120).
56b5f81: Python keywords extracted. Cleanup.
f195253: Fixed test data to satisfy PEP8.
6b6bbc1: Make right par indent=none in import statement (PY-9075).
6a39911: Make continuation indent after continuation in indenting statement (PY-9573).
cf19307: Test for PY-9573
fb5186fa: Handle 'mode' as a keyword argument to open() as well
27a4d26: Detect text or binary I/O in pathlib.Path.open()
a5600e3: Return instance types for instance types of superclasses
f56e9b1: fixed PY-11837 nose test runner errors while formatting a test error
7420dd6: Nullity annotations
97ffd71: fixed test data
d0eb725: fixed test data
326185d: generator: do not drop the whole module in case there are broken __repr__ defined
982687a: performance for generator: Split big generated modules (like _Gtk, PyQt) into smaller ones
af679a5: Simplified always true condition
3174b9c: Extracted PyClassTypeImpl.findProperty()
777280e: Added 'inherited' parameter to PyClass.findProperty()
d5d8b23: Python skeletons class members provider now can provide new overridden members
6775ed3: Fixed code insight for returning 'self' in base class methods (PY-10977, PY-11413)
d4c641f: Fix formatter to add two blank lines between declarations with comment (PY-9923).
9c8134a: add field after super call
37813c6: Revert "Detect SQL fragments only in the beginning of string literals" (PY-11828)
9d5973f: Use default charset as python console encoding.
7fed382: Added Python 3.4 modules to the stdlib modules list
c772246: Don't ignore unused attributes of empty constructors (PY-7527)
91ae6bf: Fixed NPE in PyUnusedLocalInspectionVisitor.visitPyCallExpression()
464ae1c: fixed PY-11800 Parameter unfilled false positive for decorators with '*' arguments.
e3ec532: fixed test data
31bb1dd: fixed add field declaration to the beginning of __init__
2910f7d: fixed EA-52897 - CCE: ImportToggleAliasIntention$.execute
cca9133: fixed EA-53046 - NPE: PyExtractMethodUtil.a
2fcf769: fixed quickdoc test
fcf329f: fixed editing test
859c599: fixed testdata
ab7782a: fixed PY-11765 @ivar and @type in class documentation cause PyUnresolvedReferences inspection to file
8303e4f: IDEA-112303 Tool Windows Quick Access button: impossible to select item in list by mouse (cherry picked from commit 8e2ce03)
b206d2d: fix NPE
d923a83: Trying to fix EA-51665 - assert: FTManager.createAndStoreBundledTemplate (cherry picked from commit 47dee08) +review CR-IC
72fa58b: Add additional diagnostic to investigate EA-51665 (assert: FTManager.createAndStoreBundledTemplate). (cherry picked from commit a5e4cf4) +review CR-IC
6548f1a: java: incorrect parsing of bounds in class files fixed
8f5b22c: EA-42899 - CCE: XmlLanguageInjectionSupport.doEditInjection & cleanup
2a882e0: EA-53406 - IAE: ServiceManager.getService
ed41c77: WI-13685 PhpStorm doesn't save project name CR-PS-181
2c3ccec: IDEA-119445 Remove first slash in "copy reference" (cherry picked from commit 298bb04)
50bf901: IDEA-119153 file search too wide for users folder (cherry picked from commit 37521f0)
8ab790b: IDEA-119470 File and code templates: changes gone when switching tabs (cherry picked from commit 21cdea3)
7402508: EA-53393 - IOOBE: DomAnchorImpl.createAnchor (missing cherry pick)
f6ab2da: Bug fix: IDEA incorrect handle escaping.
c78400d: IDEA-105253 Missing icon for Thread dumps view
21b6f91: IDEA-104735 Dracula: INVALID string have not dracula style red color (cherry picked from commit 4a5e793)
53885c2: Don't show active editor in recent files
6cf74eb: IDEA-104706 Remove currently active file from "Recent Files" popup (cherry pick from master)
ffef358: IDEA-119406 IDEA make corrupts files when performing Maven resource filtering (default value of escapeString is null)
b8e9ab1: IDEA-119406 IDEA make corrupts files when performing Maven resource filtering (cherry picked from commit 5b6b3f6) +review CR-IC
d3dd646: EA-53308 - CCE: DfaVariableValue.<init> (cherry picked from commit 32a579d)
10f83e0: external build for artifacts: added API to filter contents of directory extracted from jar file [rev by Michael Golubev]
b7f4af0: make nonDefaultProject="true" really work
0bebc13: cosmetics
94e0a24: Merge remote-tracking branch 'origin/133' into 133
85cae29: IDEA-119347 ../jre64 JDK not being picked up by idea64.exe
2dd77af: IDEA-117127 Editor: Throwable on Select word at caret inside plain text (cherry picked from commit 2e3a0d8)
0a5e3ad: IDEA-117555 Search everywhere dialog is being closed immediately (cherry picked from commit ba8037d)
520da57: fix getDisplayName nullability assertion
0663734: IDEA-111122 remove attached jar artifact coming from "apklib" dependency from the dependencies of app module: users add it to deploy jar to Maven repository in addition to "apklib" file, but we don't need to add it to the classpath, because it leads to class duplication [rev=sergey.evdokimov]
c1fb468: IDEA-79522 need ability to set display names for xml attribute and xml tag language injections
3ae70b9: IDEA-119163 "Language Injections" settings should use toolbar decorator in the same way as other
50c78e9: IDEA-117327 Add a setting to switch off autopopup completion item selection by Enter (cherry picked from commit 84ddafc)
ae5ce9b: groovy debugging agent that produces less garbage (cherry picked from commit c7af9fe)
f6682f7: Roll-back FileChooserDescriptor API change.
1c64249: Merge remote-tracking branch 'origin/133' into 133
b293f8c: SearchEverywhere doesn't work on Linux
07b98c1: IDEA-74428 Ability to turn on log debug categories from the GUI
4257f6f: CR-IU-511 make abstract class abstract & leave getPresentableText mandatory
7cac7b7: allow to turn off suggestion to create a file when creating a directory with file-like name (IDEA-118250) (cherry picked from commit 5d81e8d)
acb9db2: don't show parameter info for invisible editors (EA-53161 - NPE: ParameterInfoComponent.<init>) (cherry picked from commit fb24d98)
e6bfbbf: the users don't care if we're preparing editors to open (IDEA-115130) (cherry picked from commit 9a116de)
3f1ebf3: rethrow PCE from KeyedExtensionFactory reflection (cherry picked from commit df8967b)

Change-Id: I8083d21f3faff4f899c53a5dea2710713dc1a2a9
diff --git a/bin/WinLauncher/WinLauncher64.exe b/bin/WinLauncher/WinLauncher64.exe
index 4471708..e2e4348 100644
--- a/bin/WinLauncher/WinLauncher64.exe
+++ b/bin/WinLauncher/WinLauncher64.exe
Binary files differ
diff --git a/community-resources/src/idea/IdeaApplicationInfo.xml b/community-resources/src/idea/IdeaApplicationInfo.xml
index 9e07e0c..08f4adb 100644
--- a/community-resources/src/idea/IdeaApplicationInfo.xml
+++ b/community-resources/src/idea/IdeaApplicationInfo.xml
@@ -1,5 +1,5 @@
 <component>
-  <version codename="Community Edition" major="13" minor="0.2" eap="true"/>
+  <version codename="Community Edition" major="13" minor="0.2" eap="false"/>
   <company name="JetBrains s.r.o." url="http://www.jetbrains.com/?fromIDE"/>
   <build number="__BUILD_NUMBER__" date="__BUILD_DATE__"/>
   <install-over minbuild="129.1" maxbuild="132.9999" version="12.1"/>
diff --git a/community-resources/src/idea_community_about.png b/community-resources/src/idea_community_about.png
index 5bed0ec..2b5a763 100644
--- a/community-resources/src/idea_community_about.png
+++ b/community-resources/src/idea_community_about.png
Binary files differ
diff --git a/community-resources/src/[email protected] b/community-resources/src/[email protected]
index 428aaa5..f159fb0 100644
--- a/community-resources/src/[email protected]
+++ b/community-resources/src/[email protected]
Binary files differ
diff --git a/community-resources/src/idea_community_logo.png b/community-resources/src/idea_community_logo.png
index 87543ff..91a8153 100644
--- a/community-resources/src/idea_community_logo.png
+++ b/community-resources/src/idea_community_logo.png
Binary files differ
diff --git a/community-resources/src/[email protected] b/community-resources/src/[email protected]
index 57603be..1f2cfb1 100644
--- a/community-resources/src/[email protected]
+++ b/community-resources/src/[email protected]
Binary files differ
diff --git a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
index 0f13731..49a0d9d 100644
--- a/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
+++ b/java/compiler/impl/src/com/intellij/compiler/server/BuildManager.java
@@ -100,8 +100,7 @@
 import org.jetbrains.jps.incremental.Utils;
 import org.jetbrains.jps.model.serialization.JpsGlobalLoader;
 
-import javax.tools.JavaCompiler;
-import javax.tools.ToolProvider;
+import javax.tools.*;
 import java.awt.*;
 import java.io.File;
 import java.io.IOException;
@@ -878,7 +877,11 @@
         cmdLine.addParameter(option);
       }
     }
-
+    
+    if (isProfilingMode) {
+      cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,delay=10000,sessionname=ExternalBuild");
+    }
+    
     // debugging
     final int debugPort = Registry.intValue("compiler.process.debug.port");
     if (debugPort > 0) {
@@ -933,7 +936,6 @@
     cp.addAll(myClasspathManager.getBuildProcessPluginsClasspath(project));
     if (isProfilingMode) {
       cp.add(new File(workDirectory, "yjp-controller-api-redist.jar").getPath());
-      cmdLine.addParameter("-agentlib:yjpagent=disablej2ee,disablealloc,delay=10000,sessionname=ExternalBuild");
     }
     cmdLine.addParameter(classpathToString(cp));
 
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index 70f2c48..5ec56b9 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -91,7 +91,8 @@
     myIsNegated = isNegated;
     myQualifier = qualifier;
     myVarType = varType;
-    myTypeValue = varType == null ? null : (DfaTypeValue)myFactory.createTypeValue(varType, Nullness.UNKNOWN);
+    DfaValue typeValue = myFactory.createTypeValue(varType, Nullness.UNKNOWN);
+    myTypeValue = typeValue instanceof DfaTypeValue ? (DfaTypeValue)typeValue : null;
   }
 
   @Nullable
diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
index af52156..6660080b 100644
--- a/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
+++ b/java/java-impl/src/com/intellij/psi/NonClasspathClassFinder.java
@@ -44,19 +44,21 @@
   private volatile List<VirtualFile> myCache;
   private final PsiManager myManager;
   private final boolean myCheckForSources;
-  private final boolean myUseExtendedScope;
 
   public NonClasspathClassFinder(Project project) {
-    this(project, false, false);
+    this(project, false);
   }
 
-  protected NonClasspathClassFinder(Project project, boolean checkForSources, boolean useExtendedScope) {
+  protected NonClasspathClassFinder(Project project, boolean checkForSources) {
     myProject = project;
     myManager = PsiManager.getInstance(myProject);
-    myUseExtendedScope = useExtendedScope;
     myCheckForSources = checkForSources;
   }
 
+  protected List<VirtualFile> getClassRoots(@Nullable GlobalSearchScope scope) {
+    return getClassRoots();
+  }
+
   protected List<VirtualFile> getClassRoots() {
     List<VirtualFile> cache = myCache;
     long stamp = myManager.getModificationTracker().getModificationCount();
@@ -82,14 +84,11 @@
 
   @Override
   public PsiClass findClass(@NotNull String qualifiedName, @NotNull GlobalSearchScope scope) {
-    final List<VirtualFile> classRoots = getClassRoots();
+    final List<VirtualFile> classRoots = getClassRoots(scope);
     if (classRoots.isEmpty()) {
       return null;
     }
 
-    if(myUseExtendedScope) {
-      scope = addNonClasspathScope(myProject, scope);
-    }
     final String relPath = qualifiedName.replace('.', '/');
     for (final VirtualFile classRoot : classRoots) {
       if (scope.contains(classRoot)) {
@@ -131,7 +130,7 @@
   @NotNull
   @Override
   public PsiClass[] getClasses(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
-    final List<VirtualFile> classRoots = getClassRoots();
+    final List<VirtualFile> classRoots = getClassRoots(scope);
     if (classRoots.isEmpty()) {
       return PsiClass.EMPTY_ARRAY;
     }
@@ -160,7 +159,7 @@
   @NotNull
   @Override
   public Set<String> getClassNames(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
-    final List<VirtualFile> classRoots = getClassRoots();
+    final List<VirtualFile> classRoots = getClassRoots(scope);
     if (classRoots.isEmpty()) {
       return Collections.emptySet();
     }
@@ -172,7 +171,8 @@
         final VirtualFile dir = classRoot.findFileByRelativePath(pkgName.replace('.', '/'));
         if (dir != null && dir.isDirectory()) {
           for (final VirtualFile file : dir.getChildren()) {
-            if (!file.isDirectory() && "class".equals(file.getExtension())) {
+            if ((myCheckForSources && !file.isDirectory() && JavaFileType.DEFAULT_EXTENSION.equals(file.getExtension()))
+                || (!file.isDirectory() && "class".equals(file.getExtension()))) {
               result.add(file.getNameWithoutExtension());
             }
           }
@@ -207,7 +207,7 @@
                                            @NotNull GlobalSearchScope scope,
                                            @NotNull Processor<PsiDirectory> consumer,
                                            boolean includeLibrarySources) {
-    final List<VirtualFile> classRoots = getClassRoots();
+    final List<VirtualFile> classRoots = getClassRoots(scope);
     if (classRoots.isEmpty()) {
       return true;
     }
@@ -237,7 +237,7 @@
   @NotNull
   @Override
   public PsiPackage[] getSubPackages(@NotNull PsiPackage psiPackage, @NotNull GlobalSearchScope scope) {
-    final List<VirtualFile> classRoots = getClassRoots();
+    final List<VirtualFile> classRoots = getClassRoots(scope);
     if (classRoots.isEmpty()) {
       return super.getSubPackages(psiPackage, scope);
     }
diff --git a/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java b/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
index f6c8f8e..0111478 100644
--- a/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
+++ b/java/java-impl/src/com/intellij/psi/NonClasspathResolveScopeEnlarger.java
@@ -1,5 +1,6 @@
 package com.intellij.psi;
 
+import com.intellij.ide.highlighter.JavaFileType;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VfsUtil;
@@ -17,7 +18,8 @@
 
   @Override
   public SearchScope getAdditionalResolveScope(@NotNull VirtualFile file, Project project) {
-    if ("class".equals(file.getExtension())) {
+    String fileExtension = file.getExtension();
+    if ("class".equals(fileExtension) || JavaFileType.DEFAULT_EXTENSION.equals(fileExtension)) {
       for (PsiElementFinder finder : Extensions.getExtensions(PsiElementFinder.EP_NAME, project)) {
         if (finder instanceof NonClasspathClassFinder) {
           final List<VirtualFile> roots = ((NonClasspathClassFinder)finder).getClassRoots();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
index 43b57aa..96c48ec 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClassFileStubBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -34,7 +34,7 @@
 public class ClassFileStubBuilder implements BinaryFileStubBuilder {
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClassFileStubBuilder");
 
-  public static final int STUB_VERSION = 7 + JavaFileElementType.STUB_VERSION;
+  public static final int STUB_VERSION = 8 + JavaFileElementType.STUB_VERSION;
 
   @Override
   public boolean acceptsFile(final VirtualFile file) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/SignatureParsing.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/SignatureParsing.java
index 7c40209..89ea3bc 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/SignatureParsing.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/SignatureParsing.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -29,12 +29,13 @@
 import com.intellij.psi.stubs.StubElement;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.io.StringRef;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.Nullable;
 
 import java.text.CharacterIterator;
-import java.util.ArrayList;
+import java.util.List;
 
 @SuppressWarnings({"HardCodedStringLiteral"})
 public class SignatureParsing {
@@ -69,16 +70,20 @@
     //todo parse annotations on type param
     PsiTypeParameterStub parameterStub = new PsiTypeParameterStubImpl(parent, StringRef.fromString(name.toString()));
 
-    ArrayList<String> bounds = null;
+    List<String> bounds = ContainerUtil.newSmartList();
     while (signatureIterator.current() == ':') {
       signatureIterator.next();
       String bound = parseTopLevelClassRefSignature(signatureIterator);
-      if (bound != null && !bound.equals(CommonClassNames.JAVA_LANG_OBJECT)) {
-        if (bounds == null) bounds = new ArrayList<String>();
+      if (bound != null) {
         bounds.add(bound);
       }
     }
 
+    int size = bounds.size();
+    if (size > 0 && CommonClassNames.JAVA_LANG_OBJECT.equals(bounds.get(size - 1))) {
+      bounds.remove(size - 1);
+    }
+
     StubBuildingVisitor.newReferenceList(JavaStubElementTypes.EXTENDS_BOUND_LIST, parameterStub, ArrayUtil.toStringArray(bounds));
 
     return parameterStub;
diff --git a/java/java-tests/testData/codeInsight/copyReference/CopyFile_after.java b/java/java-tests/testData/codeInsight/copyReference/CopyFile_after.java
index b0c0783..f1120f4 100644
--- a/java/java-tests/testData/codeInsight/copyReference/CopyFile_after.java
+++ b/java/java-tests/testData/codeInsight/copyReference/CopyFile_after.java
@@ -1,3 +1,3 @@
 class X {
-  String s = "/x/x.txt<caret>";
+  String s = "x/x.txt<caret>";
 }
diff --git a/java/java-tests/testData/psi/cls/mirror/Bounds.txt b/java/java-tests/testData/psi/cls/mirror/Bounds.txt
new file mode 100644
index 0000000..ab190fd
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/Bounds.txt
@@ -0,0 +1,13 @@
+
+  // IntelliJ API Decompiler stub source generated from a class file
+  // Implementation of methods is not available
+
+package pkg;
+
+class Bounds {
+    Bounds() { /* compiled code */ }
+
+    public static <T extends java.lang.Object & java.lang.Comparable<? super T>>  T max(java.util.Collection<? extends T> collection) { /* compiled code */ }
+
+    public static <T>  T max(java.util.Collection<? extends T> collection, java.util.Comparator<? super T> comparator) { /* compiled code */ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/Bounds.class b/java/java-tests/testData/psi/cls/mirror/pkg/Bounds.class
new file mode 100644
index 0000000..ce57f18
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/Bounds.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/Bounds.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/Bounds.java
new file mode 100644
index 0000000..81bd3a0
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/Bounds.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package pkg;
+
+import java.util.Collection;
+import java.util.Comparator;
+
+class Bounds {
+  public static <T extends Object & Comparable<? super T>> T max(Collection<? extends T> coll) {
+    return null;
+  }
+
+  public static <T> T max(Collection<? extends T> coll, Comparator<? super T> comp) {
+    return null;
+  }
+}
diff --git a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
index d58e2e6..82d04fec4 100644
--- a/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
+++ b/java/java-tests/testData/psi/cls/stubBuilder/UtilCollections.txt
@@ -1693,7 +1693,7 @@
       PsiModifierListStub[mask=9]
       PsiTypeParameterListStub
         PsiTypeParameter[T]
-          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Comparable<? super T>]
+          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
       PsiParameterListStub
         PsiParameterStub[p1:java.util.List<? extends T>]
           PsiModifierListStub[mask=0]
@@ -1704,7 +1704,7 @@
       PsiModifierListStub[mask=10]
       PsiTypeParameterListStub
         PsiTypeParameter[T]
-          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Comparable<? super T>]
+          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
       PsiParameterListStub
         PsiParameterStub[p1:java.util.List<? extends T>]
           PsiModifierListStub[mask=0]
@@ -1715,7 +1715,7 @@
       PsiModifierListStub[mask=10]
       PsiTypeParameterListStub
         PsiTypeParameter[T]
-          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Comparable<? super T>]
+          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
       PsiParameterListStub
         PsiParameterStub[p1:java.util.List<? extends T>]
           PsiModifierListStub[mask=0]
@@ -1843,7 +1843,7 @@
       PsiModifierListStub[mask=9]
       PsiTypeParameterListStub
         PsiTypeParameter[T]
-          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Comparable<? super T>]
+          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
       PsiParameterListStub
         PsiParameterStub[p1:java.util.Collection<? extends T>]
           PsiModifierListStub[mask=0]
@@ -1863,7 +1863,7 @@
       PsiModifierListStub[mask=9]
       PsiTypeParameterListStub
         PsiTypeParameter[T]
-          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Comparable<? super T>]
+          PsiRefListStub[EXTENDS_BOUNDS_LIST:java.lang.Object, java.lang.Comparable<? super T>]
       PsiParameterListStub
         PsiParameterStub[p1:java.util.Collection<? extends T>]
           PsiModifierListStub[mask=0]
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
index fbae4d1..ae14f48 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
@@ -90,7 +90,7 @@
     performCopy()
     myFixture.configureByText 'a.txt', ''
     performPaste()
-    myFixture.checkResult "/a.java:2"
+    myFixture.checkResult "a.java:2"
   }
 
   public void _testMethodOverloadCopy() {
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index b9a4a18..728fd72 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -44,6 +44,7 @@
   public void testClassRefs() { doTest(); }
   public void testEA46236() { doTest("ValuedEnum"); }
   public void testKotlinFunList() { doTest(); }
+  public void testBounds() { doTest(); }
 
   private void doTest() {
     doTest(getTestName(false));
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreator.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreator.java
index eb2987e..5648eb9 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreator.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreator.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.jps.incremental.artifacts.instructions;
 
+import com.intellij.openapi.util.Condition;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -31,8 +32,23 @@
 
   void addDirectoryCopyInstructions(@NotNull File directory, @Nullable SourceFileFilter filter);
 
+  /**
+   * Add instruction to extract directory from a jar file into the current place in the artifact layout.
+   *
+   * @param jarFile         jar file to extract
+   * @param pathInJar       relative path to directory inside {@code jarFile} which need to be extracted. Use "/" to extract the whole jar contents
+   */
   void addExtractDirectoryInstruction(@NotNull File jarFile, @NotNull String pathInJar);
 
+  /**
+   * Add instruction to extract directory from a jar file into the current place in the artifact layout.
+   * @param jarFile jar file to extract
+   * @param pathInJar relative path to directory inside {@code jarFile} which need to be extracted. Use "/" to extract the whole jar contents
+   * @param pathInJarFilter a filter instance specifying which entries should be extracted. It should accept paths inside the jar file
+   *                        relative to {@code pathInJar} root and return {@code true} if the entry should be extracted and {@code false} otherwise
+   */
+  void addExtractDirectoryInstruction(@NotNull File jarFile, @NotNull String pathInJar, @NotNull Condition<String> pathInJarFilter);
+
   ArtifactCompilerInstructionCreator subFolder(@NotNull String directoryName);
 
   ArtifactCompilerInstructionCreator archive(@NotNull String archiveFileName);
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreatorBase.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreatorBase.java
index ee1ee17..2e5aa50 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreatorBase.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactCompilerInstructionCreatorBase.java
@@ -15,14 +15,16 @@
  */
 package org.jetbrains.jps.incremental.artifacts.instructions;
 
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Conditions;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.util.PathUtilRt;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.cmdline.ProjectDescriptor;
+import org.jetbrains.jps.incremental.artifacts.JarPathUtil;
 import org.jetbrains.jps.indices.IgnoredFileIndex;
 import org.jetbrains.jps.indices.ModuleExcludeIndex;
-import org.jetbrains.jps.incremental.artifacts.JarPathUtil;
 
 import java.io.File;
 import java.io.IOException;
@@ -56,15 +58,22 @@
 
   @Override
   public void addExtractDirectoryInstruction(@NotNull File jarFile, @NotNull String pathInJar) {
+    addExtractDirectoryInstruction(jarFile, pathInJar, Conditions.<String>alwaysTrue());
+  }
+
+  @Override
+  public void addExtractDirectoryInstruction(@NotNull File jarFile,
+                                             @NotNull String pathInJar,
+                                             @NotNull Condition<String> pathInJarFilter) {
     //an entry of a jar file is excluded if and only if the jar file itself is excluded. In that case we should unpack entries to the artifact
-    // because the jar itself is explicitly added to the artifact layout.
+    //because the jar itself is explicitly added to the artifact layout.
     boolean includeExcluded = true;
 
     final SourceFileFilterImpl filter = new SourceFileFilterImpl(null, myInstructionsBuilder.getRootsIndex(),
                                                                  myInstructionsBuilder.getIgnoredFileIndex(), includeExcluded);
     DestinationInfo destination = createDirectoryDestination();
     if (destination != null) {
-      ArtifactRootDescriptor descriptor = myInstructionsBuilder.createJarBasedRoot(jarFile, pathInJar, filter, destination);
+      ArtifactRootDescriptor descriptor = myInstructionsBuilder.createJarBasedRoot(jarFile, pathInJar, filter, destination, pathInJarFilter);
       if (myInstructionsBuilder.addDestination(descriptor)) {
         onAdded(descriptor);
       }
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java
index ae9993d..0352417 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/ArtifactInstructionsBuilderImpl.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.jps.incremental.artifacts.instructions;
 
+import com.intellij.openapi.util.Condition;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.jps.incremental.artifacts.ArtifactBuildTarget;
 import org.jetbrains.jps.indices.IgnoredFileIndex;
@@ -79,7 +80,9 @@
 
   public JarBasedArtifactRootDescriptor createJarBasedRoot(@NotNull File jarFile,
                                                            @NotNull String pathInJar,
-                                                           @NotNull SourceFileFilter filter, final DestinationInfo destinationInfo) {
-    return new JarBasedArtifactRootDescriptor(jarFile, pathInJar, filter, myRootIndex++, myBuildTarget, destinationInfo);
+                                                           @NotNull SourceFileFilter filter,
+                                                           @NotNull DestinationInfo destinationInfo,
+                                                           @NotNull Condition<String> pathInJarFilter) {
+    return new JarBasedArtifactRootDescriptor(jarFile, pathInJar, filter, myRootIndex++, myBuildTarget, destinationInfo, pathInJarFilter);
   }
 }
diff --git a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java
index 8c3f762..c5eb0494 100644
--- a/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java
+++ b/jps/jps-builders/src/org/jetbrains/jps/incremental/artifacts/instructions/JarBasedArtifactRootDescriptor.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.jps.incremental.artifacts.instructions;
 
+import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.io.FileUtil;
 import com.intellij.openapi.util.text.StringUtil;
 import org.jetbrains.annotations.NotNull;
@@ -39,14 +40,18 @@
  */
 public class JarBasedArtifactRootDescriptor extends ArtifactRootDescriptor {
   private final String myPathInJar;
+  private final Condition<String> myPathInJarFilter;
 
   public JarBasedArtifactRootDescriptor(@NotNull File jarFile,
                                         @NotNull String pathInJar,
                                         @NotNull SourceFileFilter filter,
                                         int index,
-                                        ArtifactBuildTarget target, DestinationInfo destinationInfo) {
+                                        @NotNull ArtifactBuildTarget target,
+                                        @NotNull DestinationInfo destinationInfo,
+                                        @NotNull Condition<String> pathInJarFilter) {
     super(jarFile, filter, index, target, destinationInfo);
     myPathInJar = pathInJar;
+    myPathInJarFilter = pathInJarFilter;
   }
 
   public void processEntries(EntryProcessor processor) throws IOException {
@@ -68,7 +73,9 @@
           final String name = entry.getName();
           if (name.startsWith(prefix)) {
             String relativePath = name.substring(prefix.length());
-            processor.process(entry.isDirectory() ? null : zipFile.getInputStream(entry), relativePath, entry);
+            if (myPathInJarFilter.value(relativePath)) {
+              processor.process(entry.isDirectory() ? null : zipFile.getInputStream(entry), relativePath, entry);
+            }
           }
         }
       }
diff --git a/native/WinLauncher/WinLauncher/WinLauncher.cpp b/native/WinLauncher/WinLauncher/WinLauncher.cpp
index e085b18..8d5ff13 100644
--- a/native/WinLauncher/WinLauncher/WinLauncher.cpp
+++ b/native/WinLauncher/WinLauncher/WinLauncher.cpp
@@ -190,7 +190,7 @@
 		return result;
 	}
 
-	std::string jreDir = GetAdjacentDir("jre");
+	std::string jreDir = GetAdjacentDir(need64BitJRE ? "jre64":"jre");
 	if (FindValidJVM(jreDir.c_str()) && Is64BitJRE(jvmPath) == need64BitJRE)
 	{
 		return true;
diff --git a/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java b/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java
index 084be74..f955f35 100644
--- a/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java
+++ b/platform/core-api/src/com/intellij/patterns/TreeElementPattern.java
@@ -110,7 +110,7 @@
     return withSuperParent(level, StandardPatterns.instanceOf(aClass));
   }
   public Self withSuperParent(final int level, @NotNull final ElementPattern<? extends ParentType> pattern) {
-    return with(new PatternConditionPlus<T, ParentType>("withSuperParent", pattern) {
+    return with(new PatternConditionPlus<T, ParentType>(level == 1 ? "withParent" : "withSuperParent", pattern) {
 
       @Override
       public boolean processValues(T t,
diff --git a/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
index 054cfe0..f815acf 100644
--- a/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
+++ b/platform/extensions/src/com/intellij/openapi/util/KeyedExtensionFactory.java
@@ -23,6 +23,7 @@
 import org.picocontainer.PicoContainer;
 
 import java.lang.reflect.InvocationHandler;
+import java.lang.reflect.InvocationTargetException;
 import java.lang.reflect.Method;
 import java.lang.reflect.Proxy;
 
@@ -94,6 +95,12 @@
             break;
           }
         }
+        catch (InvocationTargetException e) {
+          if (e.getCause() instanceof RuntimeException) {
+            throw (RuntimeException)e.getCause();
+          }
+          throw new RuntimeException(e);
+        }
         catch (RuntimeException e) {
           throw e;
         }
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java
new file mode 100644
index 0000000..5783f94
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalModuleBuildClasspathPojo.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.externalSystem.model.project;
+
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/14/14
+ */
+public class ExternalModuleBuildClasspathPojo {
+
+  @NotNull private List<String> myEntries;
+  @NotNull private String myPath;
+
+  @SuppressWarnings("UnusedDeclaration")
+  public ExternalModuleBuildClasspathPojo() {
+    // Used by IJ serialization
+    this("___DUMMY___", ContainerUtil.<String>newArrayList());
+  }
+
+  public ExternalModuleBuildClasspathPojo(@NotNull String path, @NotNull List<String> entries) {
+    myPath = path;
+    myEntries = entries;
+  }
+
+  @NotNull
+  public String getPath() {
+    return myPath;
+  }
+
+  public void setPath(@NotNull String path) {
+    myPath = path;
+  }
+
+  @NotNull
+  public List<String> getEntries() {
+    return myEntries;
+  }
+
+  public void setEntries(@NotNull List<String> entries) {
+    myEntries = entries;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = myEntries.hashCode();
+    result = 31 * result + myPath.hashCode();
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ExternalModuleBuildClasspathPojo pojo = (ExternalModuleBuildClasspathPojo)o;
+
+    if (!myEntries.equals(pojo.myEntries)) return false;
+    if (!myPath.equals(pojo.myPath)) return false;
+
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    return myPath;
+  }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalProjectBuildClasspathPojo.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalProjectBuildClasspathPojo.java
new file mode 100644
index 0000000..9fb2ea6
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/model/project/ExternalProjectBuildClasspathPojo.java
@@ -0,0 +1,102 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.externalSystem.model.project;
+
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/14/14
+ */
+public class ExternalProjectBuildClasspathPojo {
+
+  /**
+   * Common for all project modules build classpath. E.g. it can be build system SDK libraries, configured at project level.
+   */
+  @NotNull private List<String> myProjectBuildClasspath;
+  @NotNull private Map<String, ExternalModuleBuildClasspathPojo> myModulesBuildClasspath;
+  @NotNull private String myName;
+
+  @SuppressWarnings("UnusedDeclaration")
+  public ExternalProjectBuildClasspathPojo() {
+    // Used by IJ serialization
+    this("___DUMMY___", ContainerUtil.<String>newArrayList(), ContainerUtil.<String, ExternalModuleBuildClasspathPojo>newHashMap());
+  }
+
+  public ExternalProjectBuildClasspathPojo(@NotNull String name,
+                                           @NotNull List<String> projectBuildClasspath,
+                                           @NotNull Map<String, ExternalModuleBuildClasspathPojo> modulesBuildClasspath) {
+    myName = name;
+    myProjectBuildClasspath = projectBuildClasspath;
+    myModulesBuildClasspath = modulesBuildClasspath;
+  }
+
+  @NotNull
+  public String getName() {
+    return myName;
+  }
+
+  public void setName(@NotNull String name) {
+    myName = name;
+  }
+
+  @NotNull
+  public Map<String, ExternalModuleBuildClasspathPojo> getModulesBuildClasspath() {
+    return myModulesBuildClasspath;
+  }
+
+  public void setModulesBuildClasspath(@NotNull Map<String, ExternalModuleBuildClasspathPojo> modulesBuildClasspath) {
+    myModulesBuildClasspath = modulesBuildClasspath;
+  }
+
+  @NotNull
+  public List<String> getProjectBuildClasspath() {
+    return myProjectBuildClasspath;
+  }
+
+  public void setProjectBuildClasspath(@NotNull List<String> projectBuildClasspath) {
+    myProjectBuildClasspath = projectBuildClasspath;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = myModulesBuildClasspath.hashCode();
+    result = 31 * result + myModulesBuildClasspath.hashCode();
+    return result;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    ExternalProjectBuildClasspathPojo pojo = (ExternalProjectBuildClasspathPojo)o;
+
+    if (!myModulesBuildClasspath.equals(pojo.myModulesBuildClasspath)) return false;
+    if (!myName.equals(pojo.myName)) return false;
+
+    return true;
+  }
+
+  @Override
+  public String toString() {
+    return myName;
+  }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/psi/search/ExternalModuleBuildGlobalSearchScope.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/psi/search/ExternalModuleBuildGlobalSearchScope.java
new file mode 100644
index 0000000..acd5c80
--- /dev/null
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/psi/search/ExternalModuleBuildGlobalSearchScope.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.externalSystem.psi.search;
+
+import com.intellij.psi.search.DelegatingGlobalSearchScope;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/15/14
+ */
+public class ExternalModuleBuildGlobalSearchScope extends DelegatingGlobalSearchScope {
+
+  @NotNull
+  private final String externalModulePath;
+
+  public ExternalModuleBuildGlobalSearchScope(@NotNull GlobalSearchScope baseScope, @NotNull String externalModulePath) {
+    super(baseScope);
+    this.externalModulePath = externalModulePath;
+  }
+
+  @NotNull
+  public String getExternalModulePath() {
+    return externalModulePath;
+  }
+}
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java
index 86550ee..aa69509 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/settings/AbstractExternalSystemLocalSettings.java
@@ -19,6 +19,7 @@
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskExecutionInfo;
 import com.intellij.openapi.externalSystem.model.execution.ExternalTaskPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
 import com.intellij.openapi.externalSystem.model.project.ExternalProjectPojo;
 import com.intellij.openapi.externalSystem.service.project.PlatformFacade;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
@@ -64,6 +65,10 @@
     new AtomicReference<Map<String, Collection<ExternalTaskPojo>>>(
       ContainerUtilRt.<String, Collection<ExternalTaskPojo>>newHashMap()
     );
+  private final AtomicReference<Map<String/* external project config path */, ExternalProjectBuildClasspathPojo>> myProjectBuildClasspath =
+    new AtomicReference<Map<String, ExternalProjectBuildClasspathPojo>>(
+      ContainerUtilRt.<String, ExternalProjectBuildClasspathPojo>newHashMap()
+    );
   private final AtomicReference<Map<String/* external project config path */, Long>>
                                                                                                              myExternalConfigModificationStamps =
     new AtomicReference<Map<String, Long>>(ContainerUtilRt.<String, Long>newHashMap());
@@ -114,6 +119,15 @@
       }
     }
 
+    for (Iterator<Map.Entry<String, ExternalProjectBuildClasspathPojo>> it = myProjectBuildClasspath.get().entrySet().iterator(); it.hasNext(); ) {
+      Map.Entry<String, ExternalProjectBuildClasspathPojo> entry = it.next();
+      if (linkedProjectPathsToForget.contains(entry.getKey())
+          || linkedProjectPathsToForget.contains(ExternalSystemApiUtil.getRootProjectPath(entry.getKey(), myExternalSystemId, myProject)))
+      {
+        it.remove();
+      }
+    }
+
     Map<String, Long> modificationStamps = myExternalConfigModificationStamps.get();
     for (String path : linkedProjectPathsToForget) {
       modificationStamps.remove(path);
@@ -152,7 +166,7 @@
   public void setRecentTasks(@NotNull List<ExternalTaskExecutionInfo> tasks) {
     myRecentTasks.set(tasks);
   }
-  
+
   @NotNull
   public Map<String, Long> getExternalConfigModificationStamps() {
     return myExternalConfigModificationStamps.get();
@@ -163,7 +177,18 @@
     // Required for IJ serialization.
     myExternalConfigModificationStamps.set(modificationStamps);
   }
-  
+
+  @NotNull
+  public Map<String, ExternalProjectBuildClasspathPojo> getProjectBuildClasspath() {
+    return myProjectBuildClasspath.get();
+  }
+
+  @SuppressWarnings("UnusedDeclaration")
+  public void setProjectBuildClasspath(@NotNull Map<String, ExternalProjectBuildClasspathPojo> projectsBuildClasspath) {
+    // Required for IJ serialization.
+    myProjectBuildClasspath.set(projectsBuildClasspath);
+  }
+
   public void fillState(@NotNull State state) {
     if (PRESERVE_EXPAND_STATE) {
       state.tasksExpandState = myExpandStates.get();
@@ -175,6 +200,7 @@
     state.availableProjects = myAvailableProjects.get();
     state.availableTasks = myAvailableTasks.get();
     state.modificationStamps = myExternalConfigModificationStamps.get();
+    state.projectBuildClasspath = myProjectBuildClasspath.get();
   }
 
   public void loadState(@NotNull State state) {
@@ -182,6 +208,7 @@
     setIfNotNull(myAvailableProjects, state.availableProjects);
     setIfNotNull(myAvailableTasks, state.availableTasks);
     setIfNotNull(myExternalConfigModificationStamps, state.modificationStamps);
+    setIfNotNull(myProjectBuildClasspath, state.projectBuildClasspath);
     if (state.recentTasks != null) {
       List<ExternalTaskExecutionInfo> recentTasks = myRecentTasks.get();
       if (recentTasks != state.recentTasks) {
@@ -242,5 +269,6 @@
 
     public Map<String/* linked project path */, Long/* last config modification stamp */> modificationStamps
       = ContainerUtilRt.newHashMap();
+    public Map<String/* linked project path */, ExternalProjectBuildClasspathPojo> projectBuildClasspath = ContainerUtilRt.newHashMap();
   }
 }
diff --git a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
index 7b078c7..af0772d 100644
--- a/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
+++ b/platform/external-system-api/src/com/intellij/openapi/externalSystem/util/ExternalSystemApiUtil.java
@@ -318,6 +318,24 @@
   }
 
   @SuppressWarnings("unchecked")
+  @Nullable
+  public static <T> DataNode<T> findParent(@NotNull DataNode<?> node, @NotNull Key<T> key) {
+    return findParent(node, key, null);
+  }
+
+
+  @SuppressWarnings("unchecked")
+  @Nullable
+  public static <T> DataNode<T> findParent(@NotNull DataNode<?> node,
+                                           @NotNull Key<T> key,
+                                           @Nullable BooleanFunction<DataNode<T>> predicate) {
+    DataNode<?> parent = node.getParent();
+    if (parent == null) return null;
+    return key.equals(parent.getKey()) && (predicate == null || predicate.fun((DataNode<T>)parent))
+           ? (DataNode<T>)parent : findParent(parent, key, predicate);
+  }
+
+  @SuppressWarnings("unchecked")
   @NotNull
   public static <T> Collection<DataNode<T>> findAll(@NotNull DataNode<?> parent, @NotNull Key<T> key) {
     Collection<DataNode<T>> result = null;
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java
index 89413c58..9f14e00 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/AutoPopupController.java
@@ -171,8 +171,9 @@
       final Runnable request = new Runnable(){
         @Override
         public void run(){
-          if (myProject.isDisposed() || DumbService.isDumb(myProject) || editor.isDisposed()) return;
+          if (myProject.isDisposed() || DumbService.isDumb(myProject)) return;
           documentManager.commitAllDocuments();
+          if (editor.isDisposed() || !editor.getComponent().isShowing()) return;
           int lbraceOffset = editor.getCaretModel().getOffset() - 1;
           try {
             ShowParameterInfoHandler.invoke(myProject, editor, file1, lbraceOffset, highlightedMethod);
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
index 1aa02d4..39e0b5d 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/completion/CompletionProgressIndicator.java
@@ -705,6 +705,10 @@
   }
 
   private static boolean shouldPreselectFirstSuggestion(CompletionParameters parameters) {
+    if (!Registry.is("ide.completion.autopopup.choose.by.enter")) {
+      return false;
+    }
+
     if (!ApplicationManager.getApplication().isUnitTestMode()) {
       return true;
     }
diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/wordSelection/NaturalLanguageTextSelectioner.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/wordSelection/NaturalLanguageTextSelectioner.java
index a574ce0..dc5d9f3 100644
--- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/wordSelection/NaturalLanguageTextSelectioner.java
+++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/wordSelection/NaturalLanguageTextSelectioner.java
@@ -44,6 +44,9 @@
   private static TextRange findParagraphRange(String text, int start, int end) {
     int paragraphStart = text.lastIndexOf("\n\n", start);
     int paragraphEnd = text.indexOf("\n\n", end);
+    if (paragraphStart >= paragraphEnd) {
+      return new TextRange(0, text.length());
+    }
     return new TextRange(paragraphStart >= 0 ? paragraphStart + 2 : 0, paragraphEnd < 0 ? text.length() : paragraphEnd);
   }
 
diff --git a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/RestoreViewAction.java b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/RestoreViewAction.java
index cff9749..61676bb 100644
--- a/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/RestoreViewAction.java
+++ b/platform/lang-impl/src/com/intellij/execution/ui/layout/actions/RestoreViewAction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -17,12 +17,15 @@
 package com.intellij.execution.ui.layout.actions;
 
 import com.intellij.execution.ui.layout.CellTransform;
+import com.intellij.icons.AllIcons;
 import com.intellij.idea.ActionsBundle;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.Presentation;
 import com.intellij.ui.content.Content;
 
+import javax.swing.*;
+
 public class RestoreViewAction extends AnAction {
 
   private final Content myContent;
@@ -38,7 +41,8 @@
     Presentation p = e.getPresentation();
     p.setText(ActionsBundle.message("action.Runner.RestoreView.text", myContent.getDisplayName()));
     p.setDescription(ActionsBundle.message("action.Runner.RestoreView.description"));
-    p.setIcon(myContent.getIcon());
+    Icon icon = myContent.getIcon();
+    p.setIcon(icon == null ? AllIcons.Debugger.RestoreLayout : icon);
   }
 
   @Override
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
index 6cc5dda..7d53a7d3 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/CopyReferenceAction.java
@@ -20,7 +20,10 @@
 import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.ide.IdeBundle;
 import com.intellij.ide.dnd.FileCopyPasteUtil;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.ActionPlaces;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.actionSystem.CommonDataKeys;
+import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.editor.colors.EditorColors;
@@ -33,14 +36,12 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.util.io.FileUtil;
-import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.wm.WindowManager;
 import com.intellij.openapi.wm.ex.StatusBarEx;
 import com.intellij.psi.*;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.LogicalRoot;
-import com.intellij.util.LogicalRootsManager;
+import com.intellij.util.*;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -84,7 +85,7 @@
     Project project = CommonDataKeys.PROJECT.getData(dataContext);
     PsiElement element = getElementToCopy(editor, dataContext);
 
-    if (!doCopy(element, project, editor) && editor != null) {
+    if (!doCopy(element, project, editor) && editor != null && project != null) {
       Document document = editor.getDocument();
       PsiFile file = PsiDocumentManager.getInstance(project).getCachedPsiFile(document);
       if (file != null) {
@@ -98,7 +99,7 @@
     HighlightManager highlightManager = HighlightManager.getInstance(project);
     EditorColorsManager manager = EditorColorsManager.getInstance();
     TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
-    if (element != null && editor != null) {
+    if (element != null && editor != null && project != null) {
       PsiElement nameIdentifier = IdentifierUtil.getNameIdentifier(element);
       if (nameIdentifier != null) {
         highlightManager.addOccurrenceHighlights(editor, new PsiElement[]{nameIdentifier}, attributes, true, null);
@@ -181,7 +182,7 @@
 
     @Override
     public boolean isDataFlavorSupported(DataFlavor flavor) {
-      return ArrayUtil.find(getTransferDataFlavors(), flavor) != -1;
+      return ArrayUtilRt.find(getTransferDataFlavors(), flavor) != -1;
     }
 
     @Override
@@ -238,16 +239,16 @@
     }
     final Project project = file.getProject();
     final LogicalRoot logicalRoot = LogicalRootsManager.getLogicalRootsManager(project).findLogicalRoot(virtualFile);
-    if (logicalRoot != null) {
-      String logical = FileUtil.toSystemIndependentName(VfsUtil.virtualToIoFile(logicalRoot.getVirtualFile()).getPath());
-      String path = FileUtil.toSystemIndependentName(VfsUtil.virtualToIoFile(virtualFile).getPath());
-      return "/" + FileUtil.getRelativePath(logical, path, '/');
+    if (logicalRoot != null && logicalRoot.getVirtualFile() != null) {
+      String logical = FileUtil.toSystemIndependentName(VfsUtilCore.virtualToIoFile(logicalRoot.getVirtualFile()).getPath());
+      String path = FileUtil.toSystemIndependentName(VfsUtilCore.virtualToIoFile(virtualFile).getPath());
+      return ObjectUtils.assertNotNull(FileUtil.getRelativePath(logical, path, '/'));
     }
 
     final VirtualFile contentRoot = ProjectRootManager.getInstance(project).getFileIndex().getContentRootForFile(virtualFile);
     if (contentRoot != null) {
-      return "/" + FileUtil.getRelativePath(VfsUtil.virtualToIoFile(contentRoot), VfsUtil.virtualToIoFile(virtualFile));
-    }
+      return ObjectUtils.assertNotNull(FileUtil.getRelativePath(VfsUtilCore.virtualToIoFile(contentRoot), VfsUtilCore.virtualToIoFile(virtualFile)));
+    }  
     return virtualFile.getPath();
   }
 }
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java
index e95196c..9b8fc33 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/CreateDirectoryOrPackageHandler.java
@@ -28,6 +28,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.InputValidatorEx;
 import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiDirectory;
 import com.intellij.psi.PsiFileSystemItem;
@@ -104,7 +105,7 @@
     }
     
     boolean createFile = false;
-    if (StringUtil.countChars(subDirName, '.') == 1) {
+    if (StringUtil.countChars(subDirName, '.') == 1 && Registry.is("ide.suggest.file.when.creating.filename.like.directory")) {
       FileType fileType = findFileTypeBoundToName(subDirName);
       if (fileType != null) {
         String message = "The name you entered looks like a file name. Do you want to create a file named " + subDirName + " instead?";
diff --git a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
index 558a29c..6da322a 100644
--- a/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
+++ b/platform/lang-impl/src/com/intellij/ide/actions/SearchEverywhereAction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -42,6 +42,7 @@
 import com.intellij.openapi.application.AccessToken;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.actions.TextComponentEditorAction;
+import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
 import com.intellij.openapi.fileEditor.impl.EditorHistoryManager;
 import com.intellij.openapi.keymap.KeymapManager;
@@ -438,10 +439,10 @@
             parent.repaint();
           }
         });
-        if (myPopup != null && myPopup.isVisible()) {
-          myPopup.cancel();
-          myPopup = null;
-        }
+        //if (myPopup != null && myPopup.isVisible()) {
+        //  myPopup.cancel();
+        //  myPopup = null;
+        //}
         rebuildList("");
       }
 
@@ -674,6 +675,7 @@
     myBalloon = builder
       .setCancelOnClickOutside(true)
       .setModalContext(false)
+      .setRequestFocus(true)
       .setCancelCallback(new Computable<Boolean>() {
         @Override
         public Boolean compute() {
@@ -1393,7 +1395,14 @@
     private void buildRecentFiles(String pattern) {
       final MinusculeMatcher matcher = new MinusculeMatcher("*" + pattern, NameUtil.MatchingCaseSensitivity.NONE);
       final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
+      FileEditorManager editorManager = FileEditorManager.getInstance(project);
+      //we skip active editor
+      boolean skip = editorManager.getOpenFiles().length > 1;
       for (VirtualFile file : ArrayUtil.reverseArray(EditorHistoryManager.getInstance(project).getFiles())) {
+        if (skip) {
+          skip = false;
+          continue;
+        }
         if (StringUtil.isEmptyOrSpaces(pattern) || matcher.matches(file.getName())) {
           if (!files.contains(file)) {
             files.add(file);
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
index c9cb262..0b00557 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/AllFileTemplatesConfigurable.java
@@ -358,6 +358,8 @@
   }
 
   private void onTabChanged() {
+    applyEditor(myCurrentTab.getSelectedTemplate());
+    
     final int selectedIndex = myTabbedPane.getSelectedIndex();
     if (0 <= selectedIndex && selectedIndex < myTabs.length) {
       myCurrentTab = myTabs[selectedIndex];
@@ -371,17 +373,8 @@
     if (prevTemplate != selectedValue) {
       LOG.assertTrue(myEditor != null, "selected:" + selectedValue + "; prev:" + prevTemplate);
       //selection has changed
-      if (myEditor.isModified() && Arrays.asList(myCurrentTab.getTemplates()).contains(prevTemplate)) {
-        try {
-          myModified = true;
-          myEditor.apply();
-          fireListChanged();
-        }
-        catch (ConfigurationException e) {
-          myCurrentTab.selectTemplate(prevTemplate);
-          Messages.showErrorDialog(myMainPanel, e.getMessage(), IdeBundle.message("title.cannot.save.current.template"));
-          return;
-        }
+      if (Arrays.asList(myCurrentTab.getTemplates()).contains(prevTemplate) && !applyEditor(prevTemplate)) {
+        return;
       }
       if (selectedValue == null) {
         myEditor.setTemplate(null, FileTemplateManagerImpl.getInstanceImpl().getDefaultTemplateDescription());
@@ -393,6 +386,24 @@
     }
   }
 
+  private boolean applyEditor(FileTemplate prevTemplate) {
+    if (myEditor.isModified()) {
+      try {
+        myModified = true;
+        myEditor.apply();
+        fireListChanged();
+      }
+      catch (ConfigurationException e) {
+        if (Arrays.asList(myCurrentTab.getTemplates()).contains(prevTemplate)) {
+          myCurrentTab.selectTemplate(prevTemplate);
+        }
+        Messages.showErrorDialog(myMainPanel, e.getMessage(), IdeBundle.message("title.cannot.save.current.template"));
+        return false;
+      }
+    }
+    return true;
+  }
+
   private void selectTemplate(FileTemplate template) {
     URL defDesc = null;
     if (myCurrentTab == myTemplatesList) {
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java
index 43833e7..0a1b4a5 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/BundledFileTemplate.java
@@ -101,4 +101,9 @@
   public boolean isTextModified() {
     return !getText().equals(getDefaultText());
   }
+
+  @Override
+  public String toString() {
+    return myDefaultTemplate.getTemplateURL() == null ? "" : myDefaultTemplate.getTemplateURL().toString();
+  }
 }
diff --git a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java
index 1938241..b1b6cec 100644
--- a/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java
+++ b/platform/lang-impl/src/com/intellij/ide/fileTemplates/impl/FTManager.java
@@ -188,7 +188,8 @@
     final FileTemplateBase previous = myTemplates.put(qName, bundled);
     mySortedTemplates = null;
 
-    LOG.assertTrue(previous == null, "Duplicate bundled template " + qName);
+    LOG.assertTrue(previous == null, "Duplicate bundled template " + qName +
+                                     " [" + template.getTemplateURL() + ", " + previous + ']');
     return bundled;
   }
 
diff --git a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/AbstractNavBarModelExtension.java b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/AbstractNavBarModelExtension.java
index 91202fb..50079c0 100644
--- a/platform/lang-impl/src/com/intellij/ide/navigationToolbar/AbstractNavBarModelExtension.java
+++ b/platform/lang-impl/src/com/intellij/ide/navigationToolbar/AbstractNavBarModelExtension.java
@@ -27,12 +27,10 @@
 /**
  * @author gregsh
  */
-public class AbstractNavBarModelExtension implements NavBarModelExtension {
+public abstract class AbstractNavBarModelExtension implements NavBarModelExtension {
   @Nullable
   @Override
-  public String getPresentableText(Object object) {
-    return null;
-  }
+  public abstract String getPresentableText(Object object);
 
   @Nullable
   @Override
diff --git a/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java b/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java
index 4f7cae42..dd46f64 100644
--- a/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java
+++ b/platform/lang-impl/src/com/intellij/ide/projectView/BaseProjectTreeBuilder.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -406,7 +406,8 @@
           }
         }
       } else {
-        async.setRejected();
+        //filter tells us to stop here (for instance, in case of module nodes)
+        break;
       }
     }
     async.setRejected();
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java
index 51f9330..108868c 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileCellRenderer.java
@@ -82,7 +82,7 @@
   }
 
   @Nullable
-  private static String getRelativePath(final VirtualFile virtualFile, final Project project) {
+  static String getRelativePath(final VirtualFile virtualFile, final Project project) {
     String url = virtualFile.getPresentableUrl();
     if (project == null) {
       return url;
diff --git a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
index 49081c71..de43de5 100644
--- a/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
+++ b/platform/lang-impl/src/com/intellij/ide/util/gotoByName/GotoFileModel.java
@@ -128,7 +128,7 @@
   public String getFullName(final Object element) {
     if (element instanceof PsiFileSystemItem) {
       final VirtualFile virtualFile = ((PsiFileSystemItem)element).getVirtualFile();
-      return virtualFile != null ? virtualFile.getPath() : null;
+      return virtualFile != null ? GotoFileCellRenderer.getRelativePath(virtualFile, myProject) : null;
     }
 
     return getElementName(element);
diff --git a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
index 6053d01..e5f458a 100644
--- a/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
+++ b/platform/lang-impl/src/com/intellij/platform/ModuleAttachProcessor.java
@@ -161,6 +161,11 @@
     if (!canAttachToProject()) {
       return null;
     }
+    return findModuleInBaseDir(project);
+  }
+
+  @Nullable
+  public static Module findModuleInBaseDir(Project project) {
     for (Module module : ModuleManager.getInstance(project).getModules()) {
       final VirtualFile[] roots = ModuleRootManager.getInstance(module).getContentRoots();
       for (VirtualFile root : roots) {
diff --git a/platform/lang-impl/src/com/intellij/platform/renameProject/RenameProjectHandler.java b/platform/lang-impl/src/com/intellij/platform/renameProject/RenameProjectHandler.java
index 9baec60..2d44c867 100644
--- a/platform/lang-impl/src/com/intellij/platform/renameProject/RenameProjectHandler.java
+++ b/platform/lang-impl/src/com/intellij/platform/renameProject/RenameProjectHandler.java
@@ -33,6 +33,7 @@
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Ref;
 import com.intellij.platform.ModuleAttachProcessor;
+import com.intellij.projectImport.ProjectAttachProcessor;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.refactoring.RefactoringBundle;
@@ -101,7 +102,7 @@
 
     @Override
     public boolean canClose(final String inputString) {
-      if (!inputString.equals(myProject.getName()) && (myModule == null || myModule == ModuleAttachProcessor.getPrimaryModule(myProject))) {
+      if (shouldRenameProject(inputString)) {
         myProject.setProjectName(inputString);
         myProject.save();
       }
@@ -132,5 +133,21 @@
       }
       return true;
     }
+
+    private boolean shouldRenameProject(String inputString) {
+      if (inputString.equals(myProject.getName())) {
+        return false;
+      }
+
+      if (myModule == null) {
+        return true;
+      }
+
+      if (ProjectAttachProcessor.canAttachToProject()) {
+        return myModule == ModuleAttachProcessor.getPrimaryModule(myProject);
+      }
+
+      return myModule == ModuleAttachProcessor.findModuleInBaseDir(myProject);
+    }
   }
 }
diff --git a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
index bb98b70..1e8c431 100644
--- a/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
+++ b/platform/lang-impl/src/com/intellij/util/indexing/FileBasedIndexImpl.java
@@ -2457,7 +2457,8 @@
 
   @Override
   public void removeIndexableSet(@NotNull IndexableFileSet set) {
-    myChangedFilesCollector.forceUpdate(null, null, null, true);
+    if (!myIndexableSetToProjectMap.containsKey(set)) return; // avoid second unfiltered forceUpdate
+    myChangedFilesCollector.forceUpdate(myIndexableSetToProjectMap.get(set), null, null, true);
     IndexingStamp.flushCaches();
     myIndexableSets.remove(set);
     myIndexableSetToProjectMap.remove(set);
diff --git a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
index a024b5b..edcc97e 100644
--- a/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
+++ b/platform/platform-api/src/com/intellij/openapi/fileChooser/FileChooserDescriptor.java
@@ -81,27 +81,24 @@
     return myTitle;
   }
 
-  public final FileChooserDescriptor setTitle(String title) {
+  public final void setTitle(String title) {
     myTitle = title;
-    return this;
   }
 
   public boolean isShowFileSystemRoots() {
     return myShowFileSystemRoots;
   }
 
-  public FileChooserDescriptor setShowFileSystemRoots(boolean showFileSystemRoots) {
+  public void setShowFileSystemRoots(boolean showFileSystemRoots) {
     myShowFileSystemRoots = showFileSystemRoots;
-    return this;
   }
 
   public final String getDescription() {
     return myDescription;
   }
 
-  public final FileChooserDescriptor setDescription(String description) {
+  public final void setDescription(String description) {
     myDescription = description;
-    return this;
   }
 
   public final boolean isChooseJarContents() {
@@ -185,7 +182,6 @@
   /**
    * the method is called upon pressing Ok in the FileChooserDialog
    * Override the method in order to customize validation of user input
-   *
    * @param files - selected files to be checked
    * @throws Exception if the the files cannot be accepted
    */
@@ -220,23 +216,21 @@
     return JarFileSystem.getInstance().findFileByPath(path + JarFileSystem.JAR_SEPARATOR);
   }
 
-  public final FileChooserDescriptor setHideIgnored(boolean hideIgnored) {
+  public final void setHideIgnored(boolean hideIgnored) {
     myHideIgnored = hideIgnored;
-    return this;
   }
 
   public final List<VirtualFile> getRoots() {
     return Collections.unmodifiableList(myRoots);
   }
 
-  public final FileChooserDescriptor setRoots(final VirtualFile... roots) {
-    return setRoots(Arrays.asList(roots));
+  public final void setRoots(final VirtualFile... roots) {
+    setRoots(Arrays.asList(roots));
   }
 
-  public final FileChooserDescriptor setRoots(@NotNull final List<VirtualFile> roots) {
+  public final void setRoots(@NotNull final List<VirtualFile> roots) {
     myRoots.clear();
     myRoots.addAll(roots);
-    return this;
   }
 
   public boolean isTreeRootVisible() {
diff --git a/platform/platform-api/src/com/intellij/ui/AnActionButton.java b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
index ca69508..0e84519 100644
--- a/platform/platform-api/src/com/intellij/ui/AnActionButton.java
+++ b/platform/platform-api/src/com/intellij/ui/AnActionButton.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.ui;
 
+import com.intellij.ide.DataManager;
 import com.intellij.openapi.actionSystem.*;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.util.ui.UIUtil;
@@ -130,6 +131,10 @@
     return myContextComponent;
   }
 
+  public DataContext getDataContext() {
+    return DataManager.getInstance().getDataContext(getContextComponent());
+  }
+
   private boolean isContextComponentOk() {
     return myContextComponent == null
            || (myContextComponent.isVisible() && UIUtil.getParentOfType(JLayeredPane.class, myContextComponent) != null);
diff --git a/platform/platform-api/src/com/intellij/ui/DumbAwareActionButton.java b/platform/platform-api/src/com/intellij/ui/DumbAwareActionButton.java
new file mode 100644
index 0000000..552ee96
--- /dev/null
+++ b/platform/platform-api/src/com/intellij/ui/DumbAwareActionButton.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.openapi.project.DumbAware;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author gregsh
+ */
+public abstract class DumbAwareActionButton extends AnActionButton implements DumbAware {
+  public DumbAwareActionButton(String text) {
+    super(text);
+  }
+
+  public DumbAwareActionButton(String text, String description, @Nullable Icon icon) {
+    super(text, description, icon);
+  }
+
+  public DumbAwareActionButton(String text, Icon icon) {
+    super(text, icon);
+  }
+
+  public DumbAwareActionButton() {
+  }
+}
diff --git a/platform/platform-api/src/com/intellij/ui/table/JBTable.java b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
index ea2eebb..f7f183f 100644
--- a/platform/platform-api/src/com/intellij/ui/table/JBTable.java
+++ b/platform/platform-api/src/com/intellij/ui/table/JBTable.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -449,6 +449,7 @@
     return UIUtil.isUnderAlloyLookAndFeel()
            || UIUtil.isUnderNativeMacLookAndFeel()
            || UIUtil.isUnderDarcula()
+           || UIUtil.isUnderIntelliJLaF()
            || UIUtil.isUnderNimbusLookAndFeel()
            || UIUtil.isUnderWindowsLookAndFeel();
   }
diff --git a/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java b/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java
new file mode 100644
index 0000000..39fa3c23
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/diagnostic/DebugLogManager.java
@@ -0,0 +1,100 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.diagnostic;
+
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.apache.log4j.Level;
+import org.apache.log4j.LogManager;
+import com.intellij.openapi.diagnostic.Logger;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collections;
+import java.util.Enumeration;
+import java.util.List;
+
+/**
+ * Allows to apply & persist custom log debug categories which can be turned on by user via the {@link com.intellij.ide.actions.DebugLogConfigureAction}. <br/>
+ * Applies these custom categories on startup.
+ */
+public class DebugLogManager extends ApplicationComponent.Adapter {
+
+  private static final Logger LOG = Logger.getInstance(DebugLogManager.class);
+  private static final String LOG_DEBUG_CATEGORIES = "log.debug.categories";
+
+  @Override
+  public void initComponent() {
+    List<String> categories = getSavedCategories();
+    if (categories.isEmpty()) {
+      saveCategories(getCurrentCategories());
+    }
+    else {
+      applyCategories(categories);
+    }
+  }
+
+  @NotNull
+  public List<String> getSavedCategories() {
+    String value = PropertiesComponent.getInstance().getValue(LOG_DEBUG_CATEGORIES);
+    return value == null ? Collections.<String>emptyList() : fromString(value);
+  }
+
+  public void applyCategories(@NotNull List<String> categories) {
+    for (String category : categories) {
+      org.apache.log4j.Logger logger = LogManager.getLogger(category);
+      if (logger != null) {
+        logger.setLevel(Level.DEBUG);
+      }
+    }
+    LOG.info("Set DEBUG for the following categories: " + categories);
+  }
+
+  public void saveCategories(@NotNull List<String> categories) {
+    PropertiesComponent.getInstance().setValue(LOG_DEBUG_CATEGORIES, toString(categories));
+  }
+
+  @NotNull
+  private static List<String> fromString(@NotNull String text) {
+    return Arrays.asList(StringUtil.splitByLines(text, true));
+  }
+
+  @NotNull
+  private static String toString(@NotNull List<String> categories) {
+    return StringUtil.join(categories, "\n");
+  }
+
+  @NotNull
+  private static List<String> getCurrentCategories() {
+    Enumeration currentLoggers = LogManager.getCurrentLoggers();
+    return ContainerUtil.mapNotNull(ContainerUtil.toList(currentLoggers), new Function<Object, String>() {
+      @Override
+      public String fun(Object o) {
+        if (o instanceof org.apache.log4j.Logger) {
+          String category = ((org.apache.log4j.Logger)o).getName();
+          if (Logger.getInstance(category).isDebugEnabled()) {
+            return category;
+          }
+        }
+        return null;
+      }
+    });
+  }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
index 9e67590..96d11aa 100644
--- a/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
+++ b/platform/platform-impl/src/com/intellij/ide/IdeEventQueue.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -692,6 +692,7 @@
       myDispatchingFocusEvent = e instanceof FocusEvent;
 
       maybeReady();
+      fixStickyAlt(e);
 
       super.dispatchEvent(e);
     }
@@ -705,6 +706,13 @@
     }
   }
 
+  //IDEA-17359
+  private static void fixStickyAlt(AWTEvent e) {
+    if (SystemInfo.isWindowsXP && e instanceof KeyEvent && ((KeyEvent)e).getKeyCode() == KeyEvent.VK_ALT) {
+      ((KeyEvent)e).consume();
+    }
+  }
+
   public boolean isDispatchingFocusEvent() {
     return myDispatchingFocusEvent;
   }
@@ -889,6 +897,8 @@
       boolean dispatch = true;
       if (e instanceof KeyEvent) {
         KeyEvent ke = (KeyEvent)e;
+        final Component component = ke.getComponent();
+        final Window window = component == null ? null : SwingUtilities.windowForComponent(component);
         boolean pureAlt = ke.getKeyCode() == KeyEvent.VK_ALT && (ke.getModifiers() | InputEvent.ALT_MASK) == InputEvent.ALT_MASK;
         if (!pureAlt) {
           myPureAltWasPressed = false;
@@ -917,10 +927,14 @@
             }
             else {
               myWaiterScheduled = true;
+              //noinspection SSBasedInspection
               SwingUtilities.invokeLater(new Runnable() {
                 @Override
                 public void run() {
                   try {
+                    if (SystemInfo.isWindows || window == null || !window.isActive()) {
+                      return;
+                    }
                     myWaitingForAltRelease = true;
                     if (myRobot == null) {
                       myRobot = new Robot();
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java b/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java
new file mode 100644
index 0000000..8cefd4e
--- /dev/null
+++ b/platform/platform-impl/src/com/intellij/ide/actions/DebugLogConfigureAction.java
@@ -0,0 +1,91 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.actions;
+
+import com.intellij.diagnostic.DebugLogManager;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.DumbAwareAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.project.ProjectManager;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.ui.ScrollPaneFactory;
+import com.intellij.ui.components.JBLabel;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.List;
+
+public class DebugLogConfigureAction extends DumbAwareAction {
+
+  @Override
+  public void actionPerformed(AnActionEvent e) {
+    Project project = e.getProject() == null ? ProjectManager.getInstance().getDefaultProject() : e.getProject();
+    DebugLogManager logCustomizer = ServiceManager.getService(DebugLogManager.class);
+    DebugLogConfigureDialog dialog = new DebugLogConfigureDialog(project, logCustomizer.getSavedCategories());
+    if (dialog.showAndGet()) {
+      List<String> categories = dialog.getLogCategories();
+      logCustomizer.applyCategories(categories);
+      logCustomizer.saveCategories(categories);
+    }
+  }
+
+  private static class DebugLogConfigureDialog extends DialogWrapper {
+
+    private static final String ALL_POSSIBLE_SEPARATORS = "(\n|,|;)+";
+    @NotNull private final JTextArea myTextArea;
+
+    protected DebugLogConfigureDialog(@Nullable Project project, List<String> categories) {
+      super(project, false);
+      myTextArea = new JTextArea(10, 30);
+      myTextArea.setText(StringUtil.join(categories, "\n"));
+      setTitle("Custom Debug Log Configuration");
+      init();
+    }
+
+    @Nullable
+    @Override
+    protected JComponent createNorthPanel() {
+      return new JBLabel("Add log categories separated by new lines");
+    }
+
+    @Nullable
+    @Override
+    protected JComponent createCenterPanel() {
+      return ScrollPaneFactory.createScrollPane(myTextArea);
+    }
+
+    @NotNull
+    public List<String> getLogCategories() {
+      return parseCategories(myTextArea.getText());
+    }
+
+    @NotNull
+    private static List<String> parseCategories(@NotNull String text) {
+      return ContainerUtil.mapNotNull(text.split(ALL_POSSIBLE_SEPARATORS), new Function<String, String>() {
+        @Override
+        public String fun(String s) {
+          return StringUtil.isEmptyOrSpaces(s) ? null : s.trim();
+        }
+      });
+    }
+  }
+
+}
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java b/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java
index 47cb36d..b05f142 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/ShowRecentFilesAction.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -23,7 +23,6 @@
 import com.intellij.ide.IdeBundle;
 import com.intellij.openapi.actionSystem.AnActionEvent;
 import com.intellij.openapi.actionSystem.CommonDataKeys;
-import com.intellij.openapi.fileEditor.ex.FileEditorManagerEx;
 import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 
@@ -36,10 +35,7 @@
     final Project project = e.getData(CommonDataKeys.PROJECT);
     if (project != null) {
       FeatureUsageTracker.getInstance().triggerFeatureUsed("navigation.recent.files");
-      final Switcher.SwitcherPanel switcher = Switcher.createAndShowSwitcher(project, IdeBundle.message("title.popup.recent.files"), true);
-      if (FileEditorManagerEx.getInstanceEx(project).hasOpenedFile()) {
-        switcher.goForward();
-      }
+      Switcher.createAndShowSwitcher(project, IdeBundle.message("title.popup.recent.files"), true);
     }
   }
 }
diff --git a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
index 57b707b..8884e7d 100644
--- a/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
+++ b/platform/platform-impl/src/com/intellij/ide/actions/Switcher.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -345,7 +345,12 @@
         final int maxFiles = Math.max(editors.size(), recentFiles.length);
         final int len = isPinnedMode() ? recentFiles.length : Math.min(toolWindows.getModel().getSize(), maxFiles);
         boolean firstRecentMarked = false;
+        final List<VirtualFile> selectedFiles = Arrays.asList(editorManager.getSelectedFiles());
         for (int i = 0; i < len; i++) {
+          if (isPinnedMode() && selectedFiles.contains(recentFiles[i])) {
+            continue;
+          }
+
           final FileInfo info = new FileInfo(recentFiles[i], null);
           boolean add = true;
           if (isPinnedMode()) {
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
index a708844..f858002 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/DarculaLaf.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -227,6 +227,7 @@
       //"ENTER", "selectNextRowCell",
       "shift ENTER", "selectPreviousRowCell",
       "ctrl A", "selectAll",
+      "meta A", "selectAll",
       //"ESCAPE", "cancel",
       "F2", "startEditing"
     }));
diff --git a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java
index cc09036..0eba3d3 100644
--- a/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java
+++ b/platform/platform-impl/src/com/intellij/ide/ui/laf/darcula/ui/DarculaComboBoxUI.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -309,14 +309,19 @@
       comboBoxEditor.getEditorComponent().addFocusListener(new FocusAdapter() {
         @Override
         public void focusGained(FocusEvent e) {
-          comboBox.revalidate();
-          comboBox.repaint();
+          update();
+        }
+
+        void update() {
+          if (comboBox != null) {
+            comboBox.revalidate();
+            comboBox.repaint();
+          }
         }
 
         @Override
         public void focusLost(FocusEvent e) {
-          comboBox.revalidate();
-          comboBox.repaint();
+          update();
         }
       });
     }
diff --git a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/OpenFilesActivity.java b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/OpenFilesActivity.java
index 94d0883..62866d3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/OpenFilesActivity.java
+++ b/platform/platform-impl/src/com/intellij/openapi/fileEditor/impl/OpenFilesActivity.java
@@ -16,8 +16,6 @@
 package com.intellij.openapi.fileEditor.impl;
 
 import com.intellij.openapi.fileEditor.FileEditorManager;
-import com.intellij.openapi.progress.ProgressIndicator;
-import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.startup.StartupActivity;
@@ -44,15 +42,7 @@
         }
       };
       if (Registry.is("ide.open.editors.asynchronously")) {
-        ProgressIndicator indicator = ProgressManager.getInstance().getProgressIndicator();
-        if (indicator != null) {
-          indicator.pushState();
-          indicator.setText("Preparing editors to open...");
-        }
         runnable.run();
-        if (indicator != null) {
-          indicator.popState();
-        }
       }
       else {
         UIUtil.invokeLaterIfNeeded(runnable);
diff --git a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
index 5164807..5d27509 100644
--- a/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
+++ b/platform/platform-impl/src/com/intellij/openapi/vfs/ex/dummy/DummyCachingFileSystem.java
@@ -114,6 +114,7 @@
     throw new UnsupportedOperationException("not implemented");
   }
 
+  @Nullable
   public Project getProject(String projectId) {
     List<Project> list = myProject2Id.getKeysByValue(projectId);
     return list == null || list.size() > 1 ? null : list.get(0);
diff --git a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
index 08504b9..d4477a3 100644
--- a/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
+++ b/platform/platform-impl/src/com/intellij/openapi/wm/impl/status/ToolWindowsWidget.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -26,6 +26,7 @@
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.openapi.ui.popup.PopupChooserBuilder;
 import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.SystemInfo;
 import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.wm.*;
 import com.intellij.openapi.wm.impl.IdeFrameImpl;
@@ -110,7 +111,7 @@
               popup.cancel();
             }
           }
-        }, 150);
+        }, 300);
         return true;
       }
     }
@@ -155,7 +156,7 @@
           final Dimension size = list.getPreferredSize();
           final JComponent c = ToolWindowsWidget.this;
           final Insets padding = UIUtil.getListViewportPadding();
-          final RelativePoint point = new RelativePoint(c, new Point(-4, -padding.top - padding.bottom -4 - size.height));
+          final RelativePoint point = new RelativePoint(c, new Point(-4, -padding.top - padding.bottom -4 - size.height + (SystemInfo.isMac ? 2 : 0)));
 
           if (popup != null && popup.isVisible()) {
             return;
diff --git a/platform/platform-resources-en/src/messages/ActionsBundle.properties b/platform/platform-resources-en/src/messages/ActionsBundle.properties
index 87e2cb1..a65aac0 100644
--- a/platform/platform-resources-en/src/messages/ActionsBundle.properties
+++ b/platform/platform-resources-en/src/messages/ActionsBundle.properties
@@ -1062,6 +1062,8 @@
 
 action.SendFeedback.text=Submit _Feedback
 action.SendFeedback.description=Submit feedback to the JetBrains Web site
+action.LogDebugConfigure.text=Configure Debug Log Settings
+action.LogDebugConfigure.description=Enable or disable additional log categories. Allows to provide more information to the support team by request.
 action.ShowLog.text=Open Log file
 action.ShowLog.description=Opens folder with log file
 action.TechnicalSupport.text=Contact _Support Team
diff --git a/platform/platform-resources-en/src/misc/registry.properties b/platform/platform-resources-en/src/misc/registry.properties
index a12f869..9dfe64a 100644
--- a/platform/platform-resources-en/src/misc/registry.properties
+++ b/platform/platform-resources-en/src/misc/registry.properties
@@ -216,6 +216,9 @@
 psi.viewer.selection.color=0,153,153
 psi.deferIconLoading=true
 
+ide.suggest.file.when.creating.filename.like.directory=true
+ide.suggest.file.when.creating.filename.like.directory.description=When creating a directory named foo.txt, suggest to create a file with such a name instead
+
 find.search.in.project.files=false
 
 structureView.coalesceTime=500
@@ -235,6 +238,7 @@
 projectView.hide.dot.idea=true
 show.live.templates.in.completion=false
 ide.completion.autopopup.select.live.templates=false
+ide.completion.autopopup.choose.by.enter=true
 documentation.component.editor.font=false
 
 ide.completion.show.better.matching.classes=true
diff --git a/platform/platform-resources/src/componentSets/Platform.xml b/platform/platform-resources/src/componentSets/Platform.xml
index 93daf4f..ef911ec 100644
--- a/platform/platform-resources/src/componentSets/Platform.xml
+++ b/platform/platform-resources/src/componentSets/Platform.xml
@@ -137,6 +137,10 @@
       <implementation-class>com.intellij.ide.SystemHealthMonitor</implementation-class>
       <headless-implementation-class/>
     </component>
+
+    <component>
+      <implementation-class>com.intellij.diagnostic.DebugLogManager</implementation-class>
+    </component>
   </application-components>
 
   <project-components>
diff --git a/platform/platform-resources/src/idea/PlatformActions.xml b/platform/platform-resources/src/idea/PlatformActions.xml
index f5ac0d5..f31b83c 100644
--- a/platform/platform-resources/src/idea/PlatformActions.xml
+++ b/platform/platform-resources/src/idea/PlatformActions.xml
@@ -409,6 +409,7 @@
         <separator/>
         <action id="TechnicalSupport" class="com.intellij.ide.actions.TechnicalSupportAction"/>
         <action id="SendFeedback" class="com.intellij.ide.actions.SendFeedbackAction"/>
+        <action id="LogDebugConfigure" class="com.intellij.ide.actions.DebugLogConfigureAction"/>
         <action id="ShowLog" class="com.intellij.ide.actions.ShowLogAction"/>
         <separator/>
         <action id="OnlineDocAction" class="com.intellij.ide.actions.OnlineDocAction"/>
diff --git a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java
index 06913a5..06815acf 100644
--- a/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java
+++ b/platform/usageView/src/com/intellij/usages/impl/UsageViewTreeCellRenderer.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -18,19 +18,24 @@
 import com.intellij.navigation.ItemPresentation;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.FileStatus;
 import com.intellij.ui.ColoredTreeCellRenderer;
+import com.intellij.ui.DarculaColors;
 import com.intellij.ui.SimpleTextAttributes;
 import com.intellij.ui.speedSearch.SpeedSearchUtil;
 import com.intellij.usageView.UsageTreeColors;
 import com.intellij.usageView.UsageTreeColorsScheme;
 import com.intellij.usageView.UsageViewBundle;
 import com.intellij.usages.*;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import javax.swing.tree.DefaultMutableTreeNode;
+import java.awt.*;
 
 /**
  * @author max
@@ -40,6 +45,7 @@
   private static final EditorColorsScheme ourColorsScheme = UsageTreeColorsScheme.getInstance().getScheme();
   private static final SimpleTextAttributes ourInvalidAttributes = SimpleTextAttributes.fromTextAttributes(ourColorsScheme.getAttributes(UsageTreeColors.INVALID_PREFIX));
   private static final SimpleTextAttributes ourReadOnlyAttributes = SimpleTextAttributes.fromTextAttributes(ourColorsScheme.getAttributes(UsageTreeColors.READONLY_PREFIX));
+  private static final SimpleTextAttributes ourInvalidAttributesDarcula = new SimpleTextAttributes(null, DarculaColors.RED, null, ourInvalidAttributes.getStyle());
 
   private final SimpleTextAttributes myNumberOfUsagesAttribute;
   private final UsageViewPresentation myPresentation;
@@ -57,7 +63,7 @@
     if (value instanceof Node && tree != null && value != tree.getModel().getRoot()) {
       Node node = (Node)value;
       if (!node.isValid()) {
-        append(UsageViewBundle.message("node.invalid") + " ", ourInvalidAttributes);
+        append(UsageViewBundle.message("node.invalid") + " ", UIUtil.isUnderDarcula() ? ourInvalidAttributesDarcula : ourInvalidAttributes);
       }
       if (myPresentation.isShowReadOnlyStatusAsRed() && node.isReadOnly()) {
         showAsReadOnly = true;
diff --git a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
index 453b3bd..2304be0 100644
--- a/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
+++ b/platform/util-rt/src/com/intellij/util/containers/ContainerUtilRt.java
@@ -21,6 +21,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.io.Serializable;
 import java.util.*;
 import java.util.HashMap;
 import java.util.HashSet;
@@ -236,7 +237,9 @@
    * A variant of {@link java.util.Collections#emptyList()},
    * except that {@link #toArray()} here does not create garbage <code>new Object[0]</code> constantly.
    */
-  private static class EmptyList<T> extends AbstractList<T> implements RandomAccess {
+  private static class EmptyList<T> extends AbstractList<T> implements RandomAccess, Serializable {
+    private static final long serialVersionUID = 1L;
+
     private static final EmptyList INSTANCE = new EmptyList();
 
     @Override
diff --git a/platform/util/src/com/intellij/openapi/util/SystemInfo.java b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
index c5ce5bb..aff4475 100644
--- a/platform/util/src/com/intellij/openapi/util/SystemInfo.java
+++ b/platform/util/src/com/intellij/openapi/util/SystemInfo.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2013 JetBrains s.r.o.
+ * Copyright 2000-2014 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -52,6 +52,7 @@
   public static final boolean isWin2kOrNewer = isWindows && isOsVersionAtLeast("5.0");
   public static final boolean isWinVistaOrNewer = isWindows && isOsVersionAtLeast("6.0");
   public static final boolean isWin7OrNewer = isWindows && isOsVersionAtLeast("6.1");
+  public static final boolean isWindowsXP = isWindows && (OS_VERSION.equals("5.1") || OS_VERSION.equals("5.2"));
 
   public static final boolean isXWindow = isUnix && !isMac;
 
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogBranchFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogBranchFilter.java
new file mode 100644
index 0000000..2b658cb
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogBranchFilter.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Tells to filter by some branch name.
+ */
+public interface VcsLogBranchFilter extends VcsLogFilter {
+
+  @NotNull
+  String getBranchName();
+
+}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java
new file mode 100644
index 0000000..d080b67
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogDateFilter.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log;
+
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Date;
+
+/**
+ * Tells to filter by date. <br/>
+ * Only before or after dates can be given, or both can be given.
+ */
+public interface VcsLogDateFilter {
+
+  /**
+   * If not null, only commits made after the returned date (inclusively) should be accepted.
+   */
+  @Nullable
+  Date getAfter();
+
+  /**
+   * If not null, only commits made before the returned date (inclusively) should be accepted.
+   */
+  @Nullable
+  Date getBefore();
+
+}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
index 0a73027..ae8ee64 100644
--- a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogProvider.java
@@ -84,7 +84,12 @@
    */
   @NotNull
   List<? extends VcsFullCommitDetails> getFilteredDetails(@NotNull VirtualFile root,
-                                                          @NotNull Collection<VcsLogFilter> filters, int maxCount) throws VcsException;
+                                                          @NotNull Collection<VcsLogBranchFilter> branchFilters,
+                                                          @NotNull Collection<VcsLogUserFilter> userFilters,
+                                                          @NotNull Collection<VcsLogDateFilter> dateFilters,
+                                                          @NotNull Collection<VcsLogTextFilter> textFilters,
+                                                          @NotNull Collection<VcsLogStructureFilter> structureFilters,
+                                                          int maxCount) throws VcsException;
 
   /**
    * Returns the name of current user as specified for the given root,
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java
new file mode 100644
index 0000000..dd0ed62
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogStructureFilter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+
+/**
+ * Tells the log to filter by files and folders.
+ */
+public interface VcsLogStructureFilter {
+
+  /**
+   * <p>Returns files from the given VCS root, which are affected by matching commits, and folders containing such files.</p>
+   *
+   * <p>That is: the commit A (made in the given VCS root) modifying file f.txt matches this filter,
+   *    if this method returns a set which includes a folder containing f.txt, or the file f.txt itself.</p>
+   */
+  @NotNull
+  Collection<VirtualFile> getFiles(@NotNull VirtualFile root);
+
+}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java
new file mode 100644
index 0000000..06d84e9
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogTextFilter.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.vcs.log;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Specifies the log filter by text.
+ */
+public interface VcsLogTextFilter {
+
+  /**
+   * Only commits containing the returned text it their commit messages should match the filter.
+   */
+  @NotNull
+  String getText();
+
+}
diff --git a/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java
new file mode 100644
index 0000000..1cd6d95
--- /dev/null
+++ b/platform/vcs-log/api/src/com/intellij/vcs/log/VcsLogUserFilter.java
@@ -0,0 +1,18 @@
+package com.intellij.vcs.log;
+
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Filters log by user.
+ */
+public interface VcsLogUserFilter extends VcsLogFilter {
+
+  /**
+   * Returns the user name selected in the filter for the given root.
+   * If it is a name-as-text filter, of course, values don't differ per root. The difference appears if the special "me" filter is used.
+   */
+  @NotNull
+  String getUserName(@NotNull VirtualFile root);
+
+}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilterImpl.java
similarity index 77%
rename from platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilter.java
rename to platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilterImpl.java
index f7a4a62..90ca1e3 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilter.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogBranchFilterImpl.java
@@ -2,17 +2,18 @@
 
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.VcsLogBranchFilter;
 import com.intellij.vcs.log.VcsRef;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.Collection;
 
-public class VcsLogBranchFilter implements VcsLogGraphFilter {
+public class VcsLogBranchFilterImpl implements VcsLogBranchFilter, VcsLogGraphFilter {
 
   @NotNull private final Collection<Integer> myMatchingHeads;
   @NotNull private final String myBranchName;
 
-  public VcsLogBranchFilter(@NotNull Collection<VcsRef> allRefs, @NotNull final String selectedBranchName) {
+  public VcsLogBranchFilterImpl(@NotNull Collection<VcsRef> allRefs, @NotNull final String selectedBranchName) {
     myBranchName = selectedBranchName;
     myMatchingHeads = ContainerUtil.mapNotNull(allRefs, new Function<VcsRef, Integer>() {
       @Override
@@ -35,6 +36,7 @@
     return "on: " + myBranchName;
   }
 
+  @Override
   @NotNull
   public String getBranchName() {
     return myBranchName;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
index 547bb24..f18697a 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDataHolder.java
@@ -24,6 +24,7 @@
 import com.intellij.openapi.progress.Task;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Disposer;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.vcs.VcsException;
@@ -485,11 +486,25 @@
     runInBackground(new ThrowableConsumer<ProgressIndicator, VcsException>() {
       @Override
       public void consume(ProgressIndicator indicator) throws VcsException {
+        List<VcsLogBranchFilter> branchFilters = ContainerUtil.findAll(filters, VcsLogBranchFilter.class);
+        List<VcsLogUserFilter> userFilters = ContainerUtil.findAll(filters, VcsLogUserFilter.class);
+        List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
+        List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
+        List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
 
         Collection<List<? extends TimedVcsCommit>> logs = ContainerUtil.newArrayList();
         final Map<Hash, VcsFullCommitDetails> allDetails = ContainerUtil.newHashMap();
         for (Map.Entry<VirtualFile, VcsLogProvider> entry : myLogProviders.entrySet()) {
-          List<? extends VcsFullCommitDetails> details = entry.getValue().getFilteredDetails(entry.getKey(), filters, maxCount);
+          VirtualFile root = entry.getKey();
+
+          List<VcsLogStructureFilter> rootMatchingStructureFilters = filterStructureFiltersByRoot(root, structureFilters);
+          if (rootMatchingStructureFilters.isEmpty() && !structureFilters.isEmpty()) {
+            // there were structure filters but none matches the root
+            continue;
+          }
+
+          List<? extends VcsFullCommitDetails> details = entry.getValue().getFilteredDetails(
+            root, branchFilters, userFilters, dateFilters, textFilters, rootMatchingStructureFilters, maxCount);
           logs.add(getCommitsFromDetails(details));
           for (VcsFullCommitDetails detail : details) {
             allDetails.put(detail.getHash(), detail);
@@ -530,6 +545,17 @@
   }
 
   @NotNull
+  private static List<VcsLogStructureFilter> filterStructureFiltersByRoot(@NotNull final VirtualFile root,
+                                                                          @NotNull List<VcsLogStructureFilter> structureFilters) {
+    return ContainerUtil.filter(structureFilters, new Condition<VcsLogStructureFilter>() {
+      @Override
+      public boolean value(VcsLogStructureFilter filter) {
+        return !filter.getFiles(root).isEmpty();
+      }
+    });
+  }
+
+  @NotNull
   public Map<VirtualFile, VcsUser> getCurrentUser() {
     return myCurrentUser;
   }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java
similarity index 85%
rename from platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilter.java
rename to platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java
index 52103a5..c879ddd 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilter.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogDateFilterImpl.java
@@ -16,17 +16,18 @@
 package com.intellij.vcs.log.data;
 
 import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsLogDateFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Date;
 
-public class VcsLogDateFilter implements VcsLogDetailsFilter {
+public class VcsLogDateFilterImpl implements VcsLogDateFilter, VcsLogDetailsFilter {
 
   @Nullable private final Date myAfter;
   @Nullable private final Date myBefore;
 
-  public VcsLogDateFilter(@Nullable Date after, @Nullable Date before) {
+  public VcsLogDateFilterImpl(@Nullable Date after, @Nullable Date before) {
     myAfter = after;
     myBefore = before;
   }
@@ -44,11 +45,13 @@
     return matches;
   }
 
+  @Override
   @Nullable
   public Date getAfter() {
     return myAfter;
   }
 
+  @Override
   @Nullable
   public Date getBefore() {
     return myBefore;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
index 2c30111..da4d79d 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogFilterer.java
@@ -3,6 +3,7 @@
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.util.Ref;
 import com.intellij.util.Consumer;
 import com.intellij.util.Function;
@@ -87,13 +88,13 @@
         myUI.updateUI();
 
         if (model.getRowCount() == 0) {
-          model.requestToLoadMore();
+          model.requestToLoadMore(EmptyRunnable.INSTANCE);
         }
       }
     });
   }
 
-  public void requestVcs(@NotNull Collection<VcsLogFilter> filters, final LoadMoreStage loadMoreStage) {
+  public void requestVcs(@NotNull Collection<VcsLogFilter> filters, final LoadMoreStage loadMoreStage, @NotNull final Runnable onSuccess) {
     ApplicationManager.getApplication().assertIsDispatchThread();
     int maxCount;
     if (loadMoreStage == LoadMoreStage.INITIAL) {
@@ -108,6 +109,7 @@
         LoadMoreStage newLoadMoreStage = advanceLoadMoreStage(loadMoreStage);
         myUI.setModel(new NoGraphTableModel(myUI, details, myLogDataHolder.getDataPack().getRefsModel(), newLoadMoreStage));
         myUI.updateUI();
+        onSuccess.run();
       }
     }, maxCount);
   }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilterImpl.java
similarity index 91%
rename from platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilter.java
rename to platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilterImpl.java
index 6a0f4e3..678cfd6 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilter.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogStructureFilterImpl.java
@@ -24,17 +24,18 @@
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
 import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsLogStructureFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.Collection;
 
-public class VcsLogStructureFilter implements VcsLogDetailsFilter {
+public class VcsLogStructureFilterImpl implements VcsLogDetailsFilter, VcsLogStructureFilter {
 
   @NotNull private final Collection<VirtualFile> myFiles;
   @NotNull private final MultiMap<VirtualFile, VirtualFile> myFilesByRoots;
 
-  public VcsLogStructureFilter(@NotNull Collection<VirtualFile> files, Collection<VirtualFile> roots) {
+  public VcsLogStructureFilterImpl(@NotNull Collection<VirtualFile> files, Collection<VirtualFile> roots) {
     myFiles = files;
     myFilesByRoots = groupFilesByVcsRoots(files, roots);
   }
@@ -87,6 +88,7 @@
     }) != null;
   }
 
+  @Override
   @NotNull
   public Collection<VirtualFile> getFiles(@NotNull VirtualFile root) {
     return myFilesByRoots.get(root);
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUserFilter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUserFilter.java
deleted file mode 100644
index 492c310..0000000
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/data/VcsLogUserFilter.java
+++ /dev/null
@@ -1,71 +0,0 @@
-package com.intellij.vcs.log.data;
-
-import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.vcs.log.VcsFullCommitDetails;
-import com.intellij.vcs.log.VcsUser;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.Map;
-
-/**
- * Filters log by user.
- */
-public abstract class VcsLogUserFilter implements VcsLogDetailsFilter {
-
-  /**
-   * Filters by the given name or part of it.
-   */
-  public static class ByName extends VcsLogUserFilter {
-
-    @NotNull private final String myUser;
-
-    public ByName(@NotNull String user) {
-      myUser = user;
-    }
-
-    @Override
-    public boolean matches(@NotNull VcsFullCommitDetails detail) {
-      return detail.getAuthor().getName().toLowerCase().contains(myUser.toLowerCase()) ||
-             detail.getAuthor().getEmail().toLowerCase().contains(myUser.toLowerCase());
-    }
-
-    @NotNull
-    @Override
-    public String getUserName(@NotNull VirtualFile root) {
-      return myUser;
-    }
-  }
-
-  /**
-   * Looks for commits matching the current user,
-   * i.e. looks for the value stored in the VCS config and compares the configured name with the one returned in commit details.
-   */
-  public static class Me extends VcsLogUserFilter {
-
-    @NotNull private final Map<VirtualFile, VcsUser> myMeData;
-
-    public Me(@NotNull Map<VirtualFile, VcsUser> meData) {
-      myMeData = meData;
-    }
-
-    @Override
-    public boolean matches(@NotNull VcsFullCommitDetails details) {
-      VcsUser meInThisRoot = myMeData.get(details.getRoot());
-      return meInThisRoot != null && meInThisRoot.equals(details.getAuthor());
-    }
-
-    @NotNull
-    @Override
-    public String getUserName(@NotNull VirtualFile root) {
-      return myMeData.get(root).getName();
-    }
-  }
-
-  /**
-   * Returns the user name selected in the filter for the given root.
-   * If it is a name-as-text filter, of course, values don't differ per root. The difference appears if the special "me" filter is used.
-   */
-  @NotNull
-  public abstract String getUserName(@NotNull VirtualFile root);
-
-}
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUI.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUI.java
index e913daf..95d1631 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUI.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/VcsLogUI.java
@@ -3,6 +3,9 @@
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.MessageType;
+import com.intellij.openapi.vcs.ui.VcsBalloonProblemNotifier;
+import com.intellij.util.PairFunction;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.UIUtil;
 import com.intellij.vcs.log.Hash;
@@ -234,33 +237,68 @@
     updateUI();
   }
 
-  public void jumpToCommit(final Hash commitHash) {
-    int row = myLogDataHolder.getDataPack().getRowByHash(commitHash);
-    if (row != -1) {
+  public void jumpToCommit(@NotNull Hash commitHash) {
+    jumpTo(commitHash, new PairFunction<AbstractVcsLogTableModel, Hash, Integer>() {
+      @Override
+      public Integer fun(AbstractVcsLogTableModel model, Hash hash) {
+        return model.getRowOfCommit(hash);
+      }
+    });
+  }
+
+  public void jumpToCommitByPartOfHash(@NotNull String commitHash) {
+    jumpTo(commitHash, new PairFunction<AbstractVcsLogTableModel, String, Integer>() {
+      @Override
+      public Integer fun(AbstractVcsLogTableModel model, String hash) {
+        return model.getRowOfCommitByPartOfHash(hash);
+      }
+    });
+  }
+
+  private <T> void jumpTo(@NotNull final T commitId, @NotNull final PairFunction<AbstractVcsLogTableModel, T, Integer> rowGetter) {
+    AbstractVcsLogTableModel model = getModel();
+    if (model == null) {
+      return;
+    }
+
+    int row = rowGetter.fun(model, commitId);
+    if (row >= 0) {
       jumpToRow(row);
     }
-    else {
-      myLogDataHolder.showFullLog(new Runnable() {
+    else if (model.canRequestMore()) {
+      model.requestToLoadMore(new Runnable() {
         @Override
         public void run() {
-          jumpToCommit(commitHash);
+          jumpTo(commitId, rowGetter);
         }
       });
     }
+    else {
+      commitNotFound(commitId.toString());
+    }
   }
 
-  public void jumpToCommitByPartOfHash(final String hash) {
-    Node node = myLogDataHolder.getDataPack().getNodeByPartOfHash(hash);
-    if (node != null) {
-      jumpToRow(node.getRowIndex());
+  @Nullable
+  private AbstractVcsLogTableModel getModel() {
+    TableModel model = getTable().getModel();
+    if (model instanceof AbstractVcsLogTableModel) {
+      return (AbstractVcsLogTableModel)model;
     }
-    else if (!myLogDataHolder.isFullLogShowing()) {
-      myLogDataHolder.showFullLog(new Runnable() {
-        @Override
-        public void run() {
-          jumpToCommitByPartOfHash(hash);
-        }
-      });
+    showMessage(MessageType.WARNING, "The log is not ready to search yet");
+    return null;
+  }
+
+  private void showMessage(@NotNull MessageType messageType, @NotNull String message) {
+    LOG.info(message);
+    VcsBalloonProblemNotifier.showOverChangesView(myProject, message, messageType);
+  }
+
+  private void commitNotFound(@NotNull String commitHash) {
+    if (collectFilters().isEmpty()) {
+      showMessage(MessageType.WARNING, "Commit " + commitHash + " not found");
+    }
+    else {
+      showMessage(MessageType.WARNING, "Commit " + commitHash + " doesn't exist or doesn't match the active filters");
     }
   }
 
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchFilterPopupComponent.java
index 4318e92..aa7f1f9 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchFilterPopupComponent.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/BranchFilterPopupComponent.java
@@ -20,7 +20,7 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.VcsLogBranchFilter;
+import com.intellij.vcs.log.data.VcsLogBranchFilterImpl;
 import com.intellij.vcs.log.impl.VcsLogUtil;
 import com.intellij.vcs.log.ui.VcsLogUI;
 import org.jetbrains.annotations.NotNull;
@@ -127,7 +127,7 @@
   protected Collection<VcsLogFilter> getFilters() {
     String value = getValue();
     Collection<VcsRef> allBranches = myUi.getLogDataHolder().getDataPack().getRefsModel().getBranches();
-    return value == ALL ? null : Collections.<VcsLogFilter>singleton(new VcsLogBranchFilter(allBranches, value));
+    return value == ALL ? null : Collections.<VcsLogFilter>singleton(new VcsLogBranchFilterImpl(allBranches, value));
   }
 
 }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/DateFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/DateFilterPopupComponent.java
index 4c98df6..abac979 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/DateFilterPopupComponent.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/DateFilterPopupComponent.java
@@ -24,7 +24,7 @@
 import com.intellij.openapi.vcs.versionBrowser.DateFilterComponent;
 import com.intellij.util.text.DateFormatUtil;
 import com.intellij.vcs.log.VcsLogFilter;
-import com.intellij.vcs.log.data.VcsLogDateFilter;
+import com.intellij.vcs.log.data.VcsLogDateFilterImpl;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -69,7 +69,7 @@
   @Nullable
   @Override
   protected Collection<VcsLogFilter> getFilters() {
-    return myAfter == null && myBefore == null ? null : Collections.<VcsLogFilter>singleton(new VcsLogDateFilter(myAfter, myBefore));
+    return myAfter == null && myBefore == null ? null : Collections.<VcsLogFilter>singleton(new VcsLogDateFilterImpl(myAfter, myBefore));
   }
 
   private void setOnlyAfter(Date after) {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java
index ed0f8cf..ab5d4dd 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/StructureFilterPopupComponent.java
@@ -24,7 +24,7 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.VcsLogFilter;
-import com.intellij.vcs.log.data.VcsLogStructureFilter;
+import com.intellij.vcs.log.data.VcsLogStructureFilterImpl;
 import com.intellij.vcs.log.ui.VcsStructureChooser;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -53,7 +53,7 @@
   @Nullable
   @Override
   protected Collection<VcsLogFilter> getFilters() {
-    return getValue() == ALL || myFiles.isEmpty() ? null : Collections.<VcsLogFilter>singleton(new VcsLogStructureFilter(myFiles, myRoots));
+    return getValue() == ALL || myFiles.isEmpty() ? null : Collections.<VcsLogFilter>singleton(new VcsLogStructureFilterImpl(myFiles, myRoots));
   }
 
   private void setValue(@NotNull Collection<VirtualFile> files) {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/UserFilterPopupComponent.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/UserFilterPopupComponent.java
index 69488bb..102d32e 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/UserFilterPopupComponent.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/UserFilterPopupComponent.java
@@ -25,6 +25,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.*;
 import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.spellchecker.ui.SpellCheckingEditorCustomization;
 import com.intellij.ui.EditorCustomization;
 import com.intellij.ui.EditorTextField;
@@ -33,11 +34,13 @@
 import com.intellij.util.Function;
 import com.intellij.util.TextFieldCompletionProviderDumbAware;
 import com.intellij.util.containers.ContainerUtil;
+import com.intellij.vcs.log.VcsFullCommitDetails;
 import com.intellij.vcs.log.VcsLogFilter;
 import com.intellij.vcs.log.VcsUser;
 import com.intellij.vcs.log.data.VcsLogDataHolder;
+import com.intellij.vcs.log.data.VcsLogDetailsFilter;
 import com.intellij.vcs.log.data.VcsLogUiProperties;
-import com.intellij.vcs.log.data.VcsLogUserFilter;
+import com.intellij.vcs.log.VcsLogUserFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -101,7 +104,7 @@
     return ContainerUtil.map(mySelectedUsers, new Function<String, VcsLogFilter>() {
       @Override
       public VcsLogFilter fun(String name) {
-        return name == ME ? new VcsLogUserFilter.Me(myDataHolder.getCurrentUser()) : new VcsLogUserFilter.ByName(name);
+        return name == ME ? new Me(myDataHolder.getCurrentUser()) : new ByName(name);
       }
     });
   }
@@ -265,4 +268,54 @@
       }
     }
   }
+
+  /**
+   * Filters by the given name or part of it.
+   */
+  public static class ByName implements VcsLogUserFilter, VcsLogDetailsFilter {
+
+    @NotNull private final String myUser;
+
+    public ByName(@NotNull String user) {
+      myUser = user;
+    }
+
+    @Override
+    public boolean matches(@NotNull VcsFullCommitDetails detail) {
+      return detail.getAuthor().getName().toLowerCase().contains(myUser.toLowerCase()) ||
+             detail.getAuthor().getEmail().toLowerCase().contains(myUser.toLowerCase());
+    }
+
+    @NotNull
+    @Override
+    public String getUserName(@NotNull VirtualFile root) {
+      return myUser;
+    }
+  }
+
+  /**
+   * Looks for commits matching the current user,
+   * i.e. looks for the value stored in the VCS config and compares the configured name with the one returned in commit details.
+   */
+  public static class Me implements VcsLogUserFilter, VcsLogDetailsFilter {
+
+    @NotNull private final Map<VirtualFile, VcsUser> myMeData;
+
+    public Me(@NotNull Map<VirtualFile, VcsUser> meData) {
+      myMeData = meData;
+    }
+
+    @Override
+    public boolean matches(@NotNull VcsFullCommitDetails details) {
+      VcsUser meInThisRoot = myMeData.get(details.getRoot());
+      return meInThisRoot != null && meInThisRoot.equals(details.getAuthor());
+    }
+
+    @NotNull
+    @Override
+    public String getUserName(@NotNull VirtualFile root) {
+      return myMeData.get(root).getName();
+    }
+  }
+
 }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
index d8bd696..3cdf018 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogClassicFilterUi.java
@@ -86,7 +86,7 @@
   public Collection<VcsLogFilter> getFilters() {
     List<VcsLogFilter> filters = getPopupFilters();
     if (!myTextFilter.getText().isEmpty()) {
-      filters.add(new VcsLogTextFilter(myTextFilter.getText()));
+      filters.add(new VcsLogTextFilterImpl(myTextFilter.getText()));
     }
     return filters;
   }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilter.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java
similarity index 84%
rename from platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilter.java
rename to platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java
index 7c4c767..64bb6ea 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilter.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/filter/VcsLogTextFilterImpl.java
@@ -16,14 +16,15 @@
 package com.intellij.vcs.log.ui.filter;
 
 import com.intellij.vcs.log.VcsFullCommitDetails;
+import com.intellij.vcs.log.VcsLogTextFilter;
 import com.intellij.vcs.log.data.VcsLogDetailsFilter;
 import org.jetbrains.annotations.NotNull;
 
-public class VcsLogTextFilter implements VcsLogDetailsFilter {
+public class VcsLogTextFilterImpl implements VcsLogDetailsFilter, VcsLogTextFilter {
 
   @NotNull private final String myText;
 
-  public VcsLogTextFilter(@NotNull String text) {
+  public VcsLogTextFilterImpl(@NotNull String text) {
     myText = text;
   }
 
@@ -32,6 +33,7 @@
     return details.getFullMessage().toLowerCase().contains(myText.toLowerCase());
   }
 
+  @Override
   @NotNull
   public String getText() {
     return myText;
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java
index 7ff8c11..aba0808a 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/AbstractVcsLogTableModel.java
@@ -1,5 +1,6 @@
 package com.intellij.vcs.log.ui.tables;
 
+import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.openapi.vfs.newvfs.impl.NullVirtualFile;
@@ -46,7 +47,7 @@
   @Override
   public final Object getValueAt(int rowIndex, int columnIndex) {
     if (rowIndex >= getRowCount() - 1) {
-      requestToLoadMore();
+      requestToLoadMore(EmptyRunnable.INSTANCE);
     }
 
     VcsShortCommitDetails data = getShortDetails(rowIndex);
@@ -74,7 +75,16 @@
     }
   }
 
-  public abstract void requestToLoadMore();
+  /**
+   * Requests the proper data provider to load more data from the log & recreate the model.
+   * @param onLoaded will be called upon task completion on the EDT.
+   */
+  public abstract void requestToLoadMore(@NotNull Runnable onLoaded);
+
+  /**
+   * Returns true if not all data has been loaded, i.e. there is sense to {@link #requestToLoadMore(Runnable) request more data}.
+   */
+  public abstract boolean canRequestMore();
 
   /**
    * Returns Changes for commits at selected rows.<br/>
@@ -102,6 +112,18 @@
   @Nullable
   public abstract Hash getHashAtRow(int row);
 
+  /**
+   * Returns the row number containing the given commit,
+   * or -1 if the requested commit is not contained in this table model (possibly because not all data has been loaded).
+   */
+  public abstract int getRowOfCommit(@NotNull Hash hash);
+
+  /**
+   * Returns the number of the first row which contains a commit which hash starts with the given value,
+   * or -1 if no such commit was found (possibly because not all data has been loaded).
+   */
+  public abstract int getRowOfCommitByPartOfHash(@NotNull String hash);
+
   @Override
   public Class<?> getColumnClass(int column) {
     switch (column) {
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java
index 21e6cd4..2b48965 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/GraphTableModel.java
@@ -1,7 +1,6 @@
 package com.intellij.vcs.log.ui.tables;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.EmptyRunnable;
 import com.intellij.openapi.vcs.changes.Change;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.vcs.log.Hash;
@@ -57,8 +56,13 @@
   }
 
   @Override
-  public void requestToLoadMore() {
-    myDataHolder.showFullLog(EmptyRunnable.INSTANCE);
+  public void requestToLoadMore(@NotNull Runnable onLoaded) {
+    myDataHolder.showFullLog(onLoaded);
+  }
+
+  @Override
+  public boolean canRequestMore() {
+    return !myDataHolder.isFullLogShowing();
   }
 
   @Nullable
@@ -120,4 +124,15 @@
     return node == null ? null : myDataHolder.getHash(node.getCommitIndex());
   }
 
+  @Override
+  public int getRowOfCommit(@NotNull final Hash hash) {
+    return myDataPack.getRowByHash(hash);
+  }
+
+  @Override
+  public int getRowOfCommitByPartOfHash(@NotNull String hash) {
+    Node node = myDataPack.getNodeByPartOfHash(hash);
+    return node != null ? node.getRowIndex() : -1;
+  }
+
 }
diff --git a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java
index 1cdd138..1cf9474 100644
--- a/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java
+++ b/platform/vcs-log/impl/src/com/intellij/vcs/log/ui/tables/NoGraphTableModel.java
@@ -61,14 +61,19 @@
   }
 
   @Override
-  public void requestToLoadMore() {
+  public void requestToLoadMore(@NotNull Runnable onLoaded) {
     if (myLoadMoreWasRequested.compareAndSet(false, true)     // Don't send the request to VCS twice
         && myLoadMoreStage != LoadMoreStage.ALL_REQUESTED) {  // or when everything possible is loaded
       myUi.getTable().setPaintBusy(true);
-      myUi.getFilterer().requestVcs(myUi.collectFilters(), myLoadMoreStage);
+      myUi.getFilterer().requestVcs(myUi.collectFilters(), myLoadMoreStage, onLoaded);
     }
   }
 
+  @Override
+  public boolean canRequestMore() {
+    return myLoadMoreStage != LoadMoreStage.ALL_REQUESTED;
+  }
+
   @Nullable
   @Override
   public List<Change> getSelectedChanges(@NotNull List<Integer> selectedRows) {
@@ -115,4 +120,28 @@
   public Hash getHashAtRow(int row) {
     return myCommits.get(row).getHash();
   }
+
+  @Override
+  public int getRowOfCommit(@NotNull Hash hash) {
+    for (int i = 0; i < myCommits.size(); i++) {
+      VcsFullCommitDetails commit = myCommits.get(i);
+      if (commit.getHash().equals(hash)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
+  @Override
+  public int getRowOfCommitByPartOfHash(@NotNull String hash) {
+    String lowercaseHash = hash.toLowerCase();
+    for (int i = 0; i < myCommits.size(); i++) {
+      VcsFullCommitDetails commit = myCommits.get(i);
+      if (commit.getHash().toString().toLowerCase().startsWith(lowercaseHash)) {
+        return i;
+      }
+    }
+    return -1;
+  }
+
 }
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
index b77dd37..62fdc0e 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.form
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel">
-  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" 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="20" y="20" width="500" height="400"/>
+      <xy x="20" y="20" width="500" height="697"/>
     </constraints>
     <properties/>
     <border type="none"/>
@@ -13,16 +13,16 @@
           <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
-      <grid id="84778" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="84778" layout-manager="GridLayoutManager" row-count="2" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="0" vgap="0">
         <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="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"/>
+          <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
         </clientProperties>
-        <border type="none" title="Class-Name"/>
+        <border type="none" title="Class Methods"/>
         <children>
           <grid id="5081f" binding="myClassPanel" layout-manager="BorderLayout" hgap="0" vgap="0">
             <constraints>
@@ -32,22 +32,9 @@
             <border type="none"/>
             <children/>
           </grid>
-        </children>
-      </grid>
-      <grid id="b75a2" 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="2" 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/>
-        <clientProperties>
-          <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
-        </clientProperties>
-        <border type="none" title="Parameters"/>
-        <children>
           <scrollpane id="5dfaa" class="com.intellij.ui.components.JBScrollPane">
             <constraints>
-              <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+              <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="7" hsize-policy="7" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties/>
             <border type="none"/>
@@ -62,7 +49,7 @@
       </grid>
       <nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form" binding="myAdvancedPanel" custom-create="true">
         <constraints>
-          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
     </children>
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
index 36da2a9..0c1cf64 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/MethodParameterPanel.java
@@ -28,6 +28,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
 import com.intellij.ui.*;
 import com.intellij.ui.dualView.TreeTableView;
 import com.intellij.ui.treeStructure.treetable.ListTreeTableModelOnColumns;
@@ -42,6 +43,7 @@
 import gnu.trove.THashSet;
 import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
 import org.intellij.plugins.intelliLang.util.PsiUtilEx;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -91,23 +93,23 @@
     myParamsTable.getTree().setShowsRootHandles(true);
     myParamsTable.getTree().setCellRenderer(new ColoredTreeCellRenderer() {
 
-      public void customizeCellRenderer(final JTree tree,
-                                        final Object value,
-                                        final boolean selected,
-                                        final boolean expanded,
-                                        final boolean leaf,
-                                        final int row,
-                                        final boolean hasFocus) {
+      public void customizeCellRenderer(@NotNull JTree tree,
+                                        Object value,
+                                        boolean selected,
+                                        boolean expanded,
+                                        boolean leaf,
+                                        int row,
+                                        boolean hasFocus) {
 
         final Object o = ((DefaultMutableTreeNode)value).getUserObject();
         setIcon(o instanceof PsiMethod ? PlatformIcons.METHOD_ICON : o instanceof PsiParameter ? PlatformIcons.PARAMETER_ICON : null);
         final String name;
         if (o instanceof PsiMethod) {
-          name = PsiFormatUtil.formatMethod((PsiMethod)o, PsiSubstitutor.EMPTY, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_PARAMETERS,
-                                            PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE);
+          name = PsiFormatUtil.formatMethod((PsiMethod)o, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
+                                            PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE);
         }
         else if (o instanceof PsiParameter) {
-          name = PsiFormatUtil.formatVariable((PsiParameter)o, PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE, PsiSubstitutor.EMPTY);
+          name = PsiFormatUtil.formatVariable((PsiParameter)o, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_TYPE, PsiSubstitutor.EMPTY);
         }
         else name = null;
         final boolean missing = o instanceof PsiElement && !((PsiElement)o).isPhysical();
@@ -362,7 +364,7 @@
             return valueOf(o) != null;
           }
 
-        }, new TreeColumnInfo("Method/Parameters")
+        }, new TreeColumnInfo(" ")
     };
   }
 
@@ -386,7 +388,7 @@
     }
   }
 
-  private class MyView extends TreeTableView implements TypeSafeDataProvider {
+  private static class MyView extends TreeTableView implements TypeSafeDataProvider {
     public MyView(ListTreeTableModelOnColumns treeTableModel) {
       super(treeTableModel);
     }
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java
deleted file mode 100644
index 1b14fc2..0000000
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/MethodParameterInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel;
-
-public class MethodParameterInjectionConfigurable extends InjectionConfigurable<MethodParameterInjection, MethodParameterPanel> {
-  public MethodParameterInjectionConfigurable(MethodParameterInjection injection, Runnable treeUpdater, Project project) {
-    super(injection, treeUpdater, project);
-  }
-
-  protected MethodParameterPanel createOptionsPanelImpl() {
-    return new MethodParameterPanel(myInjection, myProject);
-  }
-
-  public String getBannerSlogan() {
-    return "Edit Method Parameter Injection";
-  }
-}
diff --git a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
index 99a3ccd..14c7535 100644
--- a/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/java-support/org/intellij/plugins/intelliLang/inject/java/JavaLanguageInjectionSupport.java
@@ -55,7 +55,6 @@
 import org.intellij.plugins.intelliLang.inject.config.MethodParameterInjection;
 import org.intellij.plugins.intelliLang.inject.config.ui.AbstractInjectionPanel;
 import org.intellij.plugins.intelliLang.inject.config.ui.MethodParameterPanel;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.MethodParameterInjectionConfigurable;
 import org.intellij.plugins.intelliLang.util.ContextComputationProcessor;
 import org.intellij.plugins.intelliLang.util.PsiUtilEx;
 import org.jdom.Element;
@@ -175,10 +174,7 @@
   }
 
   public BaseInjection createInjection(final Element element) {
-    if (element.getName().equals(MethodParameterInjection.class.getSimpleName())) {
-      return new MethodParameterInjection();
-    }
-    else return new BaseInjection(JAVA_SUPPORT_ID);
+    return new BaseInjection(JAVA_SUPPORT_ID);
   }
 
   private static boolean doInjectInJava(final Project project,
@@ -371,16 +367,21 @@
       originalCopy.setPlaceEnabled(currentPlace.getText(), true);
       methodParameterInjection = createFrom(project, originalCopy, contextMethod, false);
     }
-    if (InjectLanguageAction.doEditConfigurable(project, new MethodParameterInjectionConfigurable(methodParameterInjection, null, project))) {
-      final BaseInjection newInjection = new BaseInjection(methodParameterInjection.getSupportId()).copyFrom(methodParameterInjection);
-      if (originalInjection != null) {
-        newInjection.mergeOriginalPlacesFrom(originalInjection, true);
-      }
-      configuration.replaceInjectionsWithUndo(
-        project, Collections.singletonList(newInjection),
-        ContainerUtil.createMaybeSingletonList(originalInjection),
-        Collections.<PsiElement>emptyList());
+    mergePlacesAndAddToConfiguration(project, configuration, methodParameterInjection, originalInjection);
+  }
+
+  private static void mergePlacesAndAddToConfiguration(@NotNull Project project,
+                                                       @NotNull Configuration configuration,
+                                                       @NotNull MethodParameterInjection injection,
+                                                       @Nullable BaseInjection originalInjection) {
+    BaseInjection newInjection = new BaseInjection(injection.getSupportId()).copyFrom(injection);
+    if (originalInjection != null) {
+      newInjection.mergeOriginalPlacesFrom(originalInjection, true);
     }
+    configuration.replaceInjectionsWithUndo(
+      project, Collections.singletonList(newInjection),
+      ContainerUtil.createMaybeSingletonList(originalInjection),
+      Collections.<PsiElement>emptyList());
   }
 
   private static void collectInjections(PsiLiteralExpression host,
diff --git a/plugins/IntelliLang/src/META-INF/plugin.xml b/plugins/IntelliLang/src/META-INF/plugin.xml
index 8dad5cb..975422e 100644
--- a/plugins/IntelliLang/src/META-INF/plugin.xml
+++ b/plugins/IntelliLang/src/META-INF/plugin.xml
@@ -36,7 +36,7 @@
     <highlightErrorFilter implementation="org.intellij.plugins.intelliLang.inject.FrankensteinErrorFilter"/>
     <daemon.highlightInfoFilter implementation="org.intellij.plugins.intelliLang.inject.FrankensteinErrorFilter"/>
 
-    <projectConfigurable instance="org.intellij.plugins.intelliLang.InjectionsSettingsUI" nonDefaultProject="true"/>
+    <projectConfigurable displayName="Language Injections" instance="org.intellij.plugins.intelliLang.InjectionsSettingsUI" nonDefaultProject="true"/>
 
     <multiHostInjector implementation="org.intellij.plugins.intelliLang.inject.CommentLanguageInjector"/>
     <multiHostInjector implementation="org.intellij.plugins.intelliLang.inject.TemporaryPlacesInjector"/>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
index 414500b..a042093 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/InjectionsSettingsUI.java
@@ -30,6 +30,7 @@
 import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.options.SearchableConfigurable;
+import com.intellij.openapi.project.DumbAwareAction;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.ui.SplitterProportionsData;
@@ -47,7 +48,6 @@
 import com.intellij.util.containers.Convertor;
 import com.intellij.util.ui.ColumnInfo;
 import com.intellij.util.ui.ListTableModel;
-import gnu.trove.THashMap;
 import gnu.trove.THashSet;
 import gnu.trove.TObjectHashingStrategy;
 import org.intellij.plugins.intelliLang.inject.AbstractLanguageInjectionSupport;
@@ -81,19 +81,14 @@
 
   private final JPanel myRoot;
   private final InjectionsTable myInjectionsTable;
-  private final Map<String, LanguageInjectionSupport> mySupports = new THashMap<String, LanguageInjectionSupport>();
-  private final Map<String, AnAction> myEditActions = new THashMap<String, AnAction>();
-  private final List<AnAction> myAddActions = new ArrayList<AnAction>();
-  private final ActionToolbar myToolbar;
+  private final Map<String, LanguageInjectionSupport> mySupports = ContainerUtil.newLinkedHashMap();
+  private final Map<String, AnAction> myEditActions = ContainerUtil.newLinkedHashMap();
+  private final List<AnAction> myAddActions = ContainerUtil.newArrayList();
   private final JLabel myCountLabel;
 
   private Configurable[] myConfigurables;
   private Configuration myConfiguration;
 
-  public InjectionsSettingsUI(final Project project) {
-    this(project, Configuration.getProjectInstance(project));
-  }
-
   public InjectionsSettingsUI(final Project project, final Configuration configuration) {
     myProject = project;
     myConfiguration = configuration;
@@ -107,16 +102,12 @@
 
     myInjectionsTable = new InjectionsTable(getInjInfoList(myInfos));
     myInjectionsTable.getEmptyText().setText("No injections configured");
-    final JPanel tablePanel = new JPanel(new BorderLayout());
 
-    tablePanel.add(ScrollPaneFactory.createScrollPane(myInjectionsTable), BorderLayout.CENTER);
+    ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myInjectionsTable);
+    createActions(decorator);
 
-    final DefaultActionGroup group = createActions();
-
-    myToolbar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
-    myToolbar.setTargetComponent(myInjectionsTable);
-    myRoot.add(myToolbar.getComponent(), BorderLayout.NORTH);
-    myRoot.add(tablePanel, BorderLayout.CENTER);
+    //myRoot.add(new TitledSeparator("Languages injection places"), BorderLayout.NORTH);
+    myRoot.add(decorator.createPanel(), BorderLayout.CENTER);
     myCountLabel = new JLabel();
     myCountLabel.setHorizontalAlignment(SwingConstants.RIGHT);
     myCountLabel.setForeground(SimpleTextAttributes.GRAY_ITALIC_ATTRIBUTES.getFgColor());
@@ -124,7 +115,7 @@
     updateCountLabel();
   }
 
-  private DefaultActionGroup createActions() {
+  private void createActions(ToolbarDecorator decorator) {
     final Consumer<BaseInjection> consumer = new Consumer<BaseInjection>() {
       public void consume(final BaseInjection injection) {
         addInjection(injection);
@@ -148,22 +139,22 @@
         return Comparing.compare(o1.getTemplatePresentation().getText(), o2.getTemplatePresentation().getText());
       }
     });
-
-    final DefaultActionGroup group = new DefaultActionGroup();
-    final AnAction addAction = new AnAction("Add", "Add", IconUtil.getAddIcon()) {
+    decorator.disableUpDownActions();
+    decorator.setAddActionUpdater(new AnActionButtonUpdater() {
       @Override
-      public void update(final AnActionEvent e) {
-        e.getPresentation().setEnabled(!myAddActions.isEmpty());
+      public boolean isEnabled(AnActionEvent e) {
+        return !myAddActions.isEmpty();
       }
-
+    });
+    decorator.setAddAction(new AnActionButtonRunnable() {
       @Override
-      public void actionPerformed(final AnActionEvent e) {
-        performAdd(e);
+      public void run(AnActionButton button) {
+        performAdd(button);
       }
-    };
-    final AnAction removeAction = new AnAction("Remove", "Remove", PlatformIcons.DELETE_ICON) {
+    });
+    decorator.setRemoveActionUpdater(new AnActionButtonUpdater() {
       @Override
-      public void update(final AnActionEvent e) {
+      public boolean isEnabled(AnActionEvent e) {
         boolean enabled = false;
         for (InjInfo info : getSelectedInjections()) {
           if (!info.bundled) {
@@ -171,69 +162,63 @@
             break;
           }
         }
-        e.getPresentation().setEnabled(enabled);
+        return enabled;
       }
-
+    });
+    decorator.setRemoveAction(new AnActionButtonRunnable() {
       @Override
-      public void actionPerformed(final AnActionEvent e) {
+      public void run(AnActionButton button) {
         performRemove();
       }
-    };
+    });
 
-    final AnAction editAction = new AnAction("Edit", "Edit", PlatformIcons.PROPERTIES_ICON) {
+    decorator.setEditActionUpdater(new AnActionButtonUpdater() {
       @Override
-      public void update(final AnActionEvent e) {
-        final AnAction action = getEditAction();
-        e.getPresentation().setEnabled(action != null);
-        if (action != null) action.update(e);
+      public boolean isEnabled(AnActionEvent e) {
+        AnAction edit = getEditAction();
+        if (edit != null) edit.update(e);
+        return edit != null && edit.getTemplatePresentation().isEnabled();
+      }
+    });
+    decorator.setEditAction(new AnActionButtonRunnable() {
+      @Override
+      public void run(AnActionButton button) {
+        performEditAction();
+      }
+    });
+    decorator.addExtraAction(new DumbAwareActionButton("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) {
+
+      @Override
+      public boolean isEnabled() {
+        return getEditAction() != null;
       }
 
       @Override
-      public void actionPerformed(final AnActionEvent e) {
-        performEditAction(e);
-      }
-    };
-    final AnAction copyAction = new AnAction("Duplicate", "Duplicate", PlatformIcons.COPY_ICON) {
-      @Override
-      public void update(final AnActionEvent e) {
-        final AnAction action = getEditAction();
-        e.getPresentation().setEnabled(action != null);
-        if (action != null) action.update(e);
-      }
-
-      @Override
-      public void actionPerformed(final AnActionEvent e) {
+      public void actionPerformed(AnActionEvent e) {
         final InjInfo injection = getSelectedInjection();
         if (injection != null) {
           addInjection(injection.injection.copy());
           //performEditAction(e);
         }
       }
-    };
-    group.add(addAction);
-    group.add(removeAction);
-    group.add(copyAction);
-    group.add(editAction);
+    });
 
-    addAction.registerCustomShortcutSet(CommonShortcuts.INSERT, myInjectionsTable);
-    removeAction.registerCustomShortcutSet(CommonShortcuts.DELETE, myInjectionsTable);
-    editAction.registerCustomShortcutSet(CommonShortcuts.ENTER, myInjectionsTable);
+    decorator.addExtraAction(new DumbAwareActionButton("Enable Selected Injections", "Enable Selected Injections", PlatformIcons.SELECT_ALL_ICON) {
 
-    group.addSeparator();
-    group.add(new AnAction("Enable Selected Injections", "Enable Selected Injections", PlatformIcons.SELECT_ALL_ICON) {
       @Override
       public void actionPerformed(final AnActionEvent e) {
         performSelectedInjectionsEnabled(true);
       }
     });
-    group.add(new AnAction("Disable Selected Injections", "Disable Selected Injections", PlatformIcons.UNSELECT_ALL_ICON) {
-      @Override
-      public void actionPerformed(final AnActionEvent e) {
-        performSelectedInjectionsEnabled(false);
-      }
-    });
+    decorator.addExtraAction(new DumbAwareActionButton("Disable Selected Injections", "Disable Selected Injections", PlatformIcons.UNSELECT_ALL_ICON) {
 
-    new AnAction("Toggle") {
+        @Override
+        public void actionPerformed(final AnActionEvent e) {
+          performSelectedInjectionsEnabled(false);
+        }
+      });
+
+    new DumbAwareAction("Toggle") {
       @Override
       public void update(AnActionEvent e) {
         SpeedSearchSupply supply = SpeedSearchSupply.getSupply(myInjectionsTable);
@@ -247,8 +232,18 @@
     }.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, 0)), myInjectionsTable);
 
     if (myInfos.length > 1) {
-      group.addSeparator();
-      final AnAction shareAction = new AnAction("Make Global", null, PlatformIcons.IMPORT_ICON) {
+      AnActionButton shareAction = new DumbAwareActionButton("Make Global", null, PlatformIcons.IMPORT_ICON) {
+        {
+          addCustomUpdater(new AnActionButtonUpdater() {
+            @Override
+            public boolean isEnabled(AnActionEvent e) {
+              CfgInfo cfg = getTargetCfgInfo(getSelectedInjections());
+              e.getPresentation().setText(cfg == getDefaultCfgInfo() ? "Make Global" : "Move to Project");
+              return cfg != null;
+            }
+          });
+        }
+
         @Override
         public void actionPerformed(final AnActionEvent e) {
           final List<InjInfo> injections = getSelectedInjections();
@@ -265,14 +260,6 @@
           TableUtil.selectRows(myInjectionsTable, selectedRows);
         }
 
-        @Override
-        public void update(final AnActionEvent e) {
-          final CfgInfo cfg = getTargetCfgInfo(getSelectedInjections());
-          e.getPresentation().setEnabled(cfg != null);
-          e.getPresentation().setText(cfg == getDefaultCfgInfo() ? "Make Global" : "Move to Project");
-          super.update(e);
-        }
-
         @Nullable
         private CfgInfo getTargetCfgInfo(final List<InjInfo> injections) {
           CfgInfo cfg = null;
@@ -283,25 +270,26 @@
             if (cfg == null) cfg = info.cfgInfo;
             else if (cfg != info.cfgInfo) return info.cfgInfo;
           }
-          if (cfg == null) return cfg;
+          if (cfg == null) return null;
           for (CfgInfo info : myInfos) {
             if (info != cfg) return info;
           }
           throw new AssertionError();
         }
       };
-      shareAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)), myInjectionsTable);
-      group.add(shareAction);
+      shareAction.setShortcut(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_SPACE, InputEvent.SHIFT_DOWN_MASK)));
+      decorator.addExtraAction(shareAction);
     }
-    group.addSeparator();
-    group.add(new AnAction("Import", "Import", AllIcons.Actions.Install) {
+    decorator.addExtraAction(new DumbAwareActionButton("Import", "Import", AllIcons.Actions.Install) {
+
       @Override
       public void actionPerformed(final AnActionEvent e) {
         doImportAction(e.getDataContext());
         updateCountLabel();
       }
     });
-    group.add(new AnAction("Export", "Export", AllIcons.Actions.Export) {
+    decorator.addExtraAction(new DumbAwareActionButton("Export", "Export", AllIcons.Actions.Export) {
+
       @Override
       public void actionPerformed(final AnActionEvent e) {
         final List<BaseInjection> injections = getInjectionList(getSelectedInjections());
@@ -321,20 +309,19 @@
       }
 
       @Override
-      public void update(final AnActionEvent e) {
-        e.getPresentation().setEnabled(!getSelectedInjections().isEmpty());
+      public boolean isEnabled() {
+        return !getSelectedInjections().isEmpty();
       }
     });
-
-    return group;
   }
 
 
-  private void performEditAction(AnActionEvent e) {
+  private void performEditAction() {
     final AnAction action = getEditAction();
     if (action != null) {
       final int row = myInjectionsTable.getSelectedRow();
-      action.actionPerformed(e);
+      action.actionPerformed(new AnActionEvent(null, DataManager.getInstance().getDataContext(myInjectionsTable),
+                                               ActionPlaces.UNKNOWN, new Presentation(""), ActionManager.getInstance(), 0));
       myInjectionsTable.getListTableModel().fireTableDataChanged();
       myInjectionsTable.getSelectionModel().setSelectionInterval(row, row);
       updateCountLabel();
@@ -352,10 +339,8 @@
           if (place.isEnabled()) enablePlacesCount++;
         }
       }
-      final StringBuilder sb = new StringBuilder();
-      sb.append(items.size()).append(" injection").append(items.size() > 1 ? "s" : "").append(" (").append(enablePlacesCount)
-        .append(" of ").append(placesCount).append(" place").append(placesCount > 1 ? "s" : "").append(" enabled) ");
-      myCountLabel.setText(sb.toString());
+      myCountLabel.setText(items.size() + " injection" + (items.size() > 1 ? "s" : "") + " (" + enablePlacesCount + " of " +
+                           placesCount + " place" + (placesCount > 1 ? "s" : "") + " enabled) ");
     }
     else {
       myCountLabel.setText("no injections configured ");
@@ -511,17 +496,14 @@
     return row < 0? null : myInjectionsTable.getItems().get(myInjectionsTable.convertRowIndexToModel(row));
   }
 
-  private void performAdd(final AnActionEvent e) {
-    final DefaultActionGroup group = new DefaultActionGroup();
-    for (AnAction action : myAddActions) {
-      group.add(action);
-    }
+  private void performAdd(AnActionButton e) {
+    DefaultActionGroup group = new DefaultActionGroup(myAddActions);
 
     JBPopupFactory.getInstance().createActionGroupPopup(null, group, e.getDataContext(), JBPopupFactory.ActionSelectionAid.NUMBERING, true, new Runnable() {
       public void run() {
         updateCountLabel();
       }
-    }, -1).showUnderneathOf(myToolbar.getComponent());
+    }, -1).show(e.getPreferredPopupPoint());
   }
 
   @Nls
@@ -552,8 +534,7 @@
           if (row < 0) return false;
           if (columnAtPoint(e.getPoint()) <= 0) return false;
           myInjectionsTable.getSelectionModel().setSelectionInterval(row, row);
-          performEditAction(new AnActionEvent(e, DataManager.getInstance().getDataContext(InjectionsTable.this),
-                                              ActionPlaces.UNKNOWN, new Presentation(""), ActionManager.getInstance(), 0));
+          performEditAction();
           return true;
         }
       }.installOn(this);
@@ -632,7 +613,7 @@
       public TableCellRenderer getRenderer(final InjInfo injection) {
         return booleanCellRenderer;
       }
-    }, new ColumnInfo<InjInfo, InjInfo>("Display Name") {
+    }, new ColumnInfo<InjInfo, InjInfo>("Name") {
       @Override
       public InjInfo valueOf(final InjInfo info) {
         return info;
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
index a18a26b..1323937 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/AbstractLanguageInjectionSupport.java
@@ -114,12 +114,13 @@
   public static AnAction createDefaultAddAction(final Project project,
                                                 final Consumer<BaseInjection> consumer,
                                                 final AbstractLanguageInjectionSupport support) {
+    final String supportTitle = StringUtil.capitalize(support.getId());
     Icon icon = FileTypeManager.getInstance().getFileTypeByExtension(support.getId()).getIcon();
-    return new AnAction("Generic "+ StringUtil.capitalize(support.getId()), null, icon) {
+    return new AnAction("Generic "+ supportTitle, null, icon) {
       @Override
       public void actionPerformed(AnActionEvent e) {
         final BaseInjection injection = new BaseInjection(support.getId());
-        injection.setDisplayName("New "+ StringUtil.capitalize(support.getId())+" Injection");
+        injection.setDisplayName("New "+ supportTitle +" Injection");
         final BaseInjection newInjection = showDefaultInjectionUI(project, injection);
         if (newInjection != null) {
           consumer.consume(injection);
@@ -134,7 +135,7 @@
     panel.reset();
     final DialogBuilder builder = new DialogBuilder(project);
     LanguageInjectionSupport support = InjectorUtils.findInjectionSupport(injection.getSupportId());
-    if (support != null && support instanceof AbstractLanguageInjectionSupport) {
+    if (support instanceof AbstractLanguageInjectionSupport) {
       builder.setHelpId(((AbstractLanguageInjectionSupport)support).getHelpId());
     }
     builder.addOkAction();
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
index 18f4c01..b03a07d 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/InjectLanguageAction.java
@@ -28,7 +28,6 @@
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.keymap.KeymapUtil;
-import com.intellij.openapi.options.Configurable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.popup.JBPopup;
 import com.intellij.openapi.ui.popup.PopupChooserBuilder;
@@ -221,7 +220,4 @@
     return false;
   }
 
-  public static boolean doEditConfigurable(final Project project, final Configurable configurable) {
-    return true; //ShowSettingsUtil.getInstance().editConfigurable(project, configurable);
-  }
 }
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
index ffd54be..f5fddc2 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/BaseInjection.java
@@ -56,7 +56,8 @@
   public static final Key<BaseInjection> INJECTION_KEY = Key.create("INJECTION_KEY");
 
   @NotNull private final String mySupportId;
-  private String myDisplayName;
+
+  private String myDisplayName = "";
 
   private String myInjectedLanguageId = "";
   private String myPrefix = "";
@@ -98,7 +99,7 @@
     return myDisplayName;
   }
 
-  public void setDisplayName(String displayName) {
+  public void setDisplayName(@NotNull String displayName) {
     myDisplayName = displayName;
   }
 
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
index 2626d4f..9b6fc83 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AbstractInjectionPanel.java
@@ -15,8 +15,6 @@
  */
 package org.intellij.plugins.intelliLang.inject.config.ui;
 
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
 import com.intellij.openapi.project.Project;
 import com.intellij.util.ui.UIUtil;
 import org.intellij.plugins.intelliLang.inject.config.BaseInjection;
@@ -73,7 +71,6 @@
       final InjectionPanel p = getField(panel);
       p.init(copy);
     }
-    reset();
   }
 
   public final boolean isModified() {
@@ -89,23 +86,28 @@
 
   @SuppressWarnings({"unchecked"})
   public final void apply() {
-    apply(myOrigInjection);
-
     for (Field panel : myOtherPanels) {
       getField(panel).apply();
     }
-    myOrigInjection.generatePlaces();
-    myEditCopy.copyFrom(myOrigInjection);
+
+    // auto-generated name should go last
+    apply(myOrigInjection);
+    if (!myOtherPanels.isEmpty()) {
+      myOrigInjection.generatePlaces();
+      myEditCopy.copyFrom(myOrigInjection);
+    }
   }
 
   protected abstract void apply(T other);
 
   @SuppressWarnings({"unchecked"})
   public final void reset() {
+    if (!myOtherPanels.isEmpty()) {
+      myEditCopy.copyFrom(myOrigInjection);
+    }
     for (Field panel : myOtherPanels) {
       getField(panel).reset();
     }
-    myEditCopy.copyFrom(myOrigInjection);
     UIUtil.invokeAndWaitIfNeeded(new Runnable() {
       public void run() {
         resetImpl();
@@ -138,10 +140,4 @@
       updater.run();
     }
   }
-
-  protected class TreeUpdateListener extends DocumentAdapter {
-    public void documentChanged(DocumentEvent e) {
-      updateTree();
-    }
-  }
 }
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
index a45bfaf..0ac5d48 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form
@@ -26,7 +26,7 @@
             </constraints>
             <properties>
               <labelFor value="7bf4e"/>
-              <text value="&amp;Value Pattern:"/>
+              <text value="&amp;Value pattern:"/>
               <toolTipText value="&lt;html&gt;Enter a regular expression that selects the parts of the tag's or attribute's value the language should be injected into.&lt;br&gt;The pattern should contain exactly one capturing group.&lt;/html&gt;"/>
             </properties>
           </component>
@@ -43,7 +43,7 @@
               <grid row="0" column="2" 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="&amp;Single File"/>
+              <text value="&amp;Single file"/>
             </properties>
           </component>
         </children>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
index 0c9523f..79dafac 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/BaseInjectionPanel.form
@@ -21,7 +21,7 @@
         <clientProperties>
           <BorderFactoryClass class="java.lang.String" value="com.intellij.ui.IdeBorderFactory$PlainSmallWithoutIndent"/>
         </clientProperties>
-        <border type="none" title="Places Pattern"/>
+        <border type="none" title="Places Patterns"/>
         <children/>
       </grid>
       <nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedPanel.form" binding="myAdvancedPanel" custom-create="true">
@@ -43,7 +43,7 @@
             </constraints>
             <properties>
               <labelFor value="5916a"/>
-              <text value="Display &amp;Name:"/>
+              <text value="&amp;Name:"/>
             </properties>
           </component>
           <component id="5916a" class="javax.swing.JTextField" binding="myNameTextField">
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
index 1f582bb..e8e087e 100644
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
+++ b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.LanguagePanel">
-  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" column-count="3" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="3" 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="493" height="143"/>
@@ -44,20 +44,15 @@
         </constraints>
         <properties/>
       </component>
-      <hspacer id="7c4e8">
-        <constraints>
-          <grid row="0" column="2" row-span="1" col-span="1" vsize-policy="1" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
-        </constraints>
-      </hspacer>
       <component id="96508" class="com.intellij.ui.EditorTextField" binding="myPrefix">
         <constraints>
-          <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties/>
       </component>
       <component id="dcdf7" class="com.intellij.ui.EditorTextField" binding="mySuffix">
         <constraints>
-          <grid row="2" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="2" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
         <properties/>
       </component>
diff --git a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java b/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java
deleted file mode 100644
index b09de2e..0000000
--- a/plugins/IntelliLang/src/org/intellij/plugins/intelliLang/inject/config/ui/configurables/InjectionConfigurable.java
+++ /dev/null
@@ -1,85 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.options.ConfigurationException;
-import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.NamedConfigurable;
-import org.intellij.plugins.intelliLang.inject.config.Injection;
-import org.intellij.plugins.intelliLang.inject.config.ui.InjectionPanel;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.Nullable;
-
-import javax.swing.*;
-
-public abstract class InjectionConfigurable<T extends Injection, P extends InjectionPanel<T>> extends NamedConfigurable<T> {
-  private final Runnable myTreeUpdater;
-  protected final T myInjection;
-  protected final Project myProject;
-  private P myPanel;
-
-  public InjectionConfigurable(T injection, Runnable treeUpdater, Project project) {
-    myProject = project;
-    myInjection = injection;
-    myTreeUpdater = treeUpdater;
-  }
-
-  public void setDisplayName(String name) {
-  }
-
-  public T getEditableObject() {
-    return myInjection;
-  }
-
-  @Nullable
-  @NonNls
-  public String getHelpTopic() {
-    return null;
-  }
-
-  public JComponent createOptionsPanel() {
-    myPanel = createOptionsPanelImpl();
-    myPanel.addUpdater(myTreeUpdater);
-    return myPanel.getComponent();
-  }
-
-  protected abstract P createOptionsPanelImpl();
-
-  public P getPanel() {
-    return myPanel;
-  }
-
-  public boolean isModified() {
-    return myPanel.isModified();
-  }
-
-  public void apply() throws ConfigurationException {
-    myPanel.apply();
-  }
-
-  public void reset() {
-    myPanel.reset();
-  }
-
-  public void disposeUIResources() {
-    myPanel = null;
-  }
-
-  public String getDisplayName() {
-    final P p = getPanel();
-    return p != null ? p.getInjection().getDisplayName() : myInjection.getDisplayName();
-  }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
index 0662837..491b277 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/AbstractTagInjection.java
@@ -16,7 +16,6 @@
 package org.intellij.plugins.intelliLang.inject.config;
 
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.util.JDOMExternalizer;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.xml.XmlAttribute;
@@ -44,7 +43,7 @@
  *
  * @see org.intellij.plugins.intelliLang.inject.config.XPathSupportProxy
  */
-public class AbstractTagInjection extends BaseInjection {
+public abstract class AbstractTagInjection extends BaseInjection {
 
   private static final Logger LOG = Logger.getInstance("org.intellij.plugins.intelliLang.inject.config.AbstractTagInjection");
 
@@ -57,7 +56,7 @@
   private String myXPathCondition = "";
 
   private XPath myCompiledXPathCondition;
-  private boolean myApplyToSubTagTexts;
+  private boolean myApplyToSubTags;
 
   public AbstractTagInjection() {
     super(XmlLanguageInjectionSupport.XML_SUPPORT_ID);
@@ -134,9 +133,7 @@
   }
 
   @Override
-  public AbstractTagInjection copy() {
-    return new AbstractTagInjection().copyFrom(this);
-  }
+  public abstract AbstractTagInjection copy();
 
   public AbstractTagInjection copyFrom(@NotNull BaseInjection o) {
     super.copyFrom(o);
@@ -146,30 +143,21 @@
       myTagNamespace = other.myTagNamespace;
       setXPathCondition(other.getXPathCondition());
 
-      setApplyToSubTagTexts(other.isApplyToSubTagTexts());
+      setApplyToSubTags(other.isApplyToSubTags());
     }
     return this;
   }
 
   protected void readExternalImpl(Element e) {
-    if (e.getAttribute("injector-id") == null) {
-      setTagName(JDOMExternalizer.readString(e, "TAGNAME"));
-      setTagNamespace(JDOMExternalizer.readString(e, "TAGNAMESPACE"));
-      setXPathCondition(JDOMExternalizer.readString(e, "XPATH_CONDITION"));
-
-      myApplyToSubTagTexts = JDOMExternalizer.readBoolean(e, "APPLY_TO_SUBTAGS");
-    }
-    else {
-      setXPathCondition(e.getChildText("xpath-condition"));
-      myApplyToSubTagTexts = e.getChild("apply-to-subtags") != null;
-    }
+    setXPathCondition(e.getChildText("xpath-condition"));
+    myApplyToSubTags = e.getChild("apply-to-subtags") != null;
   }
 
   protected void writeExternalImpl(Element e) {
     if (StringUtil.isNotEmpty(myXPathCondition)) {
       e.addContent(new Element("xpath-condition").setText(myXPathCondition));
     }
-    if (myApplyToSubTagTexts) {
+    if (myApplyToSubTags) {
       e.addContent(new Element("apply-to-subtags"));
     }
   }
@@ -186,7 +174,7 @@
     if (!myTagNamespace.equals(that.myTagNamespace)) return false;
     if (!myXPathCondition.equals(that.myXPathCondition)) return false;
 
-    if (myApplyToSubTagTexts != that.myApplyToSubTagTexts) return false;
+    if (myApplyToSubTags != that.myApplyToSubTags) return false;
     return true;
   }
 
@@ -196,7 +184,7 @@
     result = 31 * result + myTagNamespace.hashCode();
     result = 31 * result + myXPathCondition.hashCode();
 
-    result = 31 * result + (myApplyToSubTagTexts ? 1 : 0);
+    result = 31 * result + (myApplyToSubTags ? 1 : 0);
     return result;
   }
 
@@ -215,12 +203,12 @@
     return myXPathCondition.length() == 0;
   }
 
-  public boolean isApplyToSubTagTexts() {
-    return myApplyToSubTagTexts;
+  public boolean isApplyToSubTags() {
+    return myApplyToSubTags;
   }
 
-  public void setApplyToSubTagTexts(final boolean applyToSubTagTexts) {
-    myApplyToSubTagTexts = applyToSubTagTexts;
+  public void setApplyToSubTags(final boolean applyToSubTagTexts) {
+    myApplyToSubTags = applyToSubTagTexts;
   }
 
   @Override
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
index 5ffe327..32a2239 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlAttributeInjection.java
@@ -15,7 +15,6 @@
  */
 package org.intellij.plugins.intelliLang.inject.config;
 
-import com.intellij.openapi.util.JDOMExternalizer;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.xml.XmlAttribute;
@@ -57,8 +56,7 @@
     return element instanceof XmlAttribute && matches((XmlAttribute)element);
   }
 
-  @NotNull
-  public String getDisplayName() {
+  public String getGeneratedName() {
     final String tag = getTagName();
     final String attributeName = getAttributeName();
     if (!attributeName.equals(StringMatcher.NONE.getPattern())) {
@@ -74,6 +72,7 @@
 
   @Override
   public void generatePlaces() {
+    if (StringUtil.isEmpty(getDisplayName())) setDisplayName(getGeneratedName());
     setInjectionPlaces(new InjectionPlace(getCompiler().createElementPattern(getPatternString(this), getDisplayName()), true));
   }
 
@@ -95,25 +94,14 @@
   public XmlAttributeInjection copyFrom(@NotNull BaseInjection o) {
     super.copyFrom(o);
     if (o instanceof XmlAttributeInjection) {
-      final XmlAttributeInjection other = (XmlAttributeInjection)o;
+      XmlAttributeInjection other = (XmlAttributeInjection)o;
+      setApplyToSubTags(other.isApplyToSubTags());
       setAttributeName(other.getAttributeName());
       setAttributeNamespace(other.getAttributeNamespace());
     }
     return this;
   }
 
-  protected void readExternalImpl(Element e) {
-    super.readExternalImpl(e);
-    if (e.getAttribute("injector-id") == null) {
-      setAttributeName(JDOMExternalizer.readString(e, "ATT_NAME"));
-      setAttributeNamespace(JDOMExternalizer.readString(e, "ATT_NAMESPACE"));
-    }
-  }
-
-  protected void writeExternalImpl(Element e) {
-    super.writeExternalImpl(e);
-  }
-
   @SuppressWarnings({"RedundantIfStatement"})
   public boolean equals(Object o) {
     if (this == o) return true;
@@ -142,7 +130,8 @@
     if (StringUtil.isNotEmpty(name)) appendStringPattern(result, ".withLocalName(", name, ")");
     if (StringUtil.isNotEmpty(namespace)) appendStringPattern(result, ".withNamespace(", namespace, ")");
     if (StringUtil.isNotEmpty(injection.getTagName()) || StringUtil.isNotEmpty(injection.getTagNamespace())) {
-      result.append(".withParent(").append(XmlTagInjection.getPatternString(injection)).append(")");
+      result.append(".").append(injection.isApplyToSubTags() ? "inside" : "withParent").append("(")
+        .append(XmlTagInjection.getPatternString(injection)).append(")");
     }
     return result.toString();
   }
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
index ade0c39..19d3a8c 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/XmlTagInjection.java
@@ -31,8 +31,7 @@
     return matches(context) && matchXPath(context);
   }
 
-  @NotNull
-  public String getDisplayName() {
+  public String getGeneratedName() {
     final String name = getTagName();
     return name.length() > 0 ? name : "*";
   }
@@ -49,6 +48,7 @@
 
   @Override
   public void generatePlaces() {
+    if (StringUtil.isEmpty(getDisplayName())) setDisplayName(getGeneratedName());
     setInjectionPlaces(new InjectionPlace(getCompiler().createElementPattern(getPatternString(this), getDisplayName()), true));
   }
 
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
index c4cd838..48df400 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form
@@ -1,9 +1,9 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.AdvancedXmlPanel">
-  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="1" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRoot" 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="20" y="20" width="531" height="97"/>
+      <xy x="20" y="20" width="531" height="123"/>
     </constraints>
     <properties/>
     <border type="none"/>
@@ -25,7 +25,7 @@
             </constraints>
             <properties>
               <labelFor value="7bf4e"/>
-              <text value="&amp;Value Pattern:"/>
+              <text value="&amp;Value pattern:"/>
               <toolTipText value="&lt;html&gt;Enter a regular expression that selects the parts of the tag's or attribute's value the language should be injected into.&lt;br&gt;The pattern should contain exactly one capturing group.&lt;/html&gt;"/>
             </properties>
           </component>
@@ -43,7 +43,7 @@
             </constraints>
             <properties>
               <labelFor value="a6f2"/>
-              <text value="&amp;XPath Condition:"/>
+              <text value="&amp;XPath condition:"/>
               <toolTipText value="&lt;html&gt;Enter an XPath expression that the tag/attribute must match additionally to the name-condition specified above.&lt;br&gt;This requires the XPathView plugin to be installed&lt;/html&gt;"/>
             </properties>
           </component>
@@ -60,11 +60,16 @@
               <grid row="0" column="2" 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="&amp;Single File"/>
+              <text value="Single &amp;file"/>
             </properties>
           </component>
         </children>
       </grid>
+      <vspacer id="5c79c">
+        <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>
     </children>
   </grid>
 </form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
index bcbe680..70051cb 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form
@@ -8,7 +8,7 @@
     <properties/>
     <border type="none"/>
     <children>
-      <grid id="7e115" layout-manager="GridLayoutManager" row-count="2" column-count="2" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+      <grid id="49b27" layout-manager="GridLayoutManager" row-count="2" 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>
           <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"/>
@@ -19,25 +19,25 @@
         </clientProperties>
         <border type="none" title="XML Tag"/>
         <children>
-          <component id="edc9a" class="javax.swing.JLabel">
+          <component id="9c78e" 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="16487"/>
-              <text value="&amp;Local Name:"/>
+              <labelFor value="8f17"/>
+              <text value="&amp;Local name:"/>
             </properties>
           </component>
-          <component id="1068d" class="javax.swing.JLabel">
+          <component id="7d32d" 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="eeee3"/>
+              <labelFor value="3d65f"/>
               <text value="&amp;Namespace:"/>
             </properties>
           </component>
-          <component id="16487" class="com.intellij.ui.EditorTextField" binding="myLocalName" custom-create="true">
+          <component id="8f17" class="com.intellij.ui.EditorTextField" binding="myLocalName" custom-create="true">
             <constraints>
               <grid row="0" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false">
                 <preferred-size width="150" height="-1"/>
@@ -45,24 +45,29 @@
             </constraints>
             <properties/>
           </component>
-          <component id="eeee3" class="com.intellij.openapi.ui.ComboBox" binding="myNamespace" custom-create="true">
+          <component id="3d65f" class="com.intellij.openapi.ui.ComboBox" binding="myNamespace" custom-create="true">
             <constraints>
-              <grid row="1" column="1" row-span="1" col-span="1" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
+              <grid row="1" column="1" row-span="1" col-span="2" vsize-policy="0" hsize-policy="7" anchor="8" fill="1" indent="0" use-parent-layout="false"/>
             </constraints>
             <properties>
               <editable value="true"/>
             </properties>
           </component>
+          <component id="3ed2c" class="javax.swing.JCheckBox" binding="myWithSubtags">
+            <constraints>
+              <grid row="0" column="2" 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="Sub-&amp;tags"/>
+            </properties>
+          </component>
         </children>
       </grid>
-      <component id="bc807" class="javax.swing.JCheckBox" binding="myApplyRecursivelyCheckBox">
+      <vspacer id="bdf19">
         <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"/>
+          <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>
-        <properties>
-          <text value="Apply to all text fragments &amp;recursively"/>
-        </properties>
-      </component>
+      </vspacer>
     </children>
   </grid>
 </form>
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
index 42db562..2b224a1 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.java
@@ -28,7 +28,6 @@
 import org.intellij.lang.regexp.RegExpLanguage;
 import org.intellij.plugins.intelliLang.inject.config.AbstractTagInjection;
 import org.intellij.plugins.intelliLang.inject.config.JspSupportProxy;
-import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
 
 import javax.swing.*;
 import java.util.ArrayList;
@@ -43,14 +42,13 @@
 
   private EditorTextField myLocalName;
   private ComboBox myNamespace;
-  private JCheckBox myApplyRecursivelyCheckBox;
+  private JCheckBox myWithSubtags;
 
   public TagPanel(Project project, AbstractTagInjection injection) {
     super(injection, project);
     $$$setupUI$$$();
 
     myNamespace.setModel(createNamespaceUriModel(myProject));
-    myLocalName.getDocument().addDocumentListener(new TreeUpdateListener());
   }
 
   public static ComboBoxModel createNamespaceUriModel(Project project) {
@@ -95,19 +93,13 @@
   protected void resetImpl() {
     myLocalName.setText(myOrigInjection.getTagName());
     myNamespace.getEditor().setItem(myOrigInjection.getTagNamespace());
-    final boolean isXmlTag = myOrigInjection instanceof XmlTagInjection;
-    myApplyRecursivelyCheckBox.setVisible(isXmlTag);
-    if (isXmlTag) {
-      myApplyRecursivelyCheckBox.setSelected(((XmlTagInjection)myOrigInjection).isApplyToSubTagTexts());
-    }
+    myWithSubtags.setSelected(myOrigInjection.isApplyToSubTags());
   }
 
-  protected void apply(AbstractTagInjection i) {
-    i.setTagName(myLocalName.getText());
-    i.setTagNamespace(getNamespace());
-    if (i instanceof XmlTagInjection) {
-      ((XmlTagInjection)i).setApplyToSubTagTexts(myApplyRecursivelyCheckBox.isSelected());
-    }
+  protected void apply(AbstractTagInjection other) {
+    other.setTagName(myLocalName.getText());
+    other.setTagNamespace(getNamespace());
+    other.setApplyToSubTags(myWithSubtags.isSelected());
   }
 
   private String getNamespace() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
index 1dce7a9..a9d67f3 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.form
@@ -1,22 +1,22 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel">
-  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="5" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="6" 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="500" height="479"/>
+      <xy x="20" y="20" width="500" height="551"/>
     </constraints>
     <properties/>
     <border type="none"/>
     <children>
       <nested-form id="260fa" form-file="org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form" binding="myTagPanel" custom-create="true">
         <constraints>
-          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="2" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
       <grid id="ea19" 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="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+          <grid row="3" 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>
@@ -30,7 +30,7 @@
             </constraints>
             <properties>
               <labelFor value="cca5"/>
-              <text value="L&amp;ocal Name:"/>
+              <text value="L&amp;ocal name:"/>
               <toolTipText value="Regular expression to match the attribute name, e.g. &quot;on.*&quot;"/>
             </properties>
           </component>
@@ -65,19 +65,46 @@
       </grid>
       <vspacer id="f7910">
         <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"/>
+          <grid row="5" column="0" row-span="1" col-span="2" vsize-policy="6" hsize-policy="1" anchor="0" fill="2" indent="0" use-parent-layout="false"/>
         </constraints>
       </vspacer>
       <nested-form id="8cfe8" form-file="org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form" binding="myLanguagePanel" custom-create="true">
         <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
       <nested-form id="b6e0b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form" binding="myAdvancedPanel" custom-create="true">
         <constraints>
-          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="4" column="0" row-span="1" col-span="2" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
+      <grid id="2032c" 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="2" vsize-policy="0" hsize-policy="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="e174b" 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="80ca6"/>
+              <text value="&amp;Name:"/>
+            </properties>
+          </component>
+          <component id="80ca6" class="javax.swing.JTextField" binding="myNameTextField">
+            <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/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
index 9e8e935..79f451d 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlAttributePanel.java
@@ -17,6 +17,8 @@
 
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.EditorTextField;
 import com.intellij.ui.LanguageTextField;
 import org.intellij.lang.regexp.RegExpLanguage;
@@ -35,6 +37,9 @@
 
   private EditorTextField myLocalName;
   private ComboBox myNamespace;
+  private JTextField myNameTextField;
+
+  private boolean myUseGeneratedName;
 
   public XmlAttributePanel(XmlAttributeInjection injection, Project project) {
     super(injection, project);
@@ -43,9 +48,6 @@
     myNamespace.setModel(TagPanel.createNamespaceUriModel(project));
 
     init(injection.copy());
-
-    // be sure to add the listener after initializing the textfield's value
-    myLocalName.getDocument().addDocumentListener(new TreeUpdateListener());
   }
 
   public JPanel getComponent() {
@@ -53,13 +55,21 @@
   }
 
   protected void resetImpl() {
+    myNameTextField.setText(myOrigInjection.getDisplayName());
     myLocalName.setText(myOrigInjection.getAttributeName());
     myNamespace.getEditor().setItem(myOrigInjection.getAttributeNamespace());
+
+    myUseGeneratedName = Comparing.equal(myOrigInjection.getDisplayName(), myOrigInjection.getGeneratedName());
   }
 
-  protected void apply(XmlAttributeInjection i) {
-    i.setAttributeName(myLocalName.getText());
-    i.setAttributeNamespace(getNamespace());
+  protected void apply(XmlAttributeInjection other) {
+    other.setAttributeName(myLocalName.getText());
+    other.setAttributeNamespace(getNamespace());
+
+    String name = myNameTextField.getText();
+    boolean useGenerated = myUseGeneratedName && Comparing.equal(myOrigInjection.getDisplayName(), name);
+    String newName = useGenerated || StringUtil.isEmptyOrSpaces(name) ? other.getGeneratedName() : name;
+    other.setDisplayName(newName);
   }
 
   private String getNamespace() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
index d19d857..36585ab 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.form
@@ -1,33 +1,60 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <form xmlns="http://www.intellij.com/uidesigner/form/" version="1" bind-to-class="org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel">
-  <grid id="27dc6" binding="myRoot" layout-manager="GridLayoutManager" row-count="4" column-count="1" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
+  <grid id="27dc6" binding="myRoot" 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="20" y="20" width="500" height="400"/>
+      <xy x="20" y="20" width="500" height="437"/>
     </constraints>
     <properties/>
     <border type="none"/>
     <children>
       <nested-form id="4c744" form-file="org/intellij/plugins/intelliLang/inject/config/ui/TagPanel.form" binding="myPanel" custom-create="true">
         <constraints>
-          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
       <vspacer id="12f92">
         <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"/>
+          <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>
       <nested-form id="4e64b" form-file="org/intellij/plugins/intelliLang/inject/config/ui/LanguagePanel.form" binding="myLanguagePanel" custom-create="true">
         <constraints>
-          <grid row="0" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
       <nested-form id="fa14a" form-file="org/intellij/plugins/intelliLang/inject/config/ui/AdvancedXmlPanel.form" binding="myAdvancedPanel" custom-create="true">
         <constraints>
-          <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
+          <grid row="3" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="7" anchor="0" fill="1" indent="0" use-parent-layout="false"/>
         </constraints>
       </nested-form>
+      <grid id="d9c54" 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="0" anchor="0" fill="3" indent="0" use-parent-layout="false"/>
+        </constraints>
+        <properties/>
+        <border type="none"/>
+        <children>
+          <component id="d2267" 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="6c531"/>
+              <text value="&amp;Name:"/>
+            </properties>
+          </component>
+          <component id="6c531" class="javax.swing.JTextField" binding="myNameTextField">
+            <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/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
index ffc9214..342cfd6 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/XmlTagPanel.java
@@ -16,6 +16,8 @@
 package org.intellij.plugins.intelliLang.inject.config.ui;
 
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
 import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
 
 import javax.swing.*;
@@ -28,6 +30,9 @@
   AdvancedXmlPanel myAdvancedPanel;
 
   private JPanel myRoot;
+  private JTextField myNameTextField;
+
+  private boolean myUseGeneratedName;
 
   public XmlTagPanel(XmlTagInjection injection, Project project) {
     super(injection, project);
@@ -37,11 +42,16 @@
   }
 
   protected void apply(XmlTagInjection other) {
-    // nothing to do, TagPanel.apply() already does this
+    String name = myNameTextField.getText();
+    boolean useGenerated = myUseGeneratedName && Comparing.equal(myOrigInjection.getDisplayName(), name);
+    String newName = useGenerated || StringUtil.isEmptyOrSpaces(name) ? other.getGeneratedName() : name;
+    other.setDisplayName(newName);
   }
 
   protected void resetImpl() {
-    // same here^
+    myNameTextField.setText(myOrigInjection.getDisplayName());
+
+    myUseGeneratedName = Comparing.equal(myOrigInjection.getDisplayName(), myOrigInjection.getGeneratedName());
   }
 
   public JPanel getComponent() {
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java
deleted file mode 100644
index a0898e0..0000000
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlAttributeInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.XmlAttributeInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel;
-
-public class XmlAttributeInjectionConfigurable extends InjectionConfigurable<XmlAttributeInjection, XmlAttributePanel> {
-  public XmlAttributeInjectionConfigurable(XmlAttributeInjection injection, Runnable treeUpdater, Project project) {
-    super(injection, treeUpdater, project);
-  }
-
-  protected XmlAttributePanel createOptionsPanelImpl() {
-    return new XmlAttributePanel(myInjection, myProject);
-  }
-
-  public String getBannerSlogan() {
-    return "Edit XML Attribute Injection";
-  }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java
deleted file mode 100644
index 655590b..0000000
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/config/ui/configurables/XmlTagInjectionConfigurable.java
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * Copyright 2006 Sascha Weinreuter
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- *     http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package org.intellij.plugins.intelliLang.inject.config.ui.configurables;
-
-import com.intellij.openapi.project.Project;
-import org.intellij.plugins.intelliLang.inject.config.XmlTagInjection;
-import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel;
-
-public class XmlTagInjectionConfigurable extends InjectionConfigurable<XmlTagInjection, XmlTagPanel> {
-  public XmlTagInjectionConfigurable(XmlTagInjection injection, Runnable treeUpdater, Project project) {
-    super(injection, treeUpdater, project);
-  }
-
-  public String getBannerSlogan() {
-    return "Edit XML Text Injection";
-  }
-
-  protected XmlTagPanel createOptionsPanelImpl() {
-    return new XmlTagPanel(myInjection, myProject);
-  }
-}
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
index 6c84a87..abe3349 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjectionSupport.java
@@ -43,8 +43,6 @@
 import org.intellij.plugins.intelliLang.inject.config.ui.AbstractInjectionPanel;
 import org.intellij.plugins.intelliLang.inject.config.ui.XmlAttributePanel;
 import org.intellij.plugins.intelliLang.inject.config.ui.XmlTagPanel;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlAttributeInjectionConfigurable;
-import org.intellij.plugins.intelliLang.inject.config.ui.configurables.XmlTagInjectionConfigurable;
 import org.jdom.Element;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -66,7 +64,7 @@
       final PsiElement p = host.getParent();
       if (p instanceof XmlAttribute) {
         final String s = ((XmlAttribute)p).getName();
-        return !(s.equals("xmlns") || s.startsWith("xmlns:"));
+        return !("xmlns".equals(s) || s.startsWith("xmlns:"));
       }
     }
     else if (host instanceof XmlText) {
@@ -177,7 +175,7 @@
       }
     });
     if (builder.show() == DialogWrapper.OK_EXIT_CODE) {
-      return new AbstractTagInjection().copyFrom(xmlInjection);
+      return xmlInjection.copy();
     }
     return null;
   }
@@ -219,12 +217,15 @@
           result.setTagNamespace(value);
         }
       }
-      else if (result instanceof XmlAttributeInjection &&
-               "inside".equals(condition.getDebugMethodName()) && condition instanceof PatternConditionPlus) {
-        final ElementPattern<?> insidePattern = ((PatternConditionPlus)condition).getValuePattern();
+      else if (result instanceof XmlAttributeInjection && condition instanceof PatternConditionPlus) {
+        boolean strict = "withParent".equals(condition.getDebugMethodName());
+        if (!strict && !"inside".equals(condition.getDebugMethodName())) return null;
+
+        result.setApplyToSubTags(!strict);
+        ElementPattern<?> insidePattern = ((PatternConditionPlus)condition).getValuePattern();
         if (!XmlTag.class.equals(insidePattern.getCondition().getInitialCondition().getAcceptedClass())) return null;
         for (PatternCondition<?> insideCondition : insidePattern.getCondition().getConditions()) {
-          final String tagValue = extractValue(insideCondition);
+          String tagValue = extractValue(insideCondition);
           if (tagValue == null) return null;
           if ("withLocalName".equals(insideCondition.getDebugMethodName())) {
             result.setTagName(tagValue);
@@ -232,10 +233,11 @@
           else if ("withNamespace".equals(insideCondition.getDebugMethodName())) {
             result.setTagNamespace(tagValue);
           }
-
         }
       }
-      else return null;
+      else {
+        return null;
+      }
     }
     result.generatePlaces();
     return result;
@@ -265,14 +267,17 @@
     return null;
   }
 
-  public BaseInjection createInjection(final Element element) {
-    if (element.getName().equals(XmlAttributeInjection.class.getSimpleName())) {
+  public BaseInjection createInjection(Element element) {
+    String place = StringUtil.notNullize(element.getChildText("place"), "");
+    if (place.startsWith("xmlAttribute")) {
       return new XmlAttributeInjection();
     }
-    else if (element.getName().equals(XmlTagInjection.class.getSimpleName())) {
+    else if (place.startsWith("xmlTag")) {
       return new XmlTagInjection();
     }
-    return new AbstractTagInjection();
+    else {
+      return new BaseInjection(XML_SUPPORT_ID);
+    }
   }
 
   public Configurable[] createSettings(final Project project, final Configuration configuration) {
@@ -298,12 +303,10 @@
     final AbstractTagInjection originalInjection = (AbstractTagInjection)configuration.findExistingInjection(template);
 
     final XmlTagInjection newInjection = originalInjection == null? template : new XmlTagInjection().copyFrom(originalInjection);
-    if (InjectLanguageAction.doEditConfigurable(project, new XmlTagInjectionConfigurable(newInjection, null, project))) {
-      configuration.replaceInjectionsWithUndo(
-        project, Collections.singletonList(newInjection),
-        ContainerUtil.createMaybeSingletonList(originalInjection),
-        Collections.<PsiElement>emptyList());
-    }
+    configuration.replaceInjectionsWithUndo(
+      project, Collections.singletonList(newInjection),
+      ContainerUtil.createMaybeSingletonList(originalInjection),
+      Collections.<PsiElement>emptyList());
   }
 
   private static boolean doInjectInAttributeValue(final XmlAttributeValue host, final String languageId) {
@@ -327,12 +330,10 @@
     final Configuration configuration = InjectorUtils.getEditableInstance(project);
     final BaseInjection originalInjection = configuration.findExistingInjection(template);
     final BaseInjection newInjection = originalInjection == null ? template : originalInjection.copy();
-    if (InjectLanguageAction.doEditConfigurable(project, new XmlAttributeInjectionConfigurable((XmlAttributeInjection)newInjection, null, project))) {
-      configuration.replaceInjectionsWithUndo(
-        project, Collections.singletonList(newInjection),
-        ContainerUtil.createMaybeSingletonList(originalInjection),
-        Collections.<PsiElement>emptyList());
-    }
+    configuration.replaceInjectionsWithUndo(
+      project, Collections.singletonList(newInjection),
+      ContainerUtil.createMaybeSingletonList(originalInjection),
+      Collections.<PsiElement>emptyList());
   }
 
   private static ArrayList<BaseInjection> collectInjections(final PsiElement host,
diff --git a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
index f8026edb..c7808b0 100644
--- a/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
+++ b/plugins/IntelliLang/xml-support/org/intellij/plugins/intelliLang/inject/xml/XmlLanguageInjector.java
@@ -32,6 +32,7 @@
 import com.intellij.psi.xml.*;
 import com.intellij.util.PairProcessor;
 import com.intellij.util.PatternValuesIndex;
+import com.intellij.util.containers.ContainerUtil;
 import gnu.trove.THashMap;
 import org.intellij.plugins.intelliLang.Configuration;
 import org.intellij.plugins.intelliLang.inject.InjectedLanguage;
@@ -113,8 +114,7 @@
           if (language == null) continue;
           final boolean separateFiles = !injection.isSingleFile() && StringUtil.isNotEmpty(injection.getValuePattern());
 
-          final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result =
-            new ArrayList<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>>();
+          final List<Trinity<PsiLanguageInjectionHost, InjectedLanguage, TextRange>> result = ContainerUtil.newArrayList();
 
           xmlTag.acceptChildren(new PsiElementVisitor() {
             @Override
@@ -130,7 +130,7 @@
               }
               else if (element instanceof XmlTag) {
                 if (!separateFiles) unparsableRef.set(Boolean.TRUE);
-                if (injection instanceof AbstractTagInjection && ((AbstractTagInjection)injection).isApplyToSubTagTexts()) {
+                if (injection instanceof AbstractTagInjection && ((AbstractTagInjection)injection).isApplyToSubTags()) {
                   element.acceptChildren(this);
                 }
               }
diff --git a/plugins/git4idea/src/git4idea/log/GitLogProvider.java b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
index 0a8bc372..672e4eb 100644
--- a/plugins/git4idea/src/git4idea/log/GitLogProvider.java
+++ b/plugins/git4idea/src/git4idea/log/GitLogProvider.java
@@ -29,12 +29,7 @@
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.VcsLogBranchFilter;
-import com.intellij.vcs.log.data.VcsLogDateFilter;
-import com.intellij.vcs.log.data.VcsLogStructureFilter;
-import com.intellij.vcs.log.data.VcsLogUserFilter;
 import com.intellij.vcs.log.impl.HashImpl;
-import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
 import git4idea.GitLocalBranch;
 import git4idea.GitRemoteBranch;
 import git4idea.GitVcs;
@@ -189,7 +184,11 @@
   @NotNull
   @Override
   public List<? extends VcsFullCommitDetails> getFilteredDetails(@NotNull final VirtualFile root,
-                                                                 @NotNull Collection<VcsLogFilter> filters,
+                                                                 @NotNull Collection<VcsLogBranchFilter> branchFilters,
+                                                                 @NotNull Collection<VcsLogUserFilter> userFilters,
+                                                                 @NotNull Collection<VcsLogDateFilter> dateFilters,
+                                                                 @NotNull Collection<VcsLogTextFilter> textFilters,
+                                                                 @NotNull Collection<VcsLogStructureFilter> structureFilters,
                                                                  int maxCount) throws VcsException {
     if (!isRepositoryReady(root)) {
       return Collections.emptyList();
@@ -197,21 +196,19 @@
 
     List<String> filterParameters = ContainerUtil.newArrayList();
 
-    List<VcsLogBranchFilter> branchFilters = ContainerUtil.findAll(filters, VcsLogBranchFilter.class);
     if (!branchFilters.isEmpty()) {
       // git doesn't support filtering by several branches very well (--branches parameter give a weak pattern capabilities)
       // => by now assuming there is only one branch filter.
       if (branchFilters.size() > 1) {
         LOG.warn("More than one branch filter was passed. Using only the first one.");
       }
-      VcsLogBranchFilter branchFilter = branchFilters.get(0);
+      VcsLogBranchFilter branchFilter = branchFilters.iterator().next();
       filterParameters.add(branchFilter.getBranchName());
     }
     else {
       filterParameters.addAll(GitHistoryUtils.LOG_ALL);
     }
 
-    List<VcsLogUserFilter> userFilters = ContainerUtil.findAll(filters, VcsLogUserFilter.class);
     if (!userFilters.isEmpty()) {
       String authorFilter = joinFilters(userFilters, new Function<VcsLogUserFilter, String>() {
         @Override
@@ -222,7 +219,6 @@
       filterParameters.add(prepareParameter("author", authorFilter));
     }
 
-    List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
     if (!dateFilters.isEmpty()) {
       // assuming there is only one date filter, until filter expressions are defined
       VcsLogDateFilter filter = dateFilters.iterator().next();
@@ -234,7 +230,6 @@
       }
     }
 
-    List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
     if (textFilters.size() > 1) {
       LOG.warn("Expected only one text filter: " + textFilters);
     }
@@ -249,8 +244,7 @@
     }
     filterParameters.add("--date-order");
 
-    // note: this filter must be the last parameter, because it uses "--" which separates parameters from paths
-    List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
+    // note: structure filter must be the last parameter, because it uses "--" which separates parameters from paths
     if (!structureFilters.isEmpty()) {
       filterParameters.add("--");
       for (VcsLogStructureFilter filter : structureFilters) {
@@ -281,7 +275,7 @@
     return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
   }
 
-  private static <T> String joinFilters(List<T> filters, Function<T, String> toString) {
+  private static <T> String joinFilters(Collection<T> filters, Function<T, String> toString) {
     return StringUtil.join(filters, toString, "\\|");
   }
 
diff --git a/plugins/gradle/src/META-INF/plugin.xml b/plugins/gradle/src/META-INF/plugin.xml
index fc7d254..034ef35 100644
--- a/plugins/gradle/src/META-INF/plugin.xml
+++ b/plugins/gradle/src/META-INF/plugin.xml
@@ -67,12 +67,14 @@
 
     <externalSystemConfigLocator implementation="org.jetbrains.plugins.gradle.service.settings.GradleConfigLocator"/>
     <externalSystemManager implementation="org.jetbrains.plugins.gradle.GradleManager"/>
+    <externalProjectDataService implementation="org.jetbrains.plugins.gradle.service.project.data.BuildClasspathModuleGradleDataService"/>
 
     <applicationService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleInstallationManager"/>
 
     <projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleSettings"/>
     <projectService serviceImplementation="org.jetbrains.plugins.gradle.settings.GradleLocalSettings"/>
     <projectService serviceImplementation="org.jetbrains.plugins.gradle.service.project.GradleNotification"/>
+    <projectService serviceImplementation="org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager"/>
 
     <configurationProducer implementation="org.jetbrains.plugins.gradle.service.execution.GradleRuntimeConfigurationProducer"/>
 
diff --git a/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
index 3989c7c..430ac6f 100644
--- a/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
+++ b/plugins/gradle/src/META-INF/services/org.jetbrains.plugins.gradle.model.ModelBuilderService
@@ -16,3 +16,4 @@
 org.jetbrains.plugins.gradle.model.builder.WarModelBuilderImpl
 org.jetbrains.plugins.gradle.model.builder.ModelDependenciesBuilderImpl
 org.jetbrains.plugins.gradle.model.builder.ModuleExtendedModelBuilderImpl
+org.jetbrains.plugins.gradle.model.builder.ModelBuildScriptClasspathBuilderImpl
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
index f85c75a..d1fa23a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleClassFinder.java
@@ -16,13 +16,15 @@
 
 package org.jetbrains.plugins.gradle.config;
 
+import com.intellij.openapi.externalSystem.psi.search.ExternalModuleBuildGlobalSearchScope;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.NonClasspathClassFinder;
+import com.intellij.psi.search.GlobalSearchScope;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
 
-import java.util.Collections;
 import java.util.List;
 
 /**
@@ -30,19 +32,31 @@
  */
 public class GradleClassFinder extends NonClasspathClassFinder {
 
-  @NotNull private final GradleInstallationManager myLibraryManager;
+  @NotNull private final GradleBuildClasspathManager myBuildClasspathManager;
 
-  public GradleClassFinder(Project project, @NotNull GradleInstallationManager manager) {
-    super(project, true, true);
-    myLibraryManager = manager;
+  public GradleClassFinder(Project project, @NotNull GradleBuildClasspathManager buildClasspathManager) {
+    super(project, true);
+    myBuildClasspathManager = buildClasspathManager;
   }
 
   @Override
   protected List<VirtualFile> calcClassRoots() {
-    final List<VirtualFile> roots = myLibraryManager.getClassRoots(myProject);
-    if (roots != null) {
-      return roots;
+    // do not use default NonClasspathClassFinder caching strategy based on PSI change
+    // the caching performed in GradleBuildClasspathManager
+    throw new AssertionError();
+  }
+
+  @Override
+  protected List<VirtualFile> getClassRoots() {
+    return myBuildClasspathManager.getAllClasspathEntries();
+  }
+
+  @Override
+  protected List<VirtualFile> getClassRoots(@Nullable GlobalSearchScope scope) {
+    if (scope instanceof ExternalModuleBuildGlobalSearchScope) {
+      ExternalModuleBuildGlobalSearchScope externalModuleBuildGlobalSearchScope = (ExternalModuleBuildGlobalSearchScope)scope;
+      return myBuildClasspathManager.getModuleClasspathEntries(externalModuleBuildGlobalSearchScope.getExternalModulePath());
     }
-    return Collections.emptyList();
+    return myBuildClasspathManager.getAllClasspathEntries();
   }
 }
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
index b7ecd35..d598490 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/config/GradleScriptType.java
@@ -21,12 +21,18 @@
 import com.intellij.execution.configurations.JavaParameters;
 import com.intellij.execution.configurations.RunProfile;
 import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.psi.search.ExternalModuleBuildGlobalSearchScope;
 import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.module.ModuleUtilCore;
 import com.intellij.openapi.project.Project;
+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.roots.impl.LibraryScopeCache;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.io.FileUtilRt;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VfsUtilCore;
 import com.intellij.openapi.vfs.VirtualFile;
@@ -40,8 +46,10 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.execution.GradleTaskLocation;
-import org.jetbrains.plugins.gradle.util.GradleConstants;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
 import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.plugins.gradle.service.resolve.GradleResolverUtil;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
 import org.jetbrains.plugins.groovy.config.GroovyConfigUtils;
 import org.jetbrains.plugins.groovy.extensions.GroovyScriptType;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFile;
@@ -72,9 +80,9 @@
   private static final Pattern MAIN_CLASS_NAME_PATTERN = Pattern.compile("\nSTARTER_MAIN_CLASS=(.*)\n");
 
   public static final GroovyScriptType INSTANCE = new GradleScriptType();
-  
+
   private GradleScriptType() {
-    super(GradleConstants.EXTENSION);    
+    super(GradleConstants.EXTENSION);
   }
 
   @NotNull
@@ -89,7 +97,7 @@
     if (params == null) {
       return false;
     }
-    
+
     final List<String> tasks = getTasksTarget(location);
     if (tasks == null) {
       return false;
@@ -218,7 +226,9 @@
           throw new CantRunException(String.format("Module '%s' is not backed by gradle", module.getName()));
         }
         final VirtualFile gradleHome = libraryManager.getGradleHome(module, project, rootProjectPath);
-        assert gradleHome != null;
+        if(gradleHome == null) {
+          throw new CantRunException("Gradle home can not be found");
+        }
 
         params.setMainClass(findMainClass(gradleHome, script, project));
 
@@ -249,11 +259,11 @@
         params.getVMParametersList().add("-Dgradle.home=" + FileUtil.toSystemDependentName(gradleHome.getPath()));
 
         setToolsJar(params);
-        
+
         final String scriptPath = configuration.getScriptPath();
         if (scriptPath == null) {
           throw new CantRunException("Target script is undefined");
-        } 
+        }
         params.getProgramParametersList().add("--build-file");
         params.getProgramParametersList().add(FileUtil.toSystemDependentName(scriptPath));
         params.getProgramParametersList().addParametersString(configuration.getProgramParameters());
@@ -298,22 +308,28 @@
 
   @Override
   public GlobalSearchScope patchResolveScope(@NotNull GroovyFile file, @NotNull GlobalSearchScope baseScope) {
+    if (!FileUtilRt.extensionEquals(file.getName(), GradleConstants.EXTENSION)) return baseScope;
+
+    final Collection<VirtualFile> files;
+    GlobalSearchScope result = GlobalSearchScope.EMPTY_SCOPE;
     final Module module = ModuleUtilCore.findModuleForPsiElement(file);
-    final GradleInstallationManager libraryManager = ServiceManager.getService(GradleInstallationManager.class);
     if (module != null) {
-      if (libraryManager.getGradleHome(module) != null) {
-        return baseScope;
+      for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+        if (entry instanceof JdkOrderEntry) {
+          GlobalSearchScope scopeForSdk = LibraryScopeCache.getInstance(module.getProject()).getScopeForSdk((JdkOrderEntry)entry);
+          result = result.uniteWith(scopeForSdk);
+        }
       }
-    }
 
-    final Collection<VirtualFile> files = libraryManager.getClassRoots(file.getProject());
-    if (files == null || files.isEmpty()) {
-      return baseScope;
-    }
+      String modulePath = module.getOptionValue(ExternalSystemConstants.LINKED_PROJECT_PATH_KEY);
+      if(modulePath == null) return result;
 
-    GlobalSearchScope result = baseScope;
-    for (final VirtualFile root : files) {
-      result = result.uniteWith(new NonClasspathDirectoryScope(root));
+      files = GradleBuildClasspathManager.getInstance(file.getProject()).getModuleClasspathEntries(modulePath);
+
+      for (final VirtualFile root : files) {
+        result = result.uniteWith(new NonClasspathDirectoryScope(root));
+      }
+      result = new ExternalModuleBuildGlobalSearchScope(result, modulePath);
     }
     return result;
   }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
index f34748e..d14125e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/integrations/maven/ImportMavenRepositoriesTask.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.plugins.gradle.integrations.maven;
 
+import com.intellij.openapi.application.ReadAction;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
 import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
@@ -97,9 +98,9 @@
 
     final PsiFile[] psiFiles = ArrayUtil.toObjectArray(psiFileList, PsiFile.class);
 
-    final Set<MavenRemoteRepository> mavenRemoteRepositories = new WriteCommandAction<Set<MavenRemoteRepository>>(myProject, psiFiles) {
+    final Set<MavenRemoteRepository> mavenRemoteRepositories = new ReadAction<Set<MavenRemoteRepository>>() {
       @Override
-      protected void run(Result<Set<MavenRemoteRepository>> result) throws Throwable {
+      protected void run(@NotNull Result<Set<MavenRemoteRepository>> result) throws Throwable {
         Set<MavenRemoteRepository> myRemoteRepositories = ContainerUtil.newHashSet();
         for (PsiFile psiFile : psiFiles) {
           List<GrClosableBlock> repositoriesBlocks = ContainerUtil.newArrayList();
@@ -118,7 +119,7 @@
       }
     }.execute().getResultObject();
 
-    if (mavenRemoteRepositories.isEmpty()) return;
+    if (mavenRemoteRepositories == null || mavenRemoteRepositories.isEmpty()) return;
 
     MavenRepositoriesHolder.getInstance(myProject).update(mavenRemoteRepositories);
 
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java
new file mode 100644
index 0000000..6854655
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/BuildScriptClasspathModel.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model;
+
+import org.gradle.tooling.model.DomainObjectSet;
+
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public interface BuildScriptClasspathModel extends Serializable {
+  DomainObjectSet<? extends ClasspathEntryModel> getClasspath();
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java
new file mode 100644
index 0000000..09120ca
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/ClasspathEntryModel.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public interface ClasspathEntryModel {
+  @NotNull
+  File getClassesFile();
+
+  @Nullable
+  File getSourcesFile();
+
+  @Nullable
+  File getJavadocFile();
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
index 7186312..78caa4d 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/GradleDependencyScope.java
@@ -22,11 +22,6 @@
  * @since 11/25/13
  */
 public enum GradleDependencyScope {
-  // Implicit scopes
-  PROVIDED("provided", "provided", true, true, true, true),
-  OPTIONAL("optional", "compile", true, true, true, true),
-
-
   // Java Plugin Scopes
   /**
    * Compile time dependencies
@@ -74,7 +69,11 @@
   /**
    * Compiles test Scala source files.
    */
-  COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true);
+  COMPILE_TEST_SCALA("compileTestScala", "test", false, false, true, true),
+
+  // Implicit scopes
+  PROVIDED("provided", "provided", true, true, true, true),
+  OPTIONAL("optional", "compile", true, true, true, true),;
 
   private final String myGradleName;
   private final String myIdeaMappingName;
@@ -124,7 +123,7 @@
   @Nullable
   public static GradleDependencyScope fromIdeaMappingName(final String ideaMappingName) {
     for (GradleDependencyScope scope : values()) {
-      if (scope.myIdeaMappingName.equals(ideaMappingName.toLowerCase())) return scope;
+      if (scope.myIdeaMappingName.equals(ideaMappingName)) return scope;
     }
     return null;
   }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java
new file mode 100644
index 0000000..875d9cc
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImpl.java
@@ -0,0 +1,93 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import org.gradle.api.Project;
+import org.gradle.api.artifacts.Configuration;
+import org.gradle.plugins.ide.idea.IdeaPlugin;
+import org.gradle.plugins.ide.idea.model.IdeaModel;
+import org.gradle.plugins.ide.internal.IdeDependenciesExtractor;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ModelBuilderService;
+import org.jetbrains.plugins.gradle.model.internal.BuildScriptClasspathModelImpl;
+import org.jetbrains.plugins.gradle.model.internal.ClasspathEntryModelImpl;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class ModelBuildScriptClasspathBuilderImpl implements ModelBuilderService {
+
+  @Override
+  public boolean canBuild(String modelName) {
+    return BuildScriptClasspathModel.class.getName().equals(modelName);
+  }
+
+  @Nullable
+  @Override
+  public Object buildAll(final String modelName, final Project project) {
+    boolean offline = false;
+    boolean downloadJavadoc = false;
+    boolean downloadSources = true;
+
+    final IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
+
+    if (ideaPlugin != null) {
+      IdeaModel ideaModel = ideaPlugin.getModel();
+      if (ideaModel != null && ideaModel.getModule() != null) {
+        offline = ideaModel.getModule().isOffline();
+        downloadJavadoc = ideaModel.getModule().isDownloadJavadoc();
+        downloadSources = ideaModel.getModule().isDownloadSources();
+      }
+    }
+
+    final IdeDependenciesExtractor dependenciesExtractor = new IdeDependenciesExtractor();
+
+    final Configuration configuration = project.getBuildscript().getConfigurations().findByName("classpath");
+    Collection<Configuration> plusConfigurations = Collections.singletonList(configuration);
+
+    BuildScriptClasspathModelImpl buildScriptClasspath = new BuildScriptClasspathModelImpl();
+
+    if (!offline) {
+      // download sources and/or javadoc
+      List<IdeDependenciesExtractor.IdeRepoFileDependency> repoFileDependencies = dependenciesExtractor.extractRepoFileDependencies(
+        project.getConfigurations(), plusConfigurations, new ArrayList<Configuration>(), downloadSources, downloadJavadoc);
+
+      for (IdeDependenciesExtractor.IdeRepoFileDependency dependency : repoFileDependencies) {
+        if (dependency.getFile() == null) continue;
+
+        buildScriptClasspath.add(
+          new ClasspathEntryModelImpl(dependency.getFile(), dependency.getSourceFile(), dependency.getJavadocFile()));
+      }
+    }
+
+    final List<IdeDependenciesExtractor.IdeLocalFileDependency> localFileDependencies =
+      dependenciesExtractor.extractLocalFileDependencies(plusConfigurations, new ArrayList<Configuration>());
+
+    for (IdeDependenciesExtractor.IdeLocalFileDependency dependency : localFileDependencies) {
+      if (dependency.getFile() == null) continue;
+      buildScriptClasspath.add(new ClasspathEntryModelImpl(dependency.getFile(), null, null));
+    }
+
+    return buildScriptClasspath;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
index 0586482..4c0e3914 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImpl.java
@@ -24,6 +24,7 @@
 import org.gradle.plugins.ide.idea.model.IdeaModel;
 import org.gradle.plugins.ide.internal.IdeDependenciesExtractor;
 import org.gradle.tooling.model.idea.IdeaDependency;
+import org.gradle.util.GradleVersion;
 import org.jetbrains.annotations.Nullable;
 import org.jetbrains.plugins.gradle.model.GradleDependencyScope;
 import org.jetbrains.plugins.gradle.model.ModelBuilderService;
@@ -54,7 +55,7 @@
   public Object buildAll(final String modelName, final Project project) {
     final List<IdeaDependency> dependencies = new ArrayList<IdeaDependency>();
 
-    final Map<DependencyVersionId, Scopes> scopesMap = new HashMap<DependencyVersionId, Scopes>();
+    final Map<DependencyVersionId, Scopes> scopesMap = new LinkedHashMap<DependencyVersionId, Scopes>();
     final IdeDependenciesExtractor dependenciesExtractor = new IdeDependenciesExtractor();
 
     boolean offline = false;
@@ -148,6 +149,7 @@
             versionId.getClassifier()
           );
           libraryDependency.setFile(fileDependency.getFile());
+          attachGradleSdkSources(libraryDependency, fileDependency);
           dependencies.add(libraryDependency);
         }
       }
@@ -156,6 +158,32 @@
     return new ProjectDependenciesModelImpl(project.getPath(), dependencies);
   }
 
+  private static void attachGradleSdkSources(IdeaSingleEntryLibraryDependencyImpl libraryDependency,
+                                             IdeDependenciesExtractor.IdeLocalFileDependency localFileDependency) {
+    final String libName = localFileDependency.getFile().getName();
+    if (localFileDependency.getFile() == null || !libName.startsWith("gradle-")) return;
+
+    File libOrPluginsFile = localFileDependency.getFile().getParentFile();
+    if (libOrPluginsFile != null && ("plugins".equals(libOrPluginsFile.getName()))) {
+      libOrPluginsFile = libOrPluginsFile.getParentFile();
+    }
+
+    if (libOrPluginsFile != null && "lib".equals(libOrPluginsFile.getName()) && libOrPluginsFile.getParentFile() != null) {
+      File srcDir = new File(libOrPluginsFile.getParentFile(), "src");
+      if (GradleVersion.current().compareTo(GradleVersion.version("1.9")) >= 0) {
+        int endIndex = libName.indexOf(GradleVersion.current().getVersion() + ".jar");
+        if (endIndex != -1) {
+          String srcDirChild = libName.substring("gradle-".length(), endIndex - 1);
+          srcDir = new File(srcDir, srcDirChild);
+        }
+      }
+
+      if (srcDir.isDirectory()) {
+        libraryDependency.setSource(srcDir);
+      }
+    }
+  }
+
   @Nullable
   private static String findDeDuplicatedModuleName(Project project) {
     if (project.hasProperty(MODULE_PROPERTY)) {
@@ -261,15 +289,13 @@
   private static GradleDependencyScope deduceScope(String configurationName,
                                                    Map<String, Map<String, Collection<Configuration>>> userScopes) {
     GradleDependencyScope scope = GradleDependencyScope.fromName(configurationName);
-    if (scope == null) {
-      for (Map.Entry<String, Map<String, Collection<Configuration>>> entry : userScopes.entrySet()) {
-        Collection<Configuration> plusConfigurations = entry.getValue().get("plus");
-        if (plusConfigurations == null) continue;
+    for (Map.Entry<String, Map<String, Collection<Configuration>>> entry : userScopes.entrySet()) {
+      Collection<Configuration> plusConfigurations = entry.getValue().get("plus");
+      if (plusConfigurations == null) continue;
 
-        for (Configuration plus : plusConfigurations) {
-          if (plus.getName().equals(configurationName)) {
-            return GradleDependencyScope.fromIdeaMappingName(entry.getKey());
-          }
+      for (Configuration plus : plusConfigurations) {
+        if (plus.getName().equals(configurationName)) {
+          return GradleDependencyScope.fromIdeaMappingName(entry.getKey().toLowerCase());
         }
       }
     }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
index 3dc8540..44eb6cf 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImpl.java
@@ -15,6 +15,7 @@
  */
 package org.jetbrains.plugins.gradle.model.builder;
 
+import groovy.lang.GroovyObject;
 import org.gradle.api.Project;
 import org.gradle.api.Task;
 import org.gradle.api.tasks.SourceSet;
@@ -69,10 +70,17 @@
 
     moduleVersionModel.setArtifacts(artifacts);
 
+    final Set<String> sourceDirectories = new HashSet<String>();
     final Set<String> testDirectories = new HashSet<String>();
+    final Set<String> resourceDirectories = new HashSet<String>();
+    final Set<String> testResourceDirectories = new HashSet<String>();
+
+    final List<File> testClassesDirs = new ArrayList<File>();
     for (Task task : project.getTasks()) {
       if (task instanceof Test) {
         Test test = (Test)task;
+        testClassesDirs.add(test.getTestClassesDir());
+
         if (test.hasProperty(TEST_SRC_DIRS_PROPERTY)) {
           Object testSrcDirs = test.property(TEST_SRC_DIRS_PROPERTY);
           if (testSrcDirs instanceof Iterable) {
@@ -84,40 +92,58 @@
       }
     }
 
-    final Set<String> javaDirectories = new HashSet<String>();
-    final Set<String> resourceDirectories = new HashSet<String>();
-
     if (project.hasProperty(SOURCE_SETS_PROPERTY)) {
       Object sourceSets = project.property(SOURCE_SETS_PROPERTY);
       if (sourceSets instanceof SourceSetContainer) {
         SourceSetContainer sourceSetContainer = (SourceSetContainer)sourceSets;
         for (SourceSet sourceSet : sourceSetContainer) {
-          for (File javaSrcDir : sourceSet.getAllJava().getSrcDirs()) {
-            addFilePath(javaDirectories, javaSrcDir);
+          for (File javaSrcDir : sourceSet.getJava().getSrcDirs()) {
+            boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
+            addFilePath(isTestDir ? testDirectories : sourceDirectories, javaSrcDir);
           }
           for (File resourcesSrcDir : sourceSet.getResources().getSrcDirs()) {
-            addFilePath(resourceDirectories, resourcesSrcDir);
+            boolean isTestDir = isTestDir(sourceSet, testClassesDirs);
+            addFilePath(isTestDir ? testResourceDirectories : resourceDirectories, resourcesSrcDir);
           }
         }
       }
     }
 
-
     File projectDir = project.getProjectDir();
     IdeaContentRootImpl contentRoot = new IdeaContentRootImpl(projectDir);
 
-    enrichDataFromIdeaPlugin(project, contentRoot, javaDirectories, testDirectories);
+    final Set<String> ideaSourceDirectories = new HashSet<String>();
+    final Set<String> ideaTestDirectories = new HashSet<String>();
+    final Set<String> ideaExtResourceDirectories = new HashSet<String>();
+    final Set<String> ideaExtTestResourceDirectories = new HashSet<String>();
+    final Set<File> excludeDirectories = new HashSet<File>();
 
-    javaDirectories.removeAll(testDirectories);
-    javaDirectories.removeAll(resourceDirectories);
+    enrichDataFromIdeaPlugin(project, excludeDirectories, ideaSourceDirectories, ideaTestDirectories,
+                             ideaExtResourceDirectories, ideaExtTestResourceDirectories);
 
-    final Set<String> testResourceDirectories = new HashSet<String>(resourceDirectories);
-    testResourceDirectories.retainAll(testDirectories);
+    if (ideaSourceDirectories.isEmpty()) {
+      sourceDirectories.clear();
+      resourceDirectories.clear();
+    }
+    if (ideaTestDirectories.isEmpty()) {
+      testDirectories.clear();
+      testResourceDirectories.clear();
+    }
 
-    testDirectories.removeAll(resourceDirectories);
-    resourceDirectories.removeAll(testResourceDirectories);
+    ideaSourceDirectories.removeAll(resourceDirectories);
+    sourceDirectories.addAll(ideaSourceDirectories);
+    ideaTestDirectories.removeAll(testResourceDirectories);
+    testDirectories.addAll(ideaTestDirectories);
 
-    for (String javaDir : javaDirectories) {
+    resourceDirectories.addAll(ideaExtResourceDirectories);
+    testResourceDirectories.addAll(ideaExtTestResourceDirectories);
+
+    // ensure disjoint directories with different type
+    resourceDirectories.removeAll(sourceDirectories);
+    testDirectories.removeAll(sourceDirectories);
+    testResourceDirectories.removeAll(testDirectories);
+
+    for (String javaDir : sourceDirectories) {
       contentRoot.addSourceDirectory(new IdeaSourceDirectoryImpl(new File(javaDir)));
     }
     for (String testDir : testDirectories) {
@@ -129,11 +155,29 @@
     for (String testResourceDir : testResourceDirectories) {
       contentRoot.addTestResourceDirectory(new IdeaSourceDirectoryImpl(new File(testResourceDir)));
     }
+    for (File excludeDir : excludeDirectories) {
+      contentRoot.addExcludeDirectory(excludeDir);
+    }
 
     moduleVersionModel.setContentRoots(Collections.<ExtIdeaContentRoot>singleton(contentRoot));
     return moduleVersionModel;
   }
 
+  private static boolean isTestDir(SourceSet sourceSet, List<File> testClassesDirs) {
+    if (SourceSet.TEST_SOURCE_SET_NAME.equals(sourceSet.getName())) return true;
+    if (SourceSet.MAIN_SOURCE_SET_NAME.equals(sourceSet.getName())) return false;
+
+    File sourceSetClassesDir = sourceSet.getOutput().getClassesDir();
+    for (File testClassesDir : testClassesDirs) {
+      do {
+        if (sourceSetClassesDir.getPath().equals(testClassesDir.getPath())) return true;
+      }
+      while ((testClassesDir = testClassesDir.getParentFile()) != null);
+    }
+
+    return false;
+  }
+
   private static void addFilePath(Set<String> filePathSet, Object file) {
     if (file instanceof File) {
       try {
@@ -145,9 +189,11 @@
   }
 
   private static void enrichDataFromIdeaPlugin(Project project,
-                                               IdeaContentRootImpl contentRoot,
+                                               Set<File> excludeDirectories,
                                                Set<String> javaDirectories,
-                                               Set<String> testDirectories) {
+                                               Set<String> testDirectories,
+                                               Set<String> ideaExtResourceDirectories,
+                                               Set<String> ideaExtTestResourceDirectories) {
 
     IdeaPlugin ideaPlugin = project.getPlugins().getPlugin(IdeaPlugin.class);
     if (ideaPlugin == null) return;
@@ -156,7 +202,7 @@
     if (ideaModel == null || ideaModel.getModule() == null) return;
 
     for (File excludeDir : ideaModel.getModule().getExcludeDirs()) {
-      contentRoot.addExcludeDirectory(excludeDir);
+      excludeDirectories.add(excludeDir);
     }
     for (File file : ideaModel.getModule().getSourceDirs()) {
       javaDirectories.add(file.getPath());
@@ -164,5 +210,25 @@
     for (File file : ideaModel.getModule().getTestSourceDirs()) {
       testDirectories.add(file.getPath());
     }
+
+    ideaExtResourceDirectories.addAll(getExtDirs("resourceDirs", ideaModel.getModule()));
+    ideaExtTestResourceDirectories.addAll(getExtDirs("testResourceDirs", ideaModel.getModule()));
+  }
+
+  private static List<String> getExtDirs(String propertyName, GroovyObject ideaModule) {
+    List<String> directories = new ArrayList<String>();
+    Object resourceDirs = ideaModule.getProperty(propertyName);
+    if (resourceDirs instanceof Iterable) {
+      for (Object o : Iterable.class.cast(resourceDirs)) {
+        if (o instanceof File) {
+          directories.add(File.class.cast(o).getPath());
+        }
+        else if (o instanceof String) {
+          directories.add((String)o);
+        }
+      }
+    }
+
+    return directories;
   }
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java
new file mode 100644
index 0000000..cc252a9
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/BuildScriptClasspathData.java
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.data;
+
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.ProjectSystemId;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class BuildScriptClasspathData extends AbstractExternalEntityData {
+  private static final long serialVersionUID = 1L;
+  @NotNull
+  public static final Key<BuildScriptClasspathData> KEY =
+    Key.create(BuildScriptClasspathData.class, ProjectKeys.LIBRARY_DEPENDENCY.getProcessingWeight() + 1);
+
+  @NotNull
+  private final List<ClasspathEntry> myClasspathEntries;
+
+
+  public BuildScriptClasspathData(@NotNull ProjectSystemId owner, @NotNull List<ClasspathEntry> classpathEntries) {
+    super(owner);
+    myClasspathEntries = classpathEntries;
+  }
+
+  @NotNull
+  public List<ClasspathEntry> getClasspathEntries() {
+    return myClasspathEntries;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java
new file mode 100644
index 0000000..fa0959f
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/data/ClasspathEntry.java
@@ -0,0 +1,84 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.data;
+
+import com.intellij.openapi.util.io.FileUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/23/13
+ */
+public class ClasspathEntry implements Serializable {
+
+  private static final long serialVersionUID = 1L;
+
+  @NotNull
+  private final File myClassesFile;
+
+  @Nullable
+  private final File mySourcesFile;
+
+  @Nullable
+  private final File myJavadocFile;
+
+  public ClasspathEntry(@NotNull File classesFile, @Nullable File sourcesFile, @Nullable File javadocFile) {
+    myClassesFile = classesFile;
+    mySourcesFile = sourcesFile;
+    myJavadocFile = javadocFile;
+  }
+
+  @NotNull
+  public File getClassesFile() {
+    return myClassesFile;
+  }
+
+  @Nullable
+  public File getSourcesFile() {
+    return mySourcesFile;
+  }
+
+  @Nullable
+  public File getJavadocFile() {
+    return myJavadocFile;
+  }
+
+  @Override
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ClasspathEntry)) return false;
+
+    ClasspathEntry entry = (ClasspathEntry)o;
+
+    if (!FileUtil.filesEqual(myClassesFile, entry.myClassesFile)) return false;
+    if (!FileUtil.filesEqual(myJavadocFile, entry.myJavadocFile)) return false;
+    if (!FileUtil.filesEqual(mySourcesFile, entry.mySourcesFile)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    int result = FileUtil.fileHashCode(myClassesFile);
+    result = 31 * result + FileUtil.fileHashCode(mySourcesFile);
+    result = 31 * result + FileUtil.fileHashCode(myJavadocFile);
+    return result;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java
new file mode 100644
index 0000000..b592411
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/BuildScriptClasspathModelImpl.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.internal;
+
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.internal.ImmutableDomainObjectSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class BuildScriptClasspathModelImpl implements BuildScriptClasspathModel {
+
+  private final List<ClasspathEntryModel> myClasspathEntries;
+
+  public BuildScriptClasspathModelImpl() {
+    myClasspathEntries = new ArrayList<ClasspathEntryModel>();
+  }
+
+  @Override
+  public DomainObjectSet<? extends ClasspathEntryModel> getClasspath() {
+    return ImmutableDomainObjectSet.of(myClasspathEntries);
+  }
+
+  public void add(@NotNull ClasspathEntryModel classpathEntryModel) {
+    myClasspathEntries.add(classpathEntryModel);
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java
new file mode 100644
index 0000000..0618810
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/ClasspathEntryModelImpl.java
@@ -0,0 +1,60 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.internal;
+
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+
+import java.io.File;
+import java.io.Serializable;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/20/13
+ */
+public class ClasspathEntryModelImpl implements ClasspathEntryModel, Serializable {
+  @NotNull
+  private final File classesFile;
+  @Nullable
+  private final File sourcesFile;
+  @Nullable
+  private final File javadocFile;
+
+  public ClasspathEntryModelImpl(@NotNull File classesFile, @Nullable File sourcesFile, @Nullable File javadocFile) {
+    this.classesFile = classesFile;
+    this.sourcesFile = sourcesFile;
+    this.javadocFile = javadocFile;
+  }
+
+  @NotNull
+  @Override
+  public File getClassesFile() {
+    return classesFile;
+  }
+
+  @Nullable
+  @Override
+  public File getSourcesFile() {
+    return sourcesFile;
+  }
+
+  @Nullable
+  @Override
+  public File getJavadocFile() {
+    return javadocFile;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle
new file mode 100644
index 0000000..91140f2
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+allprojects { project ->
+  if(project.name == 'buildSrc') {
+    apply plugin: 'groovy'
+    dependencies {
+      compile gradleApi()
+      compile localGroovy()
+    }
+  }
+}
\ No newline at end of file
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
index a788cb8..4f382fd 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/model/internal/init.gradle
@@ -34,6 +34,10 @@
   URLClassLoader classLoader = new URLClassLoader(urls, getClass().classLoader)
   Class modelClass = classLoader.loadClass('org.jetbrains.plugins.gradle.model.internal.ExtraModelBuilder')
   allprojects {
+    apply plugin: 'idea'
+    idea.module.ext.set('resourceDirs', [])
+    idea.module.ext.set('testResourceDirs', [])
+
     ext.jetExtraModelBuilderClass = modelClass
     apply plugin: JetGradlePlugin
   }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java
new file mode 100644
index 0000000..512bd70
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleBuildClasspathManager.java
@@ -0,0 +1,111 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.service;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.project.ExternalModuleBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.util.*;
+import java.util.concurrent.atomic.AtomicReference;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 12/27/13
+ */
+public class GradleBuildClasspathManager {
+  @NotNull
+  private final Project myProject;
+
+  @NotNull
+  private volatile List<VirtualFile> allFilesCache;
+
+  @NotNull
+  private final AtomicReference<Map<String/*module path*/, List<VirtualFile> /*module build classpath*/>> myClasspathMap
+    = new AtomicReference<Map<String, List<VirtualFile>>>(new HashMap<String, List<VirtualFile>>());
+
+  public GradleBuildClasspathManager(@NotNull Project project) {
+    myProject = project;
+    reload();
+  }
+
+  @NotNull
+  public static GradleBuildClasspathManager getInstance(@NotNull Project project) {
+    return ServiceManager.getService(project, GradleBuildClasspathManager.class);
+  }
+
+  public void reload() {
+    ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
+    assert manager != null;
+    AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(myProject);
+
+    Map<String/*module path*/, List<VirtualFile> /*module build classpath*/> map = ContainerUtil.newHashMap();
+
+    final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
+    final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
+    for (ExternalProjectBuildClasspathPojo projectBuildClasspathPojo : localSettings.getProjectBuildClasspath().values()) {
+      List<VirtualFile> projectBuildClasspath = ContainerUtil.newArrayList();
+      for (String path : projectBuildClasspathPojo.getProjectBuildClasspath()) {
+        final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
+        if (virtualFile != null) {
+          ContainerUtil.addIfNotNull(
+            projectBuildClasspath, virtualFile.isDirectory() ? virtualFile : jarFileSystem.getJarRootForLocalFile(virtualFile));
+        }
+      }
+
+      for (ExternalModuleBuildClasspathPojo moduleBuildClasspathPojo : projectBuildClasspathPojo.getModulesBuildClasspath().values()) {
+        List<VirtualFile> moduleBuildClasspath = ContainerUtil.newArrayList(projectBuildClasspath);
+        for (String path : moduleBuildClasspathPojo.getEntries()) {
+          final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByPath(path);
+          if (virtualFile != null) {
+            ContainerUtil.addIfNotNull(moduleBuildClasspath, jarFileSystem.getJarRootForLocalFile(virtualFile));
+          }
+        }
+
+        map.put(moduleBuildClasspathPojo.getPath(), moduleBuildClasspath);
+      }
+    }
+
+    myClasspathMap.set(map);
+
+    Set<VirtualFile> set = new LinkedHashSet<VirtualFile>();
+    for (List<VirtualFile> virtualFiles : myClasspathMap.get().values()) {
+      set.addAll(virtualFiles);
+    }
+    allFilesCache = ContainerUtil.newArrayList(set);
+  }
+
+  @NotNull
+  public List<VirtualFile> getAllClasspathEntries() {
+    return allFilesCache;
+  }
+
+  @NotNull
+  public List<VirtualFile> getModuleClasspathEntries(@NotNull String externalModulePath) {
+    List<VirtualFile> virtualFiles = myClasspathMap.get().get(externalModulePath);
+    return virtualFiles == null ? Collections.<VirtualFile>emptyList() : virtualFiles;
+  }
+}
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
index 715db5a..95fdb0a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/GradleInstallationManager.java
@@ -10,6 +10,7 @@
 import com.intellij.openapi.vfs.JarFileSystem;
 import com.intellij.openapi.vfs.LocalFileSystem;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.ContainerUtilRt;
 import org.gradle.StartParameter;
@@ -49,6 +50,9 @@
 
   public static final Pattern GRADLE_JAR_FILE_PATTERN;
   public static final Pattern ANY_GRADLE_JAR_FILE_PATTERN;
+  public static final Pattern ANT_JAR_PATTERN = Pattern.compile("ant(-(.*))?\\.jar");
+  public static final Pattern IVY_JAR_PATTERN = Pattern.compile("ivy(-(.*))?\\.jar");
+
   private static final String[] GRADLE_START_FILE_NAMES;
   @NonNls private static final String GRADLE_ENV_PROPERTY_NAME;
 
@@ -375,58 +379,84 @@
    */
   @Nullable
   public List<VirtualFile> getClassRoots(@Nullable Project project) {
+    List<File> files = getClassRoots(project, null);
+    if(files == null) return null;
+    final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
+    final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
+    return ContainerUtil.mapNotNull(files, new Function<File, VirtualFile>() {
+      @Override
+      public VirtualFile fun(File file) {
+        final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
+        return virtualFile != null ? jarFileSystem.getJarRootForLocalFile(virtualFile) : null;
+      }
+    });
+  }
+
+  @Nullable
+  public List<File> getClassRoots(@Nullable Project project, @Nullable String rootProjectPath) {
     if (project == null) return null;
 
-    for (Module module : myPlatformFacade.getModules(project)) {
-      String rootProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
-      if (StringUtil.isEmpty(rootProjectPath)) {
-        continue;
+    if(rootProjectPath == null) {
+      for (Module module : myPlatformFacade.getModules(project)) {
+        rootProjectPath = module.getOptionValue(ExternalSystemConstants.ROOT_PROJECT_PATH_KEY);
+        List<File> result = findGradleSdkClasspath(project, rootProjectPath);
+        if(!result.isEmpty()) return result;
       }
-      File gradleHome = getGradleHome(module.getProject(), rootProjectPath);
-
-      if (gradleHome == null || !gradleHome.isDirectory()) {
-        continue;
-      }
-
-      final Collection<File> libraries = getAllLibraries(gradleHome);
-      if (libraries == null) {
-        continue;
-      }
-      final LocalFileSystem localFileSystem = LocalFileSystem.getInstance();
-      final JarFileSystem jarFileSystem = JarFileSystem.getInstance();
-      List<VirtualFile> result = new ArrayList<VirtualFile>();
-      for (File file : libraries) {
-        if (ANY_GRADLE_JAR_FILE_PATTERN.matcher(file.getName()).matches() || GroovyConfigUtils.matchesGroovyAll(file.getName())) {
-          final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
-          if (virtualFile != null) {
-            ContainerUtil.addIfNotNull(result, jarFileSystem.getJarRootForLocalFile(virtualFile));
-          }
-        }
-      }
-
-      File src = new File(gradleHome, "src");
-      if (src.isDirectory()) {
-        if(new File(src, "org").isDirectory()) {
-          addRoots(localFileSystem, result, src);
-        } else {
-          addRoots(localFileSystem, result, src.listFiles());
-        }
-      }
-
-      return result;
+    } else {
+      return findGradleSdkClasspath(project, rootProjectPath);
     }
+
     return null;
   }
 
-  private void addRoots(@NotNull LocalFileSystem localFileSystem, @NotNull List<VirtualFile> result, @Nullable File... files) {
-    if(files == null) return;
-    for (File file : files) {
-      if(file == null || !file.isDirectory()) continue;
-      final VirtualFile virtualFile = localFileSystem.refreshAndFindFileByIoFile(file);
-      if (virtualFile != null) {
-        result.add(0, virtualFile);
+  private List<File> findGradleSdkClasspath(Project project, String rootProjectPath) {
+    List<File> result = new ArrayList<File>();
+
+    if (StringUtil.isEmpty(rootProjectPath)) return result;
+
+    File gradleHome = getGradleHome(project, rootProjectPath);
+
+    if (gradleHome == null || !gradleHome.isDirectory()) {
+      return result;
+    }
+
+    final Collection<File> libraries = getAllLibraries(gradleHome);
+    if (libraries == null) {
+      return result;
+    }
+
+    for (File file : libraries) {
+      if (isGradleBuildClasspathLibrary(file)) {
+        ContainerUtil.addIfNotNull(result, file);
       }
     }
+
+    File src = new File(gradleHome, "src");
+    if (src.isDirectory()) {
+      if(new File(src, "org").isDirectory()) {
+        addRoots(result, src);
+      } else {
+        addRoots(result, src.listFiles());
+      }
+    }
+
+    return result;
+  }
+
+  private boolean isGradleBuildClasspathLibrary(File file) {
+    String fileName = file.getName();
+    return ANY_GRADLE_JAR_FILE_PATTERN.matcher(fileName).matches()
+           || ANT_JAR_PATTERN.matcher(fileName).matches()
+           || IVY_JAR_PATTERN.matcher(fileName).matches()
+           || GroovyConfigUtils.matchesGroovyAll(fileName);
+  }
+
+  private void addRoots(@NotNull List<File> result, @Nullable File... files) {
+    if (files == null) return;
+    for (File file : files) {
+      if (file == null || !file.isDirectory()) continue;
+      result.add(0, file);
+    }
   }
 
   private File getWrappedGradleHome(String linkedProjectPath, @Nullable final WrapperConfiguration wrapperConfiguration) {
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
index 0a28fccd..b2eb6a0 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/BaseGradleProjectResolverExtension.java
@@ -35,8 +35,10 @@
 import com.intellij.openapi.roots.DependencyScope;
 import com.intellij.openapi.util.KeyValue;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.util.BooleanFunction;
+import com.intellij.util.Function;
 import com.intellij.util.PathUtil;
 import com.intellij.util.PathsList;
 import com.intellij.util.containers.ContainerUtil;
@@ -51,9 +53,9 @@
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
-import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot;
-import org.jetbrains.plugins.gradle.model.ModuleExtendedModel;
-import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
+import org.jetbrains.plugins.gradle.model.*;
+import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
+import org.jetbrains.plugins.gradle.model.data.ClasspathEntry;
 import org.jetbrains.plugins.gradle.util.GradleBundle;
 import org.jetbrains.plugins.gradle.util.GradleConstants;
 import org.jetbrains.plugins.gradle.util.GradleUtil;
@@ -132,14 +134,16 @@
         "Creating module data ('%s') with the external config path: '%s'", gradleModule.getGradleProject().getPath(), moduleConfigPath
       ));
     }
-    ModuleData moduleData = new ModuleData(gradleModule.getGradleProject().getPath(),
+
+    final String path = gradleModule.getGradleProject().getPath();
+    final ModuleData moduleData = new ModuleData(StringUtil.isEmpty(path) || ":".equals(path) ? moduleName : path,
                                            GradleConstants.SYSTEM_ID,
                                            StdModuleTypes.JAVA.getId(),
                                            moduleName,
                                            moduleConfigPath,
                                            moduleConfigPath);
 
-    ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
+    final ModuleExtendedModel moduleExtendedModel = resolverCtx.getExtraProject(gradleModule, ModuleExtendedModel.class);
     if (moduleExtendedModel != null) {
       moduleData.setGroup(moduleExtendedModel.getGroup());
       moduleData.setVersion(moduleExtendedModel.getVersion());
@@ -150,6 +154,19 @@
 
   @Override
   public void populateModuleExtraModels(@NotNull IdeaModule gradleModule, @NotNull DataNode<ModuleData> ideModule) {
+    BuildScriptClasspathModel buildScriptClasspathModel = resolverCtx.getExtraProject(gradleModule, BuildScriptClasspathModel.class);
+    if (buildScriptClasspathModel != null) {
+      List<ClasspathEntry> classpathEntries =
+        ContainerUtil.map(buildScriptClasspathModel.getClasspath(), new Function<ClasspathEntryModel, ClasspathEntry>() {
+          @Override
+          public ClasspathEntry fun(ClasspathEntryModel model) {
+            return new ClasspathEntry(model.getClassesFile(), model.getSourcesFile(), model.getJavadocFile());
+          }
+        });
+      BuildScriptClasspathData buildScriptClasspathData =
+        new BuildScriptClasspathData(GradleConstants.SYSTEM_ID, classpathEntries);
+      ideModule.createChild(BuildScriptClasspathData.KEY, buildScriptClasspathData);
+    }
   }
 
   @Override
@@ -289,7 +306,7 @@
   @NotNull
   @Override
   public Set<Class> getExtraProjectModelClasses() {
-    return ContainerUtil.<Class>set(ModuleExtendedModel.class, ProjectDependenciesModel.class);
+    return ContainerUtil.<Class>set(ModuleExtendedModel.class, ProjectDependenciesModel.class, BuildScriptClasspathModel.class);
   }
 
   @NotNull
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
index e4ae7b3..39dfe9a 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleExecutionHelper.java
@@ -355,22 +355,46 @@
   }
 
   @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
-  public static void setInitScript(LongRunningOperation longRunningOperation) {
+  public static boolean setInitScript(@NotNull LongRunningOperation longRunningOperation, boolean isBuildSrcProject) {
     try {
       InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/init.gradle");
-      if (stream == null) return;
+      if (stream == null) return isBuildSrcProject;
 
       String jarPath = PathUtil.getCanonicalPath(PathUtil.getJarPathForClass(GradleProjectResolver.class));
       String s = FileUtil.loadTextAndClose(stream).replace("${JAR_PATH}", jarPath);
 
+      if(isBuildSrcProject) {
+        String buildSrcDefaultInitScript = getBuildSrcDefaultInitScript();
+        if(buildSrcDefaultInitScript == null) return false;
+        s += buildSrcDefaultInitScript;
+      }
+
       final File tempFile = FileUtil.createTempFile("ijinit", '.' + GradleConstants.EXTENSION, true);
       FileUtil.writeToFile(tempFile, s);
 
       String[] buildExecutorArgs = new String[]{"--init-script", tempFile.getAbsolutePath()};
       longRunningOperation.withArguments(buildExecutorArgs);
+
+      return true;
     }
     catch (Exception e) {
       LOG.warn("Can't use IJ gradle init script", e);
+      return false;
+    }
+  }
+
+  @Nullable
+  @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
+  public static String getBuildSrcDefaultInitScript() {
+    try {
+      InputStream stream = GradleProjectResolver.class.getResourceAsStream("/org/jetbrains/plugins/gradle/model/internal/buildSrcInit.gradle");
+      if (stream == null) return null;
+
+      return FileUtil.loadTextAndClose(stream);
+    }
+    catch (Exception e) {
+      LOG.warn("Can't use IJ gradle init script", e);
+      return null;
     }
   }
 
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
index 1b1997b..29a27ba 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleProjectResolver.java
@@ -32,6 +32,7 @@
 import com.intellij.openapi.externalSystem.util.ExternalSystemDebugEnvironment;
 import com.intellij.openapi.util.KeyValue;
 import com.intellij.openapi.util.Pair;
+import com.intellij.util.BooleanFunction;
 import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.ContainerUtilRt;
@@ -52,6 +53,7 @@
 import org.jetbrains.plugins.gradle.util.GradleConstants;
 import org.jetbrains.plugins.gradle.util.GradleEnvironment;
 
+import java.io.File;
 import java.util.*;
 
 /**
@@ -110,19 +112,19 @@
       projectResolverChain = new BaseGradleProjectResolverExtension();
     }
 
-    return myHelper.execute(projectPath, settings, new Function<ProjectConnection, DataNode<ProjectData>>() {
-      @Override
-      public DataNode<ProjectData> fun(ProjectConnection connection) {
-        try {
-          return doResolveProjectInfo(
-            new ProjectResolverContext(id, projectPath, settings, connection, listener, isPreviewMode), projectResolverChain);
-        }
-        catch (RuntimeException e) {
-          LOG.info("Gradle project resolve error", e);
-          throw projectResolverChain.getUserFriendlyError(e, projectPath, null);
-        }
-      }
-    });
+    final DataNode<ProjectData> resultProjectDataNode = myHelper.execute(
+      projectPath, settings,
+      new ProjectConnectionDataNodeFunction(
+        id, projectPath, settings, listener, isPreviewMode, projectResolverChain, false)
+    );
+
+    // auto-discover buildSrc project if needed
+    final String buildSrcProjectPath = projectPath + "/buildSrc";
+    handleBuildSrcProject(
+      resultProjectDataNode,
+      new ProjectConnectionDataNodeFunction(id, buildSrcProjectPath, settings, listener, isPreviewMode, projectResolverChain, true)
+    );
+    return resultProjectDataNode;
   }
 
   @Override
@@ -133,7 +135,8 @@
 
   @NotNull
   private DataNode<ProjectData> doResolveProjectInfo(@NotNull final ProjectResolverContext resolverCtx,
-                                                     @NotNull final GradleProjectResolverExtension projectResolverChain)
+                                                     @NotNull final GradleProjectResolverExtension projectResolverChain,
+                                                     boolean isBuildSrcProject)
     throws IllegalArgumentException, IllegalStateException {
 
     final ProjectImportAction projectImportAction = new ProjectImportAction(resolverCtx.isPreviewMode());
@@ -162,7 +165,7 @@
 
     // TODO [vlad] remove the check
     if (!GradleEnvironment.DISABLE_ENHANCED_TOOLING_API) {
-      GradleExecutionHelper.setInitScript(buildActionExecutor);
+      GradleExecutionHelper.setInitScript(buildActionExecutor, isBuildSrcProject);
     }
 
     ProjectImportAction.AllModels allModels;
@@ -242,8 +245,10 @@
       projectResolverChain.populateModuleContentRoots(ideaModule, moduleDataNode);
       projectResolverChain.populateModuleCompileOutputSettings(ideaModule, moduleDataNode);
       projectResolverChain.populateModuleDependencies(ideaModule, moduleDataNode, projectDataNode);
-      final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
-      allTasks.addAll(moduleTasks);
+      if(!isBuildSrcProject) {
+        final Collection<TaskData> moduleTasks = projectResolverChain.populateModuleTasks(ideaModule, moduleDataNode, projectDataNode);
+        allTasks.addAll(moduleTasks);
+      }
     }
 
     // populate root project tasks
@@ -275,4 +280,78 @@
       return null;
     }
   }
+
+  private void handleBuildSrcProject(@NotNull final DataNode<ProjectData> resultProjectDataNode,
+                                     @NotNull final ProjectConnectionDataNodeFunction projectConnectionDataNodeFunction) {
+
+    if (projectConnectionDataNodeFunction.myIsPreviewMode || GradleEnvironment.DISABLE_ENHANCED_TOOLING_API ||
+        !new File(projectConnectionDataNodeFunction.myProjectPath).isDirectory()) return;
+
+    final DataNode<ModuleData> buildSrcModuleDataNode =
+      ExternalSystemApiUtil.find(resultProjectDataNode, ProjectKeys.MODULE, new BooleanFunction<DataNode<ModuleData>>() {
+        @Override
+        public boolean fun(DataNode<ModuleData> node) {
+          return projectConnectionDataNodeFunction.myProjectPath.equals(node.getData().getLinkedExternalProjectPath());
+        }
+      });
+
+    // check if buildSrc project was already exposed in settings.gradle file
+    if (buildSrcModuleDataNode != null) return;
+
+    final DataNode<ProjectData> buildSrcProjectDataDataNode = myHelper.execute(
+      projectConnectionDataNodeFunction.myProjectPath, projectConnectionDataNodeFunction.mySettings, projectConnectionDataNodeFunction);
+
+    if (buildSrcProjectDataDataNode != null) {
+      final DataNode<ModuleData> moduleDataNode = ExternalSystemApiUtil.find(buildSrcProjectDataDataNode, ProjectKeys.MODULE);
+      if (moduleDataNode != null) {
+        for (DataNode<LibraryData> libraryDataNode : ExternalSystemApiUtil.findAll(buildSrcProjectDataDataNode, ProjectKeys.LIBRARY)) {
+          resultProjectDataNode.createChild(libraryDataNode.getKey(), libraryDataNode.getData());
+        }
+
+        final DataNode<ModuleData> newModuleDataNode = resultProjectDataNode.createChild(ProjectKeys.MODULE, moduleDataNode.getData());
+        for (DataNode node : moduleDataNode.getChildren()) {
+          newModuleDataNode.createChild(node.getKey(), node.getData());
+        }
+      }
+    }
+  }
+
+  private class ProjectConnectionDataNodeFunction implements Function<ProjectConnection, DataNode<ProjectData>> {
+    @NotNull private final ExternalSystemTaskId myId;
+    @NotNull private final String myProjectPath;
+    @Nullable private final GradleExecutionSettings mySettings;
+    @NotNull private final ExternalSystemTaskNotificationListener myListener;
+    private final boolean myIsPreviewMode;
+    @NotNull private final GradleProjectResolverExtension myProjectResolverChain;
+    private final boolean myIsBuildSrcProject;
+
+    public ProjectConnectionDataNodeFunction(@NotNull ExternalSystemTaskId id,
+                                             @NotNull String projectPath,
+                                             @Nullable GradleExecutionSettings settings,
+                                             @NotNull ExternalSystemTaskNotificationListener listener,
+                                             boolean isPreviewMode,
+                                             @NotNull GradleProjectResolverExtension projectResolverChain,
+                                             boolean isBuildSrcProject) {
+      myId = id;
+      myProjectPath = projectPath;
+      mySettings = settings;
+      myListener = listener;
+      myIsPreviewMode = isPreviewMode;
+      myProjectResolverChain = projectResolverChain;
+      myIsBuildSrcProject = isBuildSrcProject;
+    }
+
+    @Override
+    public DataNode<ProjectData> fun(ProjectConnection connection) {
+      try {
+        return doResolveProjectInfo(
+          new ProjectResolverContext(myId, myProjectPath, mySettings, connection, myListener, myIsPreviewMode),
+          myProjectResolverChain, myIsBuildSrcProject);
+      }
+      catch (RuntimeException e) {
+        LOG.info("Gradle project resolve error", e);
+        throw myProjectResolverChain.getUserFriendlyError(e, myProjectPath, null);
+      }
+    }
+  }
 }
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
index 623a797..fc4805e 100644
--- a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/GradleStartupActivity.java
@@ -30,6 +30,7 @@
 import com.intellij.openapi.vfs.VfsUtilCore;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
 import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportBuilder;
 import org.jetbrains.plugins.gradle.service.project.wizard.GradleProjectImportProvider;
 import org.jetbrains.plugins.gradle.settings.GradleSettings;
@@ -52,9 +53,14 @@
 
   @Override
   public void runActivity(@NotNull Project project) {
+    configureBuildClasspath(project);
     showNotificationForUnlinkedGradleProject(project);
   }
 
+  private static void configureBuildClasspath(@NotNull final Project project) {
+    GradleBuildClasspathManager.getInstance(project).reload();
+  }
+
   private static void showNotificationForUnlinkedGradleProject(@NotNull final Project project) {
     if (!PropertiesComponent.getInstance(project).getBoolean(SHOW_UNLINKED_GRADLE_POPUP, true)
         || !GradleSettings.getInstance(project).getLinkedProjectsSettings().isEmpty()
diff --git a/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java
new file mode 100644
index 0000000..907f290
--- /dev/null
+++ b/plugins/gradle/src/org/jetbrains/plugins/gradle/service/project/data/BuildClasspathModuleGradleDataService.java
@@ -0,0 +1,161 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.service.project.data;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.externalSystem.ExternalSystemManager;
+import com.intellij.openapi.externalSystem.model.DataNode;
+import com.intellij.openapi.externalSystem.model.Key;
+import com.intellij.openapi.externalSystem.model.ProjectKeys;
+import com.intellij.openapi.externalSystem.model.project.ExternalModuleBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ExternalProjectBuildClasspathPojo;
+import com.intellij.openapi.externalSystem.model.project.ModuleData;
+import com.intellij.openapi.externalSystem.model.project.ProjectData;
+import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
+import com.intellij.openapi.externalSystem.settings.AbstractExternalSystemLocalSettings;
+import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
+import com.intellij.openapi.externalSystem.util.ExternalSystemConstants;
+import com.intellij.openapi.externalSystem.util.Order;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.FactoryMap;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.plugins.gradle.model.data.BuildScriptClasspathData;
+import org.jetbrains.plugins.gradle.model.data.ClasspathEntry;
+import org.jetbrains.plugins.gradle.service.GradleBuildClasspathManager;
+import org.jetbrains.plugins.gradle.service.GradleInstallationManager;
+import org.jetbrains.plugins.gradle.settings.GradleProjectSettings;
+import org.jetbrains.plugins.gradle.settings.GradleSettings;
+import org.jetbrains.plugins.gradle.util.GradleConstants;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 8/27/13
+ */
+@Order(ExternalSystemConstants.UNORDERED)
+public class BuildClasspathModuleGradleDataService implements ProjectDataService<BuildScriptClasspathData, Module> {
+
+  @NotNull
+  @Override
+  public Key<BuildScriptClasspathData> getTargetDataKey() {
+    return BuildScriptClasspathData.KEY;
+  }
+
+  @Override
+  public void importData(@NotNull final Collection<DataNode<BuildScriptClasspathData>> toImport,
+                         @NotNull final Project project,
+                         boolean synchronous) {
+    if (toImport.isEmpty()) {
+      return;
+    }
+    if (!project.isInitialized()) {
+      return;
+    }
+
+    final GradleInstallationManager gradleInstallationManager = ServiceManager.getService(GradleInstallationManager.class);
+
+    ExternalSystemManager<?, ?, ?, ?, ?> manager = ExternalSystemApiUtil.getManager(GradleConstants.SYSTEM_ID);
+    assert manager != null;
+    AbstractExternalSystemLocalSettings localSettings = manager.getLocalSettingsProvider().fun(project);
+
+    //noinspection MismatchedQueryAndUpdateOfCollection
+    Map<String/* externalProjectPath */, Set<String>> externalProjectGradleSdkLibs = new FactoryMap<String, Set<String>>() {
+      @Nullable
+      @Override
+      protected Set<String> create(String externalProjectPath) {
+        GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(externalProjectPath);
+        if (settings == null || settings.getDistributionType() == null) return null;
+
+        final Set<String> gradleSdkLibraries = ContainerUtil.newHashSet();
+        File gradleHome =
+          gradleInstallationManager.getGradleHome(settings.getDistributionType(), externalProjectPath, settings.getGradleHome());
+        if (gradleHome != null && gradleHome.isDirectory()) {
+
+          final Collection<File> libraries = gradleInstallationManager.getClassRoots(project, externalProjectPath);
+          if (libraries != null) {
+            for (File library : libraries) {
+              gradleSdkLibraries.add(FileUtil.toCanonicalPath(library.getPath()));
+            }
+          }
+        }
+        return gradleSdkLibraries;
+      }
+    };
+
+    for (final DataNode<BuildScriptClasspathData> node : toImport) {
+      if (GradleConstants.SYSTEM_ID.equals(node.getData().getOwner())) {
+
+
+        DataNode<ProjectData> projectDataNode = ExternalSystemApiUtil.findParent(node, ProjectKeys.PROJECT);
+        assert projectDataNode != null;
+
+        String linkedExternalProjectPath = projectDataNode.getData().getLinkedExternalProjectPath();
+        DataNode<ModuleData> moduleDataNode = ExternalSystemApiUtil.findParent(node, ProjectKeys.MODULE);
+        if (moduleDataNode == null) continue;
+
+        String externalModulePath = moduleDataNode.getData().getLinkedExternalProjectPath();
+        GradleProjectSettings settings = GradleSettings.getInstance(project).getLinkedProjectSettings(linkedExternalProjectPath);
+        if (settings == null || settings.getDistributionType() == null) continue;
+
+        final Set<String> buildClasspath = ContainerUtil.newHashSet();
+        BuildScriptClasspathData buildScriptClasspathData = node.getData();
+        for (ClasspathEntry classpathEntry : buildScriptClasspathData.getClasspathEntries()) {
+          if (classpathEntry.getSourcesFile() != null) {
+            buildClasspath.add(FileUtil.toCanonicalPath(classpathEntry.getSourcesFile().getPath()));
+          }
+          else {
+            buildClasspath.add(FileUtil.toCanonicalPath(classpathEntry.getClassesFile().getPath()));
+          }
+        }
+
+        ExternalProjectBuildClasspathPojo projectBuildClasspathPojo =
+          localSettings.getProjectBuildClasspath().get(linkedExternalProjectPath);
+        if (projectBuildClasspathPojo == null) {
+          projectBuildClasspathPojo = new ExternalProjectBuildClasspathPojo(
+            moduleDataNode.getData().getExternalName(),
+            ContainerUtil.<String>newArrayList(),
+            ContainerUtil.<String, ExternalModuleBuildClasspathPojo>newHashMap());
+          localSettings.getProjectBuildClasspath().put(linkedExternalProjectPath, projectBuildClasspathPojo);
+        }
+
+        List<String> projectBuildClasspath = ContainerUtil.newArrayList(externalProjectGradleSdkLibs.get(linkedExternalProjectPath));
+        // add main java root of buildSrc project
+        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/java");
+        // add main groovy root of buildSrc project
+        projectBuildClasspath.add(linkedExternalProjectPath + "/buildSrc/src/main/groovy");
+
+        projectBuildClasspathPojo.setProjectBuildClasspath(projectBuildClasspath);
+        projectBuildClasspathPojo.getModulesBuildClasspath().put(
+          externalModulePath, new ExternalModuleBuildClasspathPojo(externalModulePath, ContainerUtil.newArrayList(buildClasspath)));
+      }
+    }
+
+    GradleBuildClasspathManager.getInstance(project).reload();
+  }
+
+  @Override
+  public void removeData(@NotNull Collection<? extends Module> toRemove, @NotNull Project project, boolean synchronous) {
+  }
+}
diff --git a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
index f90814d..e69de29 100644
--- a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
+++ b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile.gradle
@@ -1 +0,0 @@
-//empty file
\ No newline at end of file
diff --git a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
index aa2892d..54c0974 100644
--- a/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
+++ b/plugins/gradle/testData/testAddMavenDependencyInEmptyFile_after.gradle
@@ -1,4 +1,3 @@
-//empty file
 dependencies{
 compile 'testGroupId:testArtifactId:1.0'
 }
\ No newline at end of file
diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
index 849b1b4..a6c9dde 100644
--- a/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
+++ b/plugins/gradle/testData/testDefaultDependenciesModel/build.gradle
@@ -4,8 +4,8 @@
   apply plugin: 'java'
 }
 
-project(":group2:subgroup11:project") {
+project("dependentProject") {
   dependencies {
-    compile project(":project")
+    compile project(":dependencyProject")
   }
 }
\ No newline at end of file
diff --git a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
index cf870fe..ef853f0 100644
--- a/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
+++ b/plugins/gradle/testData/testDefaultDependenciesModel/settings.gradle
@@ -1,5 +1,4 @@
 //noinspection GrPackage
 
-include 'group1:subgroup11:project'
-include 'group2:subgroup11:project'
-include 'project'
\ No newline at end of file
+include 'dependencyProject'
+include 'dependentProject'
\ No newline at end of file
diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
index 6f9afa4..73cb6a1 100644
--- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
+++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/build.gradle
@@ -27,7 +27,7 @@
 
 project(":service") {
   dependencies {
-    compile  (project(':api'))
+    compile(project(':api'))
   }
 }
 
@@ -35,4 +35,21 @@
   dependencies {
     provided(project(':lib'))
   }
-}
\ No newline at end of file
+}
+
+project(":withIdeaModelCustomisations") {
+  dependencies {
+    //compile 'org.slf4j:slf4j-api:1.7.5'
+    //testCompile 'junit:junit:4.11'
+
+    compile files("lib/someDep.jar")
+    testCompile files("lib/someTestDep.jar")
+  }
+
+  idea {
+    module {
+      scopes.COMPILE.plus += scopes.TEST.plus
+      scopes.TEST.plus = []
+    }
+  }
+}
diff --git a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
index 271f734..26ee835 100644
--- a/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
+++ b/plugins/gradle/testData/testGradleIdeaPluginPlusScopesDependenciesModel/settings.gradle
@@ -1,4 +1,5 @@
 //noinspection GrPackage
 include "lib"
 include "api"
-include "service"
\ No newline at end of file
+include "service"
+include "withIdeaModelCustomisations"
\ No newline at end of file
diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle
new file mode 100644
index 0000000..8c75849
--- /dev/null
+++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/build.gradle
@@ -0,0 +1,74 @@
+//noinspection GrPackage
+
+project("defaultJavaModule") {
+  apply plugin: "java"
+}
+
+project("moduleWithSourceSetDirBothAsResourceAndJava") {
+  apply plugin: "java"
+
+  sourceSets.main.resources.srcDir 'src/main/java'
+  sourceSets.test.resources.srcDir 'src/test/java'
+}
+
+project("moduleWithCustomSourceSet") {
+  apply plugin: "java"
+
+  sourceSets {
+    custom
+  }
+
+  sourceSets.custom.java.srcDir 'src/custom/java'
+}
+
+project("withIntegrationTests") {
+  apply plugin: 'java'
+
+  sourceSets {
+    integrationTest {
+      java.srcDir file('src/integration-test/java')
+      resources.srcDir file('src/integration-test/resources')
+    }
+  }
+
+  dependencies {
+    integrationTestCompile sourceSets.main.output
+    integrationTestCompile configurations.testCompile
+    integrationTestCompile sourceSets.test.output
+    integrationTestRuntime configurations.testRuntime
+  }
+
+  //noinspection GrUnresolvedAccess
+  task integrationTest(type: Test, dependsOn: jar) {
+    testClassesDir = sourceSets.integrationTest.output.classesDir
+    classpath = sourceSets.integrationTest.runtimeClasspath
+  }
+
+  check.dependsOn integrationTest
+}
+
+project("withIdeaPluginCustomization1") {
+  apply plugin: 'java'
+
+  idea {
+    module {
+      testSourceDirs += file('src/intTest/java')
+      testSourceDirs += file('src/intTest/resources')
+      excludeDirs += file('some-extra-exclude-folder')
+    }
+  }
+}
+
+// see http://youtrack.jetbrains.com/issue/IDEA-119365
+project("withIdeaPluginCustomization2") {
+  apply plugin: 'java'
+
+  idea {
+    module {
+      sourceDirs += testSourceDirs
+      testSourceDirs = []
+      ext.resourceDirs += file('some-extra-resource-folder')
+      ext.testResourceDirs += file('some-extra-test-resource-folder')
+    }
+  }
+}
diff --git a/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle
new file mode 100644
index 0000000..4f7ab78
--- /dev/null
+++ b/plugins/gradle/testData/testGradleSourcesSetsInterpretation/settings.gradle
@@ -0,0 +1,8 @@
+//noinspection GrPackage
+
+include 'defaultJavaModule'
+include 'moduleWithSourceSetDirBothAsResourceAndJava'
+include 'moduleWithCustomSourceSet'
+include 'withIntegrationTests'
+include 'withIdeaPluginCustomization1'
+include 'withIdeaPluginCustomization2'
\ No newline at end of file
diff --git a/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle
new file mode 100644
index 0000000..5b09fca
--- /dev/null
+++ b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/build.gradle
@@ -0,0 +1,9 @@
+//noinspection GrPackage
+
+project("moduleWithAdditionalClasspath") {
+  buildscript {
+    dependencies {
+      classpath files("lib/someDep.jar")
+    }
+  }
+}
diff --git a/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle
new file mode 100644
index 0000000..0297887
--- /dev/null
+++ b/plugins/gradle/testData/testModelBuildScriptClasspathBuilder/settings.gradle
@@ -0,0 +1,4 @@
+//noinspection GrPackage
+
+include 'moduleWithoutAdditionalClasspath'
+include 'moduleWithAdditionalClasspath'
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
index 835d730..0cdd2f0 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/AbstractModelBuilderTest.java
@@ -73,7 +73,7 @@
     final ProjectImportAction projectImportAction = new ProjectImportAction(true);
     projectImportAction.addExtraProjectModelClasses(getModels());
     BuildActionExecuter<ProjectImportAction.AllModels> buildActionExecutor = connection.action(projectImportAction);
-    GradleExecutionHelper.setInitScript(buildActionExecutor);
+    GradleExecutionHelper.setInitScript(buildActionExecutor, false);
 
     allModels = buildActionExecutor.run();
     assertNotNull(allModels);
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java
new file mode 100644
index 0000000..d812d8d
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelBuildScriptClasspathBuilderImplTest.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel;
+import org.jetbrains.plugins.gradle.model.ClasspathEntryModel;
+import org.junit.Test;
+
+import java.util.List;
+import java.util.Set;
+
+import static junit.framework.Assert.*;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/16/14
+ */
+public class ModelBuildScriptClasspathBuilderImplTest extends AbstractModelBuilderTest {
+
+  @Test
+  public void testModelBuildScriptClasspathBuilder() throws Exception {
+    ModelBuildScriptClasspathBuilderImpl buildScriptClasspathBuilder = new ModelBuildScriptClasspathBuilderImpl();
+    assertTrue(buildScriptClasspathBuilder.canBuild("org.jetbrains.plugins.gradle.model.BuildScriptClasspathModel"));
+
+    DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
+
+    List<BuildScriptClasspathModel> ideaModule =
+      ContainerUtil.mapNotNull(ideaModules, new Function<IdeaModule, BuildScriptClasspathModel>() {
+        @Override
+        public BuildScriptClasspathModel fun(IdeaModule module) {
+          BuildScriptClasspathModel classpathModel = allModels.getExtraProject(module, BuildScriptClasspathModel.class);
+
+          if (module.getName().equals("moduleWithAdditionalClasspath")) {
+            assertNotNull(classpathModel);
+            assertEquals(1, classpathModel.getClasspath().size());
+
+            ClasspathEntryModel classpathEntry = classpathModel.getClasspath().getAt(0);
+            assertEquals("someDep.jar", classpathEntry.getClassesFile().getName());
+          }
+          else if (module.getName().equals("moduleWithoutAdditionalClasspath") ||
+                   module.getName().equals("testModelBuildScriptClasspathBuilder")) {
+            assertNotNull(classpathModel);
+            assertTrue(classpathModel.getClasspath().isEmpty());
+          }
+          else {
+            fail();
+          }
+
+          return classpathModel;
+        }
+      });
+
+    assertEquals(3, ideaModule.size());
+  }
+
+  @Override
+  protected Set<Class> getModels() {
+    return ContainerUtil.<Class>set(BuildScriptClasspathModel.class);
+  }
+}
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
index 6bb9b6f..8cf50ef 100644
--- a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModelDependenciesBuilderImplTest.java
@@ -15,19 +15,26 @@
  */
 package org.jetbrains.plugins.gradle.model.builder;
 
-import com.intellij.openapi.util.Condition;
+import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import org.gradle.tooling.model.DomainObjectSet;
 import org.gradle.tooling.model.idea.IdeaDependency;
 import org.gradle.tooling.model.idea.IdeaModule;
 import org.gradle.tooling.model.idea.IdeaModuleDependency;
+import org.gradle.tooling.model.idea.IdeaSingleEntryLibraryDependency;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.plugins.gradle.model.GradleDependencyScope;
 import org.jetbrains.plugins.gradle.model.ProjectDependenciesModel;
+import org.junit.Assert;
 import org.junit.Test;
 
+import java.util.List;
 import java.util.Set;
 
-import static org.junit.Assert.*;
+import static junit.framework.Assert.assertTrue;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertNotNull;
 
 /**
  * @author Vladislav.Soroka
@@ -42,17 +49,29 @@
 
     DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
 
-    IdeaModule ideaModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
-      @Override
-      public boolean value(IdeaModule module) {
-        return module.getName().equals("group2-subgroup11-project");
+    final int modulesSize = 3;
+    assertEquals(modulesSize, ideaModules.size());
+
+    for (IdeaModule ideaModule : ideaModules) {
+      if (ideaModule.getName().equals("dependencyProject") ||
+          ideaModule.getName().equals("testDefaultDependenciesModel")) {
+        DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+        assertTrue((dependencies.isEmpty()));
       }
-    });
+      else if (ideaModule.getName().equals("dependentProject")) {
+        DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+        assertEquals(1, dependencies.size());
+        assertTrue(dependencies.getAt(0) instanceof IdeaModuleDependency);
+        IdeaModuleDependency moduleDependency = (IdeaModuleDependency)dependencies.getAt(0);
 
-    assertNotNull(ideaModule);
-
-    DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
-    assertEquals(1, dependencies.size());
+        assertEquals("dependencyProject", moduleDependency.getDependencyModule().getName());
+        assertEquals("COMPILE", moduleDependency.getScope().getScope());
+        assertTrue(moduleDependency.getExported());
+      }
+      else {
+        fail();
+      }
+    }
   }
 
   @Test
@@ -62,44 +81,71 @@
 
     DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
 
-    // test api module dependencies
-    IdeaModule apiModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
-      @Override
-      public boolean value(IdeaModule module) {
-        return module.getName().equals("api");
+    final int modulesSize = 5;
+    assertEquals(modulesSize, ideaModules.size());
+
+    for (IdeaModule ideaModule : ideaModules) {
+      DomainObjectSet<? extends IdeaDependency> dependencies = ideaModule.getDependencies();
+      if (ideaModule.getName().equals("lib") ||
+          ideaModule.getName().equals("testGradleIdeaPluginPlusScopesDependenciesModel")) {
+        assertTrue((dependencies.isEmpty()));
       }
-    });
-    assertNotNull(apiModule);
+      else if (ideaModule.getName().equals("api")) {
+        assertEquals(1, dependencies.size());
+        IdeaDependency libDependency = dependencies.getAt(0);
+        assertEquals(GradleDependencyScope.PROVIDED.getIdeaMappingName(), libDependency.getScope().getScope().toLowerCase());
+        assertTrue(libDependency instanceof IdeaModuleDependency);
 
-    DomainObjectSet<? extends IdeaDependency> dependencies = apiModule.getDependencies();
-    assertEquals(1, dependencies.size());
-    IdeaDependency libDependency = dependencies.getAt(0);
-    assertEquals(GradleDependencyScope.PROVIDED.name(), libDependency.getScope().getScope());
-    assertTrue(libDependency instanceof IdeaModuleDependency);
-
-    IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency;
-    assertNotNull(libModuleDependency.getDependencyModule());
-    assertEquals("lib", libModuleDependency.getDependencyModule().getName());
-
-
-    // test service module dependencies
-    IdeaModule serviceModule = ContainerUtil.find(ideaModules, new Condition<IdeaModule>() {
-      @Override
-      public boolean value(IdeaModule module) {
-        return module.getName().equals("service");
+        IdeaModuleDependency libModuleDependency = (IdeaModuleDependency)libDependency;
+        assertNotNull(libModuleDependency.getDependencyModule());
+        assertEquals("lib", libModuleDependency.getDependencyModule().getName());
       }
-    });
-    assertNotNull(serviceModule);
+      else if (ideaModule.getName().equals("service")) {
+        assertEquals(1, dependencies.size());
+        IdeaDependency apiDependency = dependencies.getAt(0);
+        assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), apiDependency.getScope().getScope().toLowerCase());
+        assertTrue(apiDependency instanceof IdeaModuleDependency);
 
-    DomainObjectSet<? extends IdeaDependency> serviceModuleDependencies = serviceModule.getDependencies();
-    assertEquals(1, serviceModuleDependencies.size());
-    IdeaDependency apiDependency = serviceModuleDependencies.getAt(0);
-    assertEquals(GradleDependencyScope.COMPILE.name(), apiDependency.getScope().getScope());
-    assertTrue(apiDependency instanceof IdeaModuleDependency);
+        IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency;
+        assertNotNull(apiModuleDependency.getDependencyModule());
+        assertEquals("api", apiModuleDependency.getDependencyModule().getName());
+      }
+      else if (ideaModule.getName().equals("withIdeaModelCustomisations")) {
 
-    IdeaModuleDependency apiModuleDependency = (IdeaModuleDependency)apiDependency;
-    assertNotNull(apiModuleDependency.getDependencyModule());
-    assertEquals("api", apiModuleDependency.getDependencyModule().getName());
+        assertTrue(findLocalLibraries(dependencies, GradleDependencyScope.TEST_COMPILE.getIdeaMappingName()).isEmpty());
+
+        List<IdeaSingleEntryLibraryDependency> libraryDependencies =
+          findLocalLibraries(dependencies, GradleDependencyScope.COMPILE.getIdeaMappingName());
+        assertEquals(2, libraryDependencies.size());
+
+        IdeaSingleEntryLibraryDependency someDep = libraryDependencies.get(0);
+        assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someDep.getScope().getScope().toLowerCase());
+        assertEquals("someDep.jar", someDep.getFile().getName());
+
+        IdeaSingleEntryLibraryDependency someTestDep = libraryDependencies.get(1);
+        assertEquals(GradleDependencyScope.COMPILE.getIdeaMappingName(), someTestDep.getScope().getScope().toLowerCase());
+        assertEquals("someTestDep.jar", someTestDep.getFile().getName());
+      }
+      else {
+        fail();
+      }
+    }
+  }
+
+  @NotNull
+  private static List<IdeaSingleEntryLibraryDependency> findLocalLibraries(
+    @NotNull final DomainObjectSet<? extends IdeaDependency> dependencies, @NotNull final String scope) {
+    return ContainerUtil.mapNotNull(
+      dependencies,
+      new Function<IdeaDependency, IdeaSingleEntryLibraryDependency>() {
+        @Override
+        public IdeaSingleEntryLibraryDependency fun(IdeaDependency dependency) {
+          return dependency instanceof IdeaSingleEntryLibraryDependency && scope.equals(dependency.getScope().getScope().toLowerCase())
+                 ? (IdeaSingleEntryLibraryDependency)dependency
+                 : null;
+        }
+      }
+    );
   }
 
   @Override
diff --git a/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java
new file mode 100644
index 0000000..9694c9d
--- /dev/null
+++ b/plugins/gradle/testSources/org/jetbrains/plugins/gradle/model/builder/ModuleExtendedModelBuilderImplTest.java
@@ -0,0 +1,177 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.jetbrains.plugins.gradle.model.builder;
+
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.gradle.tooling.model.DomainObjectSet;
+import org.gradle.tooling.model.idea.IdeaModule;
+import org.gradle.tooling.model.idea.IdeaSourceDirectory;
+import org.jetbrains.plugins.gradle.model.ExtIdeaContentRoot;
+import org.jetbrains.plugins.gradle.model.ModuleExtendedModel;
+import org.junit.Assert;
+import org.junit.Test;
+
+import java.io.File;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+import java.util.Set;
+
+import static junit.framework.Assert.assertNotNull;
+import static junit.framework.Assert.fail;
+import static org.junit.Assert.assertEquals;
+import static org.junit.Assert.assertTrue;
+
+/**
+ * @author Vladislav.Soroka
+ * @since 1/16/14
+ */
+public class ModuleExtendedModelBuilderImplTest extends AbstractModelBuilderTest {
+
+  @Test
+  public void testGradleSourcesSetsInterpretation() throws Exception {
+    final int modulesSize = 7;
+
+    ModuleExtendedModelBuilderImpl moduleExtendedModelBuilder = new ModuleExtendedModelBuilderImpl();
+    assertTrue(moduleExtendedModelBuilder.canBuild("org.jetbrains.plugins.gradle.model.ModuleExtendedModel"));
+
+    DomainObjectSet<? extends IdeaModule> ideaModules = allModels.getIdeaProject().getModules();
+
+    List<ModuleExtendedModel> models =
+      ContainerUtil.mapNotNull(ideaModules, new Function<IdeaModule, ModuleExtendedModel>() {
+        @Override
+        public ModuleExtendedModel fun(IdeaModule module) {
+          ModuleExtendedModel moduleExtendedModel = allModels.getExtraProject(module, ModuleExtendedModel.class);
+
+          assertNotNull(moduleExtendedModel);
+
+          List<String> sourceDirectories = ContainerUtil.newArrayList();
+          List<String> resourceDirectories = ContainerUtil.newArrayList();
+          List<String> testResourceDirectories = ContainerUtil.newArrayList();
+          List<String> testDirectories = ContainerUtil.newArrayList();
+          List<String> excludeDirectories = ContainerUtil.newArrayList();
+
+          fillDirectories(moduleExtendedModel,
+                          sourceDirectories, resourceDirectories,
+                          testDirectories, testResourceDirectories,
+                          excludeDirectories);
+
+          if (module.getName().equals("defaultJavaModule") || module.getName().equals("moduleWithSourceSetDirBothAsResourceAndJava")) {
+            assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+          }
+          else if (module.getName().equals("moduleWithCustomSourceSet")) {
+            assertEquals(ContainerUtil.newArrayList("src/custom/java", "src/main/java"), sourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/custom/resources", "src/main/resources"), resourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/test/java"), testDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+          }
+          else if (module.getName().equals("withIntegrationTests")) {
+            assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(
+              "src/integration-test/java", "src/integrationTest/java", "src/test/java"), testDirectories);
+            assertEquals(ContainerUtil.newArrayList(
+              "src/integration-test/resources",
+              "src/integrationTest/resources",
+              "src/test/resources"), testResourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+          }
+          else if (module.getName().equals("testGradleSourcesSetsInterpretation")) {
+            assertTrue(sourceDirectories.isEmpty());
+            assertTrue(resourceDirectories.isEmpty());
+            assertTrue(testDirectories.isEmpty());
+            assertTrue(testResourceDirectories.isEmpty());
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+          }
+          else if (module.getName().equals("withIdeaPluginCustomization1")) {
+            assertEquals(ContainerUtil.newArrayList("src/main/java"), sourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/main/resources"), resourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/intTest/java", "src/intTest/resources", "src/test/java"), testDirectories);
+            assertEquals(ContainerUtil.newArrayList("src/test/resources"), testResourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build", "some-extra-exclude-folder"), excludeDirectories);
+          }
+          else if (module.getName().equals("withIdeaPluginCustomization2")) {
+            assertEquals(ContainerUtil.newArrayList("src/main/java", "src/test/java", "src/test/resources"), sourceDirectories);
+            assertEquals(ContainerUtil.newArrayList("some-extra-resource-folder", "src/main/resources"), resourceDirectories);
+            assertTrue(testDirectories.isEmpty());
+            assertEquals(ContainerUtil.newArrayList("some-extra-test-resource-folder"), testResourceDirectories);
+            assertEquals(ContainerUtil.newArrayList(".gradle", "build"), excludeDirectories);
+          }
+          else {
+            fail();
+          }
+
+          return moduleExtendedModel;
+        }
+      });
+
+    assertEquals(modulesSize, models.size());
+  }
+
+  private void fillDirectories(final ModuleExtendedModel model,
+                               List<String> sourceDirectories, List<String> resourceDirectories,
+                               List<String> testDirectories, List<String> resourceTestDirectories,
+                               List<String> excludeDirectories) {
+    for (ExtIdeaContentRoot contentRoot : model.getContentRoots()) {
+      sourceDirectories.addAll(getAllPaths(contentRoot.getSourceDirectories(), model.getName()));
+      resourceDirectories.addAll(getAllPaths(contentRoot.getResourceDirectories(), model.getName()));
+      testDirectories.addAll(getAllPaths(contentRoot.getTestDirectories(), model.getName()));
+      resourceTestDirectories.addAll(getAllPaths(contentRoot.getTestResourceDirectories(), model.getName()));
+      excludeDirectories.addAll(getAllPaths(contentRoot.getExcludeDirectories(), model.getName()));
+    }
+  }
+
+  private Collection<? extends String> getAllPaths(Collection<? extends File> directories, final String moduleName) {
+    List<String> list = ContainerUtil.map2List(directories, new Function<File, String>() {
+      @Override
+      public String fun(File sourceDirectory) {
+        String path =
+          FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory));
+        Assert.assertNotNull(path);
+        return path.substring(path.indexOf("/") + 1);
+      }
+    });
+    Collections.sort(list);
+    return list;
+  }
+
+  private Collection<? extends String> getAllPaths(DomainObjectSet<? extends IdeaSourceDirectory> directories, final String moduleName) {
+    List<String> list = ContainerUtil.map2List(directories, new Function<IdeaSourceDirectory, String>() {
+      @Override
+      public String fun(IdeaSourceDirectory sourceDirectory) {
+        String path =
+          FileUtil.toCanonicalPath(FileUtil.getRelativePath(new File(testDir, moduleName), sourceDirectory.getDirectory()));
+        Assert.assertNotNull(path);
+        return path.substring(path.indexOf("/") + 1);
+      }
+    });
+    Collections.sort(list);
+    return list;
+  }
+
+  @Override
+  protected Set<Class> getModels() {
+    return ContainerUtil.<Class>set(ModuleExtendedModel.class);
+  }
+}
+
diff --git a/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java b/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
index a3e7023..35b3577 100644
--- a/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
+++ b/plugins/groovy/hotswap/agentSrc/org/groovy/debug/hotswap/ResetAgent.java
@@ -2,6 +2,7 @@
 
 import org.objectweb.asm.*;
 
+import java.lang.String;
 import java.lang.instrument.ClassFileTransformer;
 import java.lang.instrument.IllegalClassFormatException;
 import java.lang.instrument.Instrumentation;
@@ -18,7 +19,15 @@
  */
 @SuppressWarnings({"UtilityClassWithoutPrivateConstructor", "UnusedDeclaration"})
 public class ResetAgent {
-  private static final String timStampFieldStart = "__timeStamp__239_neverHappen";
+  private static final String timeStampFieldStart = "__timeStamp__239_neverHappen";
+  private static final byte[] timeStampFieldStartBytes;
+  
+  static {
+    timeStampFieldStartBytes = new byte[timeStampFieldStart.length()];
+    for (int i = 0; i < timeStampFieldStart.length(); i++) {
+      timeStampFieldStartBytes[i] = (byte)timeStampFieldStart.charAt(i);
+    }
+  }
 
   private static boolean initialized;
 
@@ -44,18 +53,30 @@
     });
   }
 
-  private static boolean hasTimestampField(byte[] buffer) {
-    try {
-      return new String(buffer, "ISO-8859-1").contains(timStampFieldStart);
-    } catch (Throwable e) {
-      return true;
+  private static boolean matches(byte[] array, byte[] subArray, int start) {
+    for (int i = 0; i < subArray.length; i++) {
+      if (array[start + i] != subArray[i]) {
+        return false;
+      }
     }
+    return true;
+  }
+
+  private static boolean containsSubArray(byte[] array, byte[] subArray) {
+    int maxLength = array.length - subArray.length;
+    for (int i = 0; i < maxLength; i++) {
+      if (matches(array, subArray, i)) {
+        return true;
+      }
+    }
+    return false;
   }
 
   private static byte[] removeTimestampField(byte[] newBytes) {
-    if (!hasTimestampField(newBytes)) {
+    if (!containsSubArray(newBytes, timeStampFieldStartBytes)) {
       return null;
     }
+    
 
     final boolean[] changed = new boolean[]{false};
     final ClassWriter writer = new ClassWriter(0);
@@ -76,7 +97,7 @@
 
     @Override
     public FieldVisitor visitField(int i, String name, String s1, String s2, Object o) {
-      if (name.startsWith(timStampFieldStart)) {
+      if (name.startsWith(timeStampFieldStart)) {
         //remove the field
         changed[0] = true;
         return null;
@@ -92,7 +113,7 @@
         return new MethodAdapter(mw) {
           @Override
           public void visitFieldInsn(int opCode, String s, String name, String desc) {
-            if (name.startsWith(timStampFieldStart) && opCode == Opcodes.PUTSTATIC) {
+            if (name.startsWith(timeStampFieldStart) && opCode == Opcodes.PUTSTATIC) {
               visitInsn(Type.LONG_TYPE.getDescriptor().equals(desc) ? Opcodes.POP2 : Opcodes.POP);
             } else {
               super.visitFieldInsn(opCode, s, name, desc);
diff --git a/plugins/groovy/hotswap/gragent.jar b/plugins/groovy/hotswap/gragent.jar
index 8794d67..b0e1767 100644
--- a/plugins/groovy/hotswap/gragent.jar
+++ b/plugins/groovy/hotswap/gragent.jar
Binary files differ
diff --git a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.ft b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.ft
similarity index 100%
rename from plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.ft
rename to plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.ft
diff --git a/plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.html b/plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.html
similarity index 100%
rename from plugins/groovy/resources/fileTemplates/code/Spock SetUp Method.groovy.html
rename to plugins/groovy/resources/fileTemplates/code/Spock_SetUp_Method.groovy.html
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
index e5b5681..9116dbe 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/navbar/GrNavBarModelExtension.java
@@ -22,6 +22,7 @@
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.Nullable;
 import org.jetbrains.jps.model.java.JavaModuleSourceRootTypes;
 import org.jetbrains.plugins.groovy.GroovyFileType;
 import org.jetbrains.plugins.groovy.lang.psi.GroovyFileBase;
@@ -32,6 +33,12 @@
  */
 public class GrNavBarModelExtension extends AbstractNavBarModelExtension {
 
+  @Nullable
+  @Override
+  public String getPresentableText(Object object) {
+    return null;
+  }
+
   @Override
   public PsiElement adjustElement(PsiElement psiElement) {
     final ProjectFileIndex index = ProjectRootManager.getInstance(psiElement.getProject()).getFileIndex();
diff --git a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
index b7872dcc..9a36c8c8 100644
--- a/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
+++ b/plugins/groovy/src/org/jetbrains/plugins/groovy/spock/SpockTestFramework.java
@@ -51,7 +51,7 @@
 
   @Override
   public FileTemplateDescriptor getSetUpMethodFileTemplateDescriptor() {
-    return new FileTemplateDescriptor("Spock SetUp Method.groovy");
+    return new FileTemplateDescriptor("Spock_SetUp_Method.groovy");
   }
 
   @Override
diff --git a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
index 53cb43d..9fc2b16 100644
--- a/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
+++ b/plugins/hg4idea/src/org/zmlx/hg4idea/log/HgLogProvider.java
@@ -19,20 +19,14 @@
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vcs.VcsException;
 import com.intellij.openapi.vcs.VcsKey;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.Consumer;
-import com.intellij.util.Function;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.vcs.log.*;
-import com.intellij.vcs.log.data.VcsLogBranchFilter;
-import com.intellij.vcs.log.data.VcsLogDateFilter;
-import com.intellij.vcs.log.data.VcsLogStructureFilter;
-import com.intellij.vcs.log.data.VcsLogUserFilter;
-import com.intellij.vcs.log.ui.filter.VcsLogTextFilter;
+import com.intellij.vcs.log.VcsLogTextFilter;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 import org.zmlx.hg4idea.HgNameWithHashInfo;
@@ -162,33 +156,28 @@
   @NotNull
   @Override
   public List<? extends VcsFullCommitDetails> getFilteredDetails(@NotNull final VirtualFile root,
-                                                                 @NotNull Collection<VcsLogFilter> filters,
+                                                                 @NotNull Collection<VcsLogBranchFilter> branchFilters,
+                                                                 @NotNull Collection<VcsLogUserFilter> userFilters,
+                                                                 @NotNull Collection<VcsLogDateFilter> dateFilters,
+                                                                 @NotNull Collection<VcsLogTextFilter> textFilters,
+                                                                 @NotNull Collection<VcsLogStructureFilter> structureFilters,
                                                                  int maxCount) throws VcsException {
     List<String> filterParameters = ContainerUtil.newArrayList();
 
-    List<VcsLogBranchFilter> branchFilters = ContainerUtil.findAll(filters, VcsLogBranchFilter.class);
+    // branch filter and user filter may be used several times without delimiter
+    // or -r options with appropriate revset arguments delimited by '|' or 'and'.
     if (!branchFilters.isEmpty()) {
-      String branchFilter = joinFilters(branchFilters, new Function<VcsLogBranchFilter, String>() {
-        @Override
-        public String fun(VcsLogBranchFilter filter) {
-          return filter.getBranchName();
-        }
-      });
-      filterParameters.add(prepareParameter("branch", branchFilter));
+      for (VcsLogBranchFilter branchFilter : branchFilters) {
+        filterParameters.add(prepareParameter("branch", branchFilter.getBranchName()));
+      }
     }
 
-    List<VcsLogUserFilter> userFilters = ContainerUtil.findAll(filters, VcsLogUserFilter.class);
     if (!userFilters.isEmpty()) {
-      String authorFilter = joinFilters(userFilters, new Function<VcsLogUserFilter, String>() {
-        @Override
-        public String fun(VcsLogUserFilter filter) {
-          return filter.getUserName(root);
-        }
-      });
-      filterParameters.add(prepareParameter("user", authorFilter));
+      for (VcsLogUserFilter authorFilter : userFilters) {
+        filterParameters.add(prepareParameter("user", authorFilter.getUserName(root)));
+      }
     }
 
-    List<VcsLogDateFilter> dateFilters = ContainerUtil.findAll(filters, VcsLogDateFilter.class);
     if (!dateFilters.isEmpty()) {
       StringBuilder args = new StringBuilder();
       final SimpleDateFormat dateFormatter = new SimpleDateFormat("yyyy-MM-dd HH:mm");
@@ -208,7 +197,6 @@
       filterParameters.add(args.toString());
     }
 
-    List<VcsLogTextFilter> textFilters = ContainerUtil.findAll(filters, VcsLogTextFilter.class);
     if (textFilters.size() > 1) {
       LOG.warn("Expected only one text filter: " + textFilters);
     }
@@ -217,7 +205,6 @@
       filterParameters.add(prepareParameter("keyword", textFilter));
     }
 
-    List<VcsLogStructureFilter> structureFilters = ContainerUtil.findAll(filters, VcsLogStructureFilter.class);
     if (!structureFilters.isEmpty()) {
       for (VcsLogStructureFilter filter : structureFilters) {
         for (VirtualFile file : filter.getFiles(root)) {
@@ -249,8 +236,4 @@
   private static String prepareParameter(String paramName, String value) {
     return "--" + paramName + "=" + value; // no value escaping needed, because the parameter itself will be quoted by GeneralCommandLine
   }
-
-  private static <T> String joinFilters(List<T> filters, Function<T, String> toString) {
-    return StringUtil.join(filters, toString, "\\|");
-  }
 }
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
index 8f9a7b8..13bf786 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/compiler/MavenResourcesBuilder.java
@@ -1,6 +1,7 @@
 package org.jetbrains.jps.maven.compiler;
 
 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 org.jetbrains.jps.builders.BuildOutputConsumer;
@@ -116,7 +117,13 @@
       private Pattern getDelimitersPattern() {
         Pattern pattern = myDelimitersPattern;
         if (pattern == null) {
-          pattern = Pattern.compile(config.delimitersPattern);
+          if (StringUtil.isEmpty(config.escapeString)) {
+            pattern = Pattern.compile(config.delimitersPattern);
+          }
+          else {
+            String quotedEscapeString = Pattern.quote(config.escapeString);
+            pattern = Pattern.compile("(" + quotedEscapeString + quotedEscapeString + ")|(?:(" + quotedEscapeString + ")?(" + config.delimitersPattern + "))");
+          }
           myDelimitersPattern = pattern;
         }
         return pattern;
@@ -168,28 +175,31 @@
     Map<String, String> resolvedProperties = resolvedPropertiesParam;
 
     final Matcher matcher = delimitersPattern.matcher(text);
+
+    boolean hasEscapeString = !StringUtil.isEmpty(moduleConfig.escapeString);
+
     final int groupCount = matcher.groupCount();
-    final String escapeString = moduleConfig.escapeString;
+    int firstPropertyGroupIndex = hasEscapeString ? 3 : 0;
+
     int last = 0;
     while (matcher.find()) {
-      if (escapeString != null) {
-        int escapeStringStartIndex = matcher.start() - escapeString.length();
-        if (escapeStringStartIndex >= last) {
-          if (text.startsWith(escapeString, escapeStringStartIndex)) {
-            out.append(text, last, escapeStringStartIndex);
-            out.append(matcher.group());
-            last = matcher.end();
-            continue;
-          }
-        }
-      }
-
       out.append(text, last, matcher.start());
       last = matcher.end();
 
+      if (hasEscapeString) {
+        if (matcher.group(1) != null) {
+          out.append(moduleConfig.escapeString).append(moduleConfig.escapeString); // double escape string
+          continue;
+        }
+        else if (matcher.group(2) != null) {
+          out.append(matcher.group(3)); // escaped value
+          continue;
+        }
+      }
+
       String propertyName = null;
 
-      for (int i = 0; i < groupCount; i++) {
+      for (int i = firstPropertyGroupIndex; i < groupCount; i++) {
         propertyName = matcher.group(i + 1);
         if (propertyName != null) {
           break;
diff --git a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
index 3c4c47c..86340ad 100644
--- a/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
+++ b/plugins/maven/jps-plugin/src/org/jetbrains/jps/maven/model/impl/MavenModuleResourceConfiguration.java
@@ -58,7 +58,7 @@
   public Set<String> filteringExclusions = new THashSet<String>(FileUtil.PATH_HASHING_STRATEGY);
 
   @OptionTag
-  public String escapeString = MavenProjectConfiguration.DEFAULT_ESCAPE_STRING;
+  public String escapeString = null;
 
   @OptionTag
   public boolean escapeWindowsPaths = true;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
index 209583b..d5eb4a6 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/compiler/MavenResourceCompiler.java
@@ -167,7 +167,7 @@
         Set<String> nonFilteredExtensions = collectNonFilteredExtensions(mavenProject);
         String escapeString = MavenJDOMUtil.findChildValueByPath(mavenProject.getPluginConfiguration("org.apache.maven.plugins",
                                                                                                      "maven-resources-plugin"),
-                                                                 "escapeString", "\\");
+                                                                 "escapeString", null);
 
         List<MyProcessingItem> moduleItemsToProcess = new ArrayList<MyProcessingItem>();
         collectProcessingItems(eachModule, mavenProject, context, properties, propertiesHashCode,
@@ -245,7 +245,7 @@
                                              Properties properties,
                                              long propertiesHashCode,
                                              Set<String> nonFilteredExtensions,
-                                             String escapeString,
+                                             @Nullable String escapeString,
                                              boolean tests,
                                              List<MyProcessingItem> result) {
     String outputDir = CompilerPaths.getModuleOutputPath(module, tests);
@@ -305,7 +305,7 @@
                                              final Properties properties,
                                              final long propertiesHashCode,
                                              final Set<String> nonFilteredExtensions,
-                                             final String escapeString,
+                                             @Nullable final String escapeString,
                                              final List<MyProcessingItem> result,
                                              final ProgressIndicator indicator) {
     VfsUtilCore.visitChildrenRecursively(currentDir, new VirtualFileVisitor() {
@@ -476,7 +476,7 @@
                             boolean isFiltered,
                             Properties properties,
                             long propertiesHashCode,
-                            String escapeString) {
+                            @Nullable String escapeString) {
       myModule = module;
       mySourceFile = sourceFile;
       myOutputPath = outputPath;
@@ -507,6 +507,7 @@
       return myProperties;
     }
 
+    @Nullable
     public String getEscapeString() {
       return myEscapeString;
     }
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
index 979e182..6687589 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/dom/MavenPropertyResolver.java
@@ -47,7 +47,7 @@
   public static void doFilterText(Module module,
                                   String text,
                                   Properties additionalProperties,
-                                  String propertyEscapeString,
+                                  @Nullable String propertyEscapeString,
                                   Appendable out) throws IOException {
     MavenProjectsManager manager = MavenProjectsManager.getInstance(module.getProject());
     MavenProject mavenProject = manager.findProject(module);
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
index 553175e..0d4b06b 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/importing/MavenModuleImporter.java
@@ -294,9 +294,7 @@
         if (file == null) continue;
 
         if (libraryModel == null) {
-          String libraryName = artifact.getLibraryName();
-          assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX);
-          libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length());
+          String libraryName = getAttachedJarsLibName(artifact);
 
           Library library = myModifiableModelsProvider.getLibraryByName(libraryName);
           if (library == null) {
@@ -314,6 +312,14 @@
   }
 
   @NotNull
+  public static String getAttachedJarsLibName(@NotNull MavenArtifact artifact) {
+    String libraryName = artifact.getLibraryName();
+    assert libraryName.startsWith(MavenArtifact.MAVEN_LIB_PREFIX);
+    libraryName = MavenArtifact.MAVEN_LIB_PREFIX + "ATTACHED-JAR: " + libraryName.substring(MavenArtifact.MAVEN_LIB_PREFIX.length());
+    return libraryName;
+  }
+
+  @NotNull
   public static DependencyScope selectScope(String mavenScope) {
     if (MavenConstants.SCOPE_RUNTIME.equals(mavenScope)) return DependencyScope.RUNTIME;
     if (MavenConstants.SCOPE_TEST.equals(mavenScope)) return DependencyScope.TEST;
diff --git a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
index 523d5cb..c2b0aa9 100644
--- a/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
+++ b/plugins/maven/src/main/java/org/jetbrains/idea/maven/project/MavenResourceCompilerConfigurationGenerator.java
@@ -129,7 +129,7 @@
       }
 
       Element pluginConfiguration = mavenProject.getPluginConfiguration("org.apache.maven.plugins", "maven-resources-plugin");
-      resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", "\\");
+      resourceConfig.escapeString = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeString", null);
       String escapeWindowsPaths = MavenJDOMUtil.findChildValueByPath(pluginConfiguration, "escapeWindowsPaths");
       if (escapeWindowsPaths != null) {
         resourceConfig.escapeWindowsPaths = Boolean.parseBoolean(escapeWindowsPaths);
diff --git a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
index 4c2c781..80e738f 100644
--- a/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
+++ b/plugins/maven/src/test/java/org/jetbrains/idea/maven/compiler/ResourceFilteringTest.java
@@ -868,10 +868,15 @@
   }
 
   public void testEscapingFiltering() throws Exception {
+    if (!useJps()) return;
+
     createProjectSubFile("filters/filter.properties", "xxx=value");
     createProjectSubFile("resources/file.properties",
                          "value1=\\${xxx}\n" +
-                         "value2=${xxx}\n");
+                         "value2=\\\\${xxx}\n" +
+                         "value3=\\\\\\${xxx}\n" +
+                         "value3=\\\\\\\\${xxx}\n" +
+                         "value4=.\\.\\\\.\\\\\\.");
 
     importProject("<groupId>test</groupId>" +
                   "<artifactId>project</artifactId>" +
@@ -887,12 +892,24 @@
                   "      <filtering>true</filtering>" +
                   "    </resource>" +
                   "  </resources>" +
+                  "  <plugins>" +
+                  "    <plugin>" +
+                  "      <groupId>org.apache.maven.plugins</groupId>" +
+                  "      <artifactId>maven-resources-plugin</artifactId>" +
+                  "      <configuration>" +
+                  "        <escapeString>\\</escapeString>" +
+                  "      </configuration>" +
+                  "    </plugin>" +
+                  "  </plugins>" +
                   "</build>");
 
     compileModules("project");
     assertResult("target/classes/file.properties",
                  "value1=${xxx}\n" +
-                 "value2=value\n");
+                 "value2=\\\\value\n" +
+                 "value3=\\\\${xxx}\n" +
+                 "value3=\\\\\\\\value\n" +
+                 "value4=.\\.\\\\.\\\\\\.");
   }
 
   public void testPropertyPriority() throws Exception {
diff --git a/python/IntelliLang-python/src/pyInjections.xml b/python/IntelliLang-python/src/pyInjections.xml
index f561c1d..a75015e 100644
--- a/python/IntelliLang-python/src/pyInjections.xml
+++ b/python/IntelliLang-python/src/pyInjections.xml
@@ -9,6 +9,6 @@
   </injection>
   <injection language="SQL" injector-id="python">
     <display-name>"SQL select/delete/insert/update/create"</display-name>
-    <place><![CDATA[pyLiteralExpression().withText(string().matchesBrics("[UuRrBb\\\"\\' \t]*(((SELECT|DELETE) .*FROM)|((INSERT|REPLACE) .*INTO)|(UPDATE .* SET)|((CREATE|DROP|ALTER) +(TABLE|INDEX))) .*"))]]></place>
+    <place><![CDATA[pyLiteralExpression().withText(string().matchesBrics(".*(((SELECT|DELETE) .*FROM)|((INSERT|REPLACE) .*INTO)|(UPDATE .* SET)|((CREATE|DROP|ALTER) +(TABLE|INDEX))) .*"))]]></place>
   </injection>
 </component>
diff --git a/python/helpers/generator3.py b/python/helpers/generator3.py
index fe24620..ca61efe 100644
--- a/python/helpers/generator3.py
+++ b/python/helpers/generator3.py
@@ -1,43 +1,15 @@
 # encoding: utf-8
-from pycharm_generator_utils.module_redeclarator import *
-from pycharm_generator_utils.util_methods import *
-from pycharm_generator_utils.constants import *
-import os
 import atexit
 import zipfile
 
+from pycharm_generator_utils.module_redeclarator import *
+from pycharm_generator_utils.util_methods import *
+from pycharm_generator_utils.constants import *
+
+
 debug_mode = False
 
 
-def build_output_name(dirname, qualified_name):
-    qualifiers = qualified_name.split(".")
-    if dirname and not dirname.endswith("/") and not dirname.endswith("\\"):
-        dirname += os.path.sep # "a -> a/"
-    for pathindex in range(len(qualifiers) - 1): # create dirs for all qualifiers but last
-        subdirname = dirname + os.path.sep.join(qualifiers[0: pathindex + 1])
-        if not os.path.isdir(subdirname):
-            action("creating subdir %r", subdirname)
-            os.makedirs(subdirname)
-        init_py = os.path.join(subdirname, "__init__.py")
-        if os.path.isfile(subdirname + ".py"):
-            os.rename(subdirname + ".py", init_py)
-        elif not os.path.isfile(init_py):
-            init = fopen(init_py, "w")
-            init.close()
-    target_name = dirname + os.path.sep.join(qualifiers)
-    if os.path.isdir(target_name):
-        fname = os.path.join(target_name, "__init__.py")
-    else:
-        fname = target_name + ".py"
-
-    dirname = os.path.dirname(fname)
-
-    if not os.path.isdir(dirname):
-        os.makedirs(dirname)
-
-    return fname
-
-
 def redo_module(module_name, outfile, module_file_name, doing_builtins):
     # gobject does 'del _gobject' in its __init__.py, so the chained attribute lookup code
     # fails to find 'gobject._gobject'. thus we need to pull the module directly out of
@@ -263,80 +235,67 @@
         say(name)
         sys.stdout.flush()
     action("doing nothing")
-    outfile = None
+
     try:
-        try:
-            fname = build_output_name(subdir, name)
-            action("opening %r", fname)
-            outfile = fopen(fname, "w")
-            old_modules = list(sys.modules.keys())
-            imported_module_names = []
+        fname = build_output_name(subdir, name)
+        action("opening %r", fname)
+        old_modules = list(sys.modules.keys())
+        imported_module_names = []
 
-            class MyFinder:
-                #noinspection PyMethodMayBeStatic
-                def find_module(self, fullname, path=None):
-                    if fullname != name:
-                        imported_module_names.append(fullname)
-                    return None
+        class MyFinder:
+            #noinspection PyMethodMayBeStatic
+            def find_module(self, fullname, path=None):
+                if fullname != name:
+                    imported_module_names.append(fullname)
+                return None
 
-            my_finder = None
-            if hasattr(sys, 'meta_path'):
-                my_finder = MyFinder()
-                sys.meta_path.append(my_finder)
-            else:
-                imported_module_names = None
+        my_finder = None
+        if hasattr(sys, 'meta_path'):
+            my_finder = MyFinder()
+            sys.meta_path.append(my_finder)
+        else:
+            imported_module_names = None
 
-            action("importing")
-            __import__(name) # sys.modules will fill up with what we want
+        action("importing")
+        __import__(name) # sys.modules will fill up with what we want
 
-            if my_finder:
-                sys.meta_path.remove(my_finder)
-            if imported_module_names is None:
-                imported_module_names = [m for m in sys.modules.keys() if m not in old_modules]
+        if my_finder:
+            sys.meta_path.remove(my_finder)
+        if imported_module_names is None:
+            imported_module_names = [m for m in sys.modules.keys() if m not in old_modules]
 
-            redo_module(name, outfile, mod_file_name, doing_builtins)
-            # The C library may have called Py_InitModule() multiple times to define several modules (gtk._gtk and gtk.gdk);
-            # restore all of them
-            path = name.split(".")
-            redo_imports = not ".".join(path[:-1]) in MODULES_INSPECT_DIR
-            if imported_module_names and redo_imports:
-                for m in sys.modules.keys():
-                    action("looking at possible submodule %r", m)
-                    # if module has __file__ defined, it has Python source code and doesn't need a skeleton
-                    if m not in old_modules and m not in imported_module_names and m != name and not hasattr(
-                            sys.modules[m], '__file__'):
-                        if not quiet:
-                            say(m)
-                            sys.stdout.flush()
-                        fname = build_output_name(subdir, m)
-                        action("opening %r", fname)
-                        subfile = fopen(fname, "w")
-                        try:
-                            redo_module(m, subfile, mod_file_name, doing_builtins)
-                        finally:
-                            action("closing %r", fname)
-                            subfile.close()
-        except:
-            exctype, value = sys.exc_info()[:2]
-            msg = "Failed to process %r while %s: %s"
-            args = name, CURRENT_ACTION, str(value)
-            report(msg, *args)
-            if outfile is not None and not outfile.closed:
-                outfile.write("# encoding: %s\n" % OUT_ENCODING)
-                outfile.write("# module %s\n" % name)
-                outfile.write("# from %s\n" % mod_file_name)
-                outfile.write("# by generator %s\n" % VERSION)
-                outfile.write("\n\n")
-                outfile.write("# Skeleton generation error:\n#\n#     " + (msg % args) + "\n")
-            if debug_mode:
-                if sys.platform == 'cli':
-                    import traceback
-                    traceback.print_exc(file=sys.stderr)
-                raise
-            return False
-    finally:
-        if outfile is not None and not outfile.closed:
-            outfile.close()
+        redo_module(name, fname, mod_file_name, doing_builtins)
+        # The C library may have called Py_InitModule() multiple times to define several modules (gtk._gtk and gtk.gdk);
+        # restore all of them
+        path = name.split(".")
+        redo_imports = not ".".join(path[:-1]) in MODULES_INSPECT_DIR
+        if imported_module_names and redo_imports:
+            for m in sys.modules.keys():
+                if m.startswith("pycharm_generator_utils"): continue
+                action("looking at possible submodule %r", m)
+                # if module has __file__ defined, it has Python source code and doesn't need a skeleton
+                if m not in old_modules and m not in imported_module_names and m != name and not hasattr(
+                        sys.modules[m], '__file__'):
+                    if not quiet:
+                        say(m)
+                        sys.stdout.flush()
+                    fname = build_output_name(subdir, m)
+                    action("opening %r", fname)
+                    try:
+                        redo_module(m, fname, mod_file_name, doing_builtins)
+                    finally:
+                        action("closing %r", fname)
+    except:
+        exctype, value = sys.exc_info()[:2]
+        msg = "Failed to process %r while %s: %s"
+        args = name, CURRENT_ACTION, str(value)
+        report(msg, *args)
+        if debug_mode:
+            if sys.platform == 'cli':
+                import traceback
+                traceback.print_exc(file=sys.stderr)
+            raise
+        return False
     return True
 
 
diff --git a/python/helpers/pycharm/nose_utils.py b/python/helpers/pycharm/nose_utils.py
index bed318a..9a6d682 100644
--- a/python/helpers/pycharm/nose_utils.py
+++ b/python/helpers/pycharm/nose_utils.py
@@ -1,9 +1,13 @@
-from tcmessages import TeamcityServiceMessages
-import sys, traceback, datetime
+import sys
+import traceback
+import datetime
 import unittest
+
+from tcmessages import TeamcityServiceMessages
 from tcunittest import strclass
 from tcunittest import TeamcityTestResult
 
+
 try:
   from nose.util import isclass # backwards compat
   from nose.config import Config
@@ -59,7 +63,10 @@
   def formatErr(self, err):
     exctype, value, tb = err
     if isinstance(value, str):
-      value = exctype(value)
+      try:
+        value = exctype(value)
+      except TypeError:
+        pass
     return ''.join(traceback.format_exception(exctype, value, tb))
 
   def is_gen(self, test):
diff --git a/python/helpers/pycharm_generator_utils/constants.py b/python/helpers/pycharm_generator_utils/constants.py
index 6b77e73..4ea8cf1 100644
--- a/python/helpers/pycharm_generator_utils/constants.py
+++ b/python/helpers/pycharm_generator_utils/constants.py
@@ -6,7 +6,7 @@
 import time
 
 
-VERSION = "1.131"
+VERSION = "1.133"
 
 OUT_ENCODING = 'utf-8'
 
diff --git a/python/helpers/pycharm_generator_utils/module_redeclarator.py b/python/helpers/pycharm_generator_utils/module_redeclarator.py
index f56fb43..8377879 100644
--- a/python/helpers/pycharm_generator_utils/module_redeclarator.py
+++ b/python/helpers/pycharm_generator_utils/module_redeclarator.py
@@ -1,6 +1,7 @@
+import keyword
+
 from pycharm_generator_utils.util_methods import *
 from pycharm_generator_utils.constants import *
-import keyword, re
 
 
 class emptylistdict(dict):
@@ -49,6 +50,11 @@
         return len(self.data) == 0
 
 
+class ClassBuf(Buf):
+    def __init__(self, name, indenter):
+        super(ClassBuf, self).__init__(indenter)
+        self.name = name
+
 #noinspection PyUnresolvedReferences,PyBroadException
 class ModuleRedeclarator(object):
     def __init__(self, module, outfile, mod_filename, indent_size=4, doing_builtins=False):
@@ -67,6 +73,7 @@
         self.imports_buf = Buf(self)
         self.functions_buf = Buf(self)
         self.classes_buf = Buf(self)
+        self.classes_buffs = list()
         self.footer_buf = Buf(self)
         self.indent_size = indent_size
         self._indent_step = " " * self.indent_size
@@ -106,8 +113,43 @@
         return self._indent_step * level
 
     def flush(self):
-        for buf in (self.header_buf, self.imports_buf, self.functions_buf, self.classes_buf, self.footer_buf):
-            buf.flush(self.outfile)
+        init = None
+        try:
+            if self.mod_filename and len(self.classes_buffs) >= 30:
+                mod_path = self.outfile.strip(".py")
+
+                fname = build_output_name(mod_path, "__init__")
+                init = fopen(fname, "w")
+                for buf in (self.header_buf, self.imports_buf, self.functions_buf, self.classes_buf):
+                    buf.flush(init)
+
+                data = ""
+                for buf in self.classes_buffs:
+                    fname = build_output_name(mod_path, buf.name)
+                    dummy = fopen(fname, "w")
+                    self.header_buf.flush(dummy)
+                    buf.flush(dummy)
+                    data += "from "
+                    if version[0] >= 3:
+                        data += "."
+                    data += buf.name + " import " + buf.name + "\n"
+                    dummy.close()
+
+                init.write(data)
+                self.footer_buf.flush(init)
+            else:
+                init = fopen(self.outfile, "w")
+                for buf in (self.header_buf, self.imports_buf, self.functions_buf, self.classes_buf):
+                    buf.flush(init)
+
+                for buf in self.classes_buffs:
+                    buf.flush(init)
+
+                self.footer_buf.flush(init)
+
+        finally:
+            if init is not None and not init.closed:
+                init.close()
 
     # Some builtin classes effectively change __init__ signature without overriding it.
     # This callable serves as a placeholder to be replaced via REDEFINED_BUILTIN_SIGS
@@ -150,7 +192,7 @@
         for initializer_type, r in self._initializers:
             if initializer_type == a_type:
                 return r
-            # NOTE: here we could handle things like defaultdict, sets, etc if we wanted
+                # NOTE: here we could handle things like defaultdict, sets, etc if we wanted
         return "None"
 
 
@@ -224,7 +266,7 @@
                                 seen_values.append(value)
                             if isinstance(k, SIMPLEST_TYPES):
                                 self.fmt_value(out, value, indent + 1, prefix=repr(k) + ": ", postfix=",",
-                                              seen_values=seen_values)
+                                               seen_values=seen_values)
                             else:
                                 # both key and value need fancy formatting
                                 self.fmt_value(out, k, indent + 1, postfix=": ", seen_values=seen_values)
@@ -244,9 +286,15 @@
                     if self._defined.get(found_name, False):
                         out(indent, prefix, found_name, postfix)
                     else:
-                    # a forward / circular declaration happens
+                        # a forward / circular declaration happens
                         notice = ""
-                        real_value = cleanup(repr(p_value))
+                        try:
+                            representation = repr(p_value)
+                        except Exception:
+                            import traceback
+                            traceback.print_exc(file=sys.stderr)
+                            return
+                        real_value = cleanup(representation)
                         if found_name:
                             if found_name == as_name:
                                 notice = " # (!) real value is %r" % real_value
@@ -409,7 +457,7 @@
 
     def is_predefined_builtin(self, module_name, class_name, func_name):
         return self.doing_builtins and module_name == BUILTIN_MOD_NAME and (
-        class_name, func_name) in PREDEFINED_BUILTIN_SIGS
+            class_name, func_name) in PREDEFINED_BUILTIN_SIGS
 
 
     def redo_function(self, out, p_func, p_name, indent, p_class=None, p_modname=None, classname=None, seen=None):
@@ -434,7 +482,7 @@
                 return
             else:
                 seen[id(p_func)] = p_name
-            # real work
+                # real work
         if classname is None:
             classname = p_class and p_class.__name__ or None
         if p_class and hasattr(p_class, '__mro__'):
@@ -492,7 +540,7 @@
             out(indent, "def ", p_name, sig, ": # known case of ", ofwhat)
             out_doc_attr(out, p_func, indent + 1, p_class)
         else:
-        # __doc__ is our best source of arglist
+            # __doc__ is our best source of arglist
             sig_note = "real signature unknown"
             spec = ""
             is_init = (p_name == "__init__" and p_class is not None)
@@ -508,17 +556,17 @@
             action("parsing doc of func %r of class %r", p_name, p_class)
             if isinstance(funcdoc, STR_TYPES):
                 (spec, ret_literal, more_notes) = self.parse_func_doc(funcdoc, p_name, p_name, classname, deco,
-                                                                    sip_generated)
+                                                                      sip_generated)
                 if spec is None and p_name == '__init__' and classname:
                     (spec, ret_literal, more_notes) = self.parse_func_doc(funcdoc, classname, p_name, classname, deco,
-                                                                        sip_generated)
+                                                                          sip_generated)
                 sig_restored = spec is not None
                 if more_notes:
                     if sig_note:
                         sig_note += "; "
                     sig_note += more_notes
             if not sig_restored:
-            # use an allow-all declaration
+                # use an allow-all declaration
                 decl = []
                 if p_class:
                     first_param = propose_first_param(deco)
@@ -531,7 +579,7 @@
             # to reduce size of stubs, don't output same docstring twice for class and its __init__ method
             if not is_init or funcdoc != p_class.__doc__:
                 out_docstring(out, funcdoc, indent + 1)
-            # body
+                # body
         if ret_literal and not is_init:
             out(indent + 1, "return ", ret_literal)
         else:
@@ -646,7 +694,7 @@
                 self.redo_function(out, item, item_name, indent + 1, p_class, p_modname, classname=p_name, seen=seen_funcs)
             except:
                 handle_error_func(item_name, out)
-            #
+                #
         known_props = KNOWN_PROPS.get(p_modname, {})
         a_setter = "lambda self, v: None"
         a_deleter = "lambda self: None"
@@ -782,7 +830,7 @@
         for item_name in module_dict:
             note("looking at %s", item_name)
             if item_name in (
-            "__dict__", "__doc__", "__module__", "__file__", "__name__", "__builtins__", "__package__"):
+                "__dict__", "__doc__", "__module__", "__file__", "__name__", "__builtins__", "__package__"):
                 continue # handled otherwise
             try:
                 item = getattr(self.module, item_name) # let getters do the magic
@@ -806,7 +854,7 @@
                     mod_name = getattr(item, '__module__', None)
                 except:
                     pass
-                # we assume that module foo.bar never imports foo; foo may import foo.bar. (see pygame and pygame.rect)
+                    # we assume that module foo.bar never imports foo; foo may import foo.bar. (see pygame and pygame.rect)
             maybe_import_mod_name = mod_name or ""
             import_is_from_top = len(p_name) > len(maybe_import_mod_name) and p_name.startswith(maybe_import_mod_name)
             note("mod_name = %s, prospective = %s,  from top = %s", mod_name, maybe_import_mod_name, import_is_from_top)
@@ -906,9 +954,8 @@
             self.functions_buf.out(0, "# no functions")
             #
         if classes:
-            out = self.functions_buf.out
-            out(0, "# classes")
-            out(0, "")
+            self.classes_buf.out(0, "# classes")
+            self.classes_buf.out(0, "")
             seen_classes = {}
             # sort classes so that inheritance order is preserved
             cls_list = [] # items are (class_name, mro_tuple)
@@ -922,6 +969,9 @@
                         break         # ...and need not go fartehr than first known child
                 cls_list.insert(ins_index, (cls_name, get_mro(cls)))
             for item_name in [cls_item[0] for cls_item in cls_list]:
+                buf = ClassBuf(item_name, self)
+                self.classes_buffs.append(buf)
+                out = buf.out
                 if item_name in omitted_names:
                     out(0, "# definition of ", item_name, " omitted")
                     continue
@@ -974,7 +1024,7 @@
             self.footer_buf.out(0, "# intermittent names")
             for value in values_to_add:
                 self.footer_buf.out(0, value)
-            # imports: last, because previous parts could alter used_imports or hidden_imports
+                # imports: last, because previous parts could alter used_imports or hidden_imports
         self.output_import_froms()
         if self.imports_buf.isEmpty():
             self.imports_buf.out(0, "# no imports")
@@ -1009,7 +1059,7 @@
                             names_pack.append(n)
                             names_pack.append(", ")
                             right_pos += (len_n + 2)
-                        # last line is...
+                            # last line is...
                     if indent_level == 0: # one line
                         names_pack[0] = names_pack[0][:-1] # cut off lpar
                         names_pack[-1] = "" # cut last comma
diff --git a/python/helpers/pycharm_generator_utils/util_methods.py b/python/helpers/pycharm_generator_utils/util_methods.py
index 8d6d356..2ddbc94 100644
--- a/python/helpers/pycharm_generator_utils/util_methods.py
+++ b/python/helpers/pycharm_generator_utils/util_methods.py
@@ -6,7 +6,7 @@
     inspect = None
 
 def create_named_tuple():   #TODO: user-skeleton
-        return """
+    return """
 class __namedtuple(tuple):
     '''A mock base class for named tuples.'''
 
@@ -38,12 +38,12 @@
 """
 
 def create_generator():
-        # Fake <type 'generator'>
-        if version[0] < 3:
-            next_name = "next"
-        else:
-            next_name = "__next__"
-        txt = """
+    # Fake <type 'generator'>
+    if version[0] < 3:
+        next_name = "next"
+    else:
+        next_name = "__next__"
+    txt = """
 class __generator(object):
     '''A mock class representing the generator function type.'''
     def __init__(self):
@@ -59,8 +59,8 @@
         '''Return the next item from the container.'''
         pass
 """ % (next_name,)
-        if version[0] >= 3 or (version[0] == 2 and version[1] >= 5):
-            txt += """
+    if version[0] >= 3 or (version[0] == 2 and version[1] >= 5):
+        txt += """
     def close(self):
         '''Raises new GeneratorExit exception inside the generator to terminate the iteration.'''
         pass
@@ -73,10 +73,10 @@
         '''Used to raise an exception inside the generator.'''
         pass
 """
-        return txt
+    return txt
 
 def _searchbases(cls, accum):
-# logic copied from inspect.py
+    # logic copied from inspect.py
     if cls not in accum:
         accum.append(cls)
         for x in cls.__bases__:
@@ -84,7 +84,7 @@
 
 
 def get_mro(a_class):
-# logic copied from inspect.py
+    # logic copied from inspect.py
     """Returns a tuple of MRO classes."""
     if hasattr(a_class, "__mro__"):
         return a_class.__mro__
@@ -236,7 +236,7 @@
                 if toplevel and not has_item_starting_with(ret, "*"):
                     ret.append("*more")
                 else:
-                # we're in a "foo, (bar1, bar2, ...)"; make it "foo, bar_tuple"
+                    # we're in a "foo, (bar1, bar2, ...)"; make it "foo, bar_tuple"
                     return extract_alpha_prefix(results[0][1]) + "_tuple"
             else: # just name
                 ret.append(sanitize_ident(token_name, is_clr))
@@ -271,7 +271,7 @@
             if len(token) == 3: # name with value; little sense, but can happen in a deeply nested optional
                 ret.append(sanitize_ident(token_name, is_clr) + "=" + sanitize_value(token[2]))
             elif token_name == '...':
-            # we're in a "foo, [bar, ...]"; make it "foo, *bar"
+                # we're in a "foo, [bar, ...]"; make it "foo, *bar"
                 return ["*" + extract_alpha_prefix(
                     results[1][1])] # we must return a seq; [1] is first simple, [1][1] is its name
             else: # just name
@@ -531,7 +531,7 @@
         if not methods:
             bases = p_class.__bases__
             if len(bases) == 1 and p_name in dir(bases[0]):
-            # skip inherited methods
+                # skip inherited methods
                 return None, None
             return p_name + '(*args)', 'cannot find CLR method'
 
@@ -542,3 +542,31 @@
     if not methods[0].IsStatic:
         params = ['self'] + params
     return build_signature(p_name, params), None
+
+def build_output_name(dirname, qualified_name):
+    qualifiers = qualified_name.split(".")
+    if dirname and not dirname.endswith("/") and not dirname.endswith("\\"):
+        dirname += os.path.sep # "a -> a/"
+    for pathindex in range(len(qualifiers) - 1): # create dirs for all qualifiers but last
+        subdirname = dirname + os.path.sep.join(qualifiers[0: pathindex + 1])
+        if not os.path.isdir(subdirname):
+            action("creating subdir %r", subdirname)
+            os.makedirs(subdirname)
+        init_py = os.path.join(subdirname, "__init__.py")
+        if os.path.isfile(subdirname + ".py"):
+            os.rename(subdirname + ".py", init_py)
+        elif not os.path.isfile(init_py):
+            init = fopen(init_py, "w")
+            init.close()
+    target_name = dirname + os.path.sep.join(qualifiers)
+    if os.path.isdir(target_name):
+        fname = os.path.join(target_name, "__init__.py")
+    else:
+        fname = target_name + ".py"
+
+    dirname = os.path.dirname(fname)
+
+    if not os.path.isdir(dirname):
+        os.makedirs(dirname)
+
+    return fname
diff --git a/python/helpers/tools/stdlib_packages.txt b/python/helpers/tools/stdlib_packages.txt
index 619651eb..2ee4b5d 100644
--- a/python/helpers/tools/stdlib_packages.txt
+++ b/python/helpers/tools/stdlib_packages.txt
@@ -6,6 +6,7 @@
 array
 ast
 asynchat
+asyncio
 asyncore
 atexit
 audiodev
@@ -68,6 +69,8 @@
 dummy_threading
 email
 encodings
+ensurepip
+enum
 errno
 exceptions
 fcntl
@@ -150,6 +153,7 @@
 os2emxpath
 ossaudiodev
 parser
+pathlib
 pdb
 pickle
 pickletools
@@ -194,6 +198,7 @@
 runpy
 sched
 select
+selectors
 sets
 sgmllib
 sha
@@ -219,6 +224,7 @@
 ssl
 stat
 statcache
+statistics
 statvfs
 string
 StringIO
@@ -254,6 +260,7 @@
 tokenize
 trace
 traceback
+tracemalloc
 tty
 turtle
 turtledemo
diff --git a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
index e1084e8..6bad8d1 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/PyClass.java
@@ -136,11 +136,13 @@
   /**
    * Finds a property with the specified name in the class or one of its ancestors.
    *
+   *
    * @param name of the property
+   * @param inherited
    * @return descriptor of property accessors, or null if such property does not exist.
    */
   @Nullable
-  Property findProperty(@NotNull String name);
+  Property findProperty(@NotNull String name, boolean inherited);
 
   /**
    * Apply a processor to every method, looking at superclasses in method resolution order as needed.
diff --git a/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java b/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
index 38a0ee6..b4e5be8 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/impl/PyTypeProvider.java
@@ -30,7 +30,7 @@
   ExtensionPointName<PyTypeProvider> EP_NAME = ExtensionPointName.create("Pythonid.typeProvider");
 
   @Nullable
-  PyType getReferenceExpressionType(PyReferenceExpression referenceExpression, TypeEvalContext context);
+  PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context);
 
   @Nullable
   PyType getReferenceType(@NotNull PsiElement referenceTarget, TypeEvalContext context, @Nullable PsiElement anchor);
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyOverridingAncestorsClassMembersProvider.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyOverridingAncestorsClassMembersProvider.java
new file mode 100644
index 0000000..07b5309
--- /dev/null
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyOverridingAncestorsClassMembersProvider.java
@@ -0,0 +1,22 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.psi.types;
+
+/**
+ * @author vlan
+ */
+public interface PyOverridingAncestorsClassMembersProvider extends PyClassMembersProvider {
+}
diff --git a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
index dc20bad..0792b50 100644
--- a/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
+++ b/python/psi-api/src/com/jetbrains/python/psi/types/PyTypeProviderBase.java
@@ -80,7 +80,7 @@
   };
 
   @Override
-  public PyType getReferenceExpressionType(PyReferenceExpression referenceExpression, TypeEvalContext context) {
+  public PyType getReferenceExpressionType(@NotNull PyReferenceExpression referenceExpression, @NotNull TypeEvalContext context) {
     return null;
   }
 
diff --git a/python/src/META-INF/python-core.xml b/python/src/META-INF/python-core.xml
index f11f009..708a686 100644
--- a/python/src/META-INF/python-core.xml
+++ b/python/src/META-INF/python-core.xml
@@ -76,7 +76,7 @@
     <applicationService serviceInterface="com.jetbrains.python.module.PyModuleService"
                         serviceImplementation="com.jetbrains.python.module.PyModuleServiceImpl"/>
 
-    <typedHandler implementation="com.jetbrains.python.codeInsight.KeywordTypedHandler" id="pyCommaAfterKwd"/>
+    <typedHandler implementation="com.jetbrains.python.codeInsight.PyKeywordTypedHandler" id="pyCommaAfterKwd"/>
     <typedHandler implementation="com.jetbrains.python.codeInsight.PyMethodNameTypedHandler" id="pyMethodNameTypedHandler"/>
     <typedHandler implementation="com.jetbrains.python.editor.PythonSpaceHandler"/>
 
@@ -364,6 +364,8 @@
 
     <applicationService serviceInterface="com.jetbrains.python.codeInsight.PyCodeInsightSettings"
                         serviceImplementation="com.jetbrains.python.codeInsight.PyCodeInsightSettings"/>
+    <applicationService serviceInterface="com.jetbrains.python.testing.PyTestFrameworkService"
+                        serviceImplementation="com.jetbrains.python.testing.PyTestFrameworkService"/>
     <autoImportOptionsProvider instance="com.jetbrains.python.codeInsight.imports.PyAutoImportOptions"/>
 
     <defaultLiveTemplatesProvider implementation="com.jetbrains.python.codeInsight.liveTemplates.PyDefaultLiveTemplatesProvider"/>
diff --git a/python/src/com/jetbrains/python/codeInsight/KeywordTypedHandler.java b/python/src/com/jetbrains/python/codeInsight/PyKeywordTypedHandler.java
similarity index 94%
rename from python/src/com/jetbrains/python/codeInsight/KeywordTypedHandler.java
rename to python/src/com/jetbrains/python/codeInsight/PyKeywordTypedHandler.java
index 5e3e6ca..3bf094d 100644
--- a/python/src/com/jetbrains/python/codeInsight/KeywordTypedHandler.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyKeywordTypedHandler.java
@@ -30,7 +30,7 @@
  * User: dcheryasov
  * Date: May 29, 2009 4:42:03 AM
  */
-public class KeywordTypedHandler extends TypedHandlerDelegate {
+public class PyKeywordTypedHandler extends TypedHandlerDelegate {
   @Override
   public Result beforeCharTyped(char character, Project project, Editor editor, PsiFile file, FileType fileType) {
     if (!(fileType instanceof PythonFileType)) return Result.CONTINUE; // else we'd mess up with other file types!
@@ -51,7 +51,7 @@
         editor.getCaretModel().moveToOffset(offset + 1); // overtype, that is, jump over
         return Result.STOP;
       }
-      UnindentingInsertHandler.unindentAsNeeded(project, editor, file);
+      PyUnindentingInsertHandler.unindentAsNeeded(project, editor, file);
     }
 
     return Result.CONTINUE; // the default
diff --git a/python/src/com/jetbrains/python/codeInsight/PyKeywords.java b/python/src/com/jetbrains/python/codeInsight/PyKeywords.java
new file mode 100644
index 0000000..458715f
--- /dev/null
+++ b/python/src/com/jetbrains/python/codeInsight/PyKeywords.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2014 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.codeInsight;
+
+/**
+ * @author traff
+ */
+public class PyKeywords {
+  public static final String DEF = "def";
+  public static final String CLASS = "class";
+  
+  public static final String IF = "if";
+  public static final String ELSE = "else";
+  public static final String ELIF = "elif";
+
+  public static final String TRY = "try";
+  public static final String EXCEPT = "except";
+  public static final String FINALLY = "finally";
+  
+  public static final String WHILE = "while";
+
+  public static final String FOR = "for";
+  public static final String WITH = "with";
+  public static final String AS = "as";
+  
+  public static final String ASSERT = "assert";
+  public static final String DEL = "del";
+  public static final String EXEC = "exec";
+  public static final String FROM = "from";
+  public static final String IMPORT = "import";
+  public static final String RAISE = "raise";
+  public static final String PRINT = "print";
+  public static final String BREAK = "break";
+  public static final String CONTINUE = "continue";
+  public static final String GLOBAL = "global";
+  public static final String RETURN = "return";
+  public static final String YIELD = "yield";
+  public static final String NONLOCAL = "nonlocal";
+  
+  public static final String AND = "and";
+  public static final String OR = "or";
+  public static final String IS = "is";
+  public static final String IN = "in";
+  public static final String NOT = "not";
+  
+  public static final String LAMBDA = "lambda";
+  
+  public static final String TRUE = "True";
+  public static final String FALSE = "False";
+  public static final String NONE = "None";
+}
diff --git a/python/src/com/jetbrains/python/codeInsight/UnindentingInsertHandler.java b/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java
similarity index 71%
rename from python/src/com/jetbrains/python/codeInsight/UnindentingInsertHandler.java
rename to python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java
index cd29026..c6a69d7 100644
--- a/python/src/com/jetbrains/python/codeInsight/UnindentingInsertHandler.java
+++ b/python/src/com/jetbrains/python/codeInsight/PyUnindentingInsertHandler.java
@@ -34,10 +34,10 @@
  * User: dcheryasov
  * Date: Mar 2, 2010 6:48:40 PM
  */
-public class UnindentingInsertHandler implements InsertHandler<PythonLookupElement> {
-  public final static UnindentingInsertHandler INSTANCE = new UnindentingInsertHandler();
+public class PyUnindentingInsertHandler implements InsertHandler<PythonLookupElement> {
+  public final static PyUnindentingInsertHandler INSTANCE = new PyUnindentingInsertHandler();
 
-  private UnindentingInsertHandler() {
+  private PyUnindentingInsertHandler() {
   }
 
   public void handleInsert(InsertionContext context, PythonLookupElement item) {
@@ -46,6 +46,7 @@
 
   /**
    * Unindent current line to be flush with a starting part, detecting the part if necessary.
+   *
    * @param project
    * @param editor
    * @param file
@@ -56,7 +57,9 @@
     final Document document = editor.getDocument();
     int offset = editor.getCaretModel().getOffset();
     CharSequence text = document.getCharsSequence();
-    if (offset >= text.length()) offset = text.length() - 1;
+    if (offset >= text.length()) {
+      offset = text.length() - 1;
+    }
 
     int line_start_offset = document.getLineStartOffset(document.getLineNumber(offset));
     int nonspace_offset = findBeginning(line_start_offset, text);
@@ -64,26 +67,29 @@
 
     Class<? extends PsiElement> parentClass = null;
 
-    int last_offset = nonspace_offset + "finally".length(); // the longest of all
+    int last_offset = nonspace_offset + PyKeywords.FINALLY.length(); // the longest of all
     if (last_offset > offset) last_offset = offset;
     int local_length = last_offset - nonspace_offset + 1;
     if (local_length > 0) {
-      String piece = text.subSequence(nonspace_offset, last_offset+1).toString();
-      final int else_len = "else".length();
+      String piece = text.subSequence(nonspace_offset, last_offset + 1).toString();
+      final int else_len = PyKeywords.ELSE.length();
       if (local_length >= else_len) {
-        if ((piece.startsWith("else") || piece.startsWith("elif")) && (else_len == piece.length() || piece.charAt(else_len) < 'a' || piece.charAt(else_len) > 'z')) {
+        if ((piece.startsWith(PyKeywords.ELSE) || piece.startsWith(PyKeywords.ELIF)) &&
+            (else_len == piece.length() || piece.charAt(else_len) < 'a' || piece.charAt(else_len) > 'z')) {
           parentClass = PyStatementWithElse.class;
         }
       }
-      final int except_len = "except".length();
+      final int except_len = PyKeywords.EXCEPT.length();
       if (local_length >= except_len) {
-        if (piece.startsWith("except") && (except_len == piece.length() || piece.charAt(except_len) < 'a' || piece.charAt(except_len) > 'z')) {
+        if (piece.startsWith(PyKeywords.EXCEPT) &&
+            (except_len == piece.length() || piece.charAt(except_len) < 'a' || piece.charAt(except_len) > 'z')) {
           parentClass = PyTryExceptStatement.class;
         }
       }
-      final int finally_len = "finally".length();
+      final int finally_len = PyKeywords.FINALLY.length();
       if (local_length >= finally_len) {
-        if (piece.startsWith("finally") && (finally_len == piece.length() || piece.charAt(finally_len) < 'a' || piece.charAt(finally_len) > 'z')) {
+        if (piece.startsWith(PyKeywords.FINALLY) &&
+            (finally_len == piece.length() || piece.charAt(finally_len) < 'a' || piece.charAt(finally_len) > 'z')) {
           parentClass = PyTryExceptStatement.class;
         }
       }
@@ -94,14 +100,17 @@
 
     PsiDocumentManager.getInstance(project).commitDocument(document); // reparse
 
-    PsiElement token = file.findElementAt(offset-2); // -1 is our ':'; -2 is even safer.
+    PsiElement token = file.findElementAt(offset - 2); // -1 is our ':'; -2 is even safer.
     PsiElement outer = PsiTreeUtil.getParentOfType(token, parentClass);
     if (outer != null) {
       int outer_offset = outer.getTextOffset();
       int outer_indent = outer_offset - document.getLineStartOffset(document.getLineNumber(outer_offset));
       assert outer_indent >= 0;
       int current_indent = nonspace_offset - line_start_offset;
-      EditorActionUtil.indentLine(project, editor, document.getLineNumber(offset), outer_indent - current_indent);
+      int indent = outer_indent - current_indent;
+      EditorActionUtil.indentLine(project, editor, document.getLineNumber(offset), editor.getSettings().isUseTabCharacter(project)
+                                                                                   ? indent * editor.getSettings().getTabSize(project)
+                                                                                   : indent);
       return true;
     }
     return false;
diff --git a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
index 44ef899..6d72024 100644
--- a/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
+++ b/python/src/com/jetbrains/python/codeInsight/completion/PyKeywordCompletionContributor.java
@@ -33,7 +33,8 @@
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.PyTokenTypes;
 import com.jetbrains.python.PythonLanguage;
-import com.jetbrains.python.codeInsight.UnindentingInsertHandler;
+import com.jetbrains.python.codeInsight.PyKeywords;
+import com.jetbrains.python.codeInsight.PyUnindentingInsertHandler;
 import com.jetbrains.python.documentation.doctest.PyDocstringFile;
 import com.jetbrains.python.psi.*;
 import org.jetbrains.annotations.NonNls;
@@ -286,9 +287,9 @@
     psiElement()
       .inside(PyConditionalStatementPart.class)
       .andOr(
-        psiElement().afterLeaf(psiElement().withText("if")),
-        psiElement().afterLeaf(psiElement().withText("elif")),
-        psiElement().afterLeaf(psiElement().withText("while"))
+        psiElement().afterLeaf(psiElement().withText(PyKeywords.IF)),
+        psiElement().afterLeaf(psiElement().withText(PyKeywords.ELIF)),
+        psiElement().afterLeaf(psiElement().withText(PyKeywords.WHILE))
       );
 
   private static final PsiElementPattern.Capture<PsiElement> IN_IMPORT_STMT =
@@ -378,8 +379,8 @@
         protected void addCompletions(
           @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result
         ) {
-          putKeywords(result, TailType.NONE, "def", "class", "for", "if", "while", "with");
-          putKeywords(result, TailType.CASE_COLON, "try");
+          putKeywords(result, TailType.NONE, PyKeywords.DEF, PyKeywords.CLASS, PyKeywords.FOR, PyKeywords.IF, PyKeywords.WHILE, PyKeywords.WITH);
+          putKeywords(result, TailType.CASE_COLON, PyKeywords.TRY);
         }
       }
     );
@@ -402,13 +403,13 @@
         protected void addCompletions(
           @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result
         ) {
-          putKeywords(result, TailType.SPACE, "assert", "del", "exec", "from", "import", "raise");
+          putKeywords(result, TailType.SPACE, PyKeywords.ASSERT, PyKeywords.DEL, PyKeywords.EXEC, PyKeywords.FROM, PyKeywords.IMPORT, PyKeywords.RAISE);
           putKeywords(result, TailType.NONE, PyNames.PASS);
         }
       }
     );
 
-    extend(CompletionType.BASIC, inStatement.andNot(PY3K), new PyKeywordCompletionProvider(TailType.SPACE, "print"));
+    extend(CompletionType.BASIC, inStatement.andNot(PY3K), new PyKeywordCompletionProvider(TailType.SPACE, PyKeywords.PRINT));
   }
 
   private void addBreak() {
@@ -421,7 +422,7 @@
       .andNot(IN_ARG_LIST)
       .and(IN_LOOP)
       ,
-      new PyKeywordCompletionProvider(TailType.NONE, "break")
+      new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.BREAK)
     );
   }
 
@@ -436,7 +437,7 @@
       .andNot(IN_FINALLY_NO_LOOP)
       .and(IN_LOOP)
       ,
-      new PyKeywordCompletionProvider(TailType.NONE, "continue")
+      new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.CONTINUE)
     );
   }
 
@@ -448,7 +449,7 @@
       .and(IN_BEGIN_STMT)
       .andNot(AFTER_QUALIFIER)
       ,
-      new PyKeywordCompletionProvider("global", "return", "yield")
+      new PyKeywordCompletionProvider(PyKeywords.GLOBAL, PyKeywords.RETURN, PyKeywords.YIELD)
     );
 
     extend(
@@ -459,7 +460,7 @@
       .and(PY3K)
       .andNot(AFTER_QUALIFIER)
       ,
-      new PyKeywordCompletionProvider("nonlocal")
+      new PyKeywordCompletionProvider(PyKeywords.NONLOCAL)
     );
   }
 
@@ -471,7 +472,7 @@
       .andOr(IN_IF_BODY, AFTER_IF)
       .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
       ,
-      new PyKeywordCompletionProvider(TailType.NONE, UnindentingInsertHandler.INSTANCE, "elif"));
+      new PyKeywordCompletionProvider(TailType.NONE, PyUnindentingInsertHandler.INSTANCE, PyKeywords.ELIF));
   }
 
   private void addWithinTry() {
@@ -487,8 +488,8 @@
         protected void addCompletions(
           @NotNull final CompletionParameters parameters, final ProcessingContext context, @NotNull final CompletionResultSet result
         ) {
-          putKeyword("except", UnindentingInsertHandler.INSTANCE, TailType.NONE, result);
-          putKeyword("finally", UnindentingInsertHandler.INSTANCE, TailType.CASE_COLON, result);
+          putKeyword(PyKeywords.EXCEPT, PyUnindentingInsertHandler.INSTANCE, TailType.NONE, result);
+          putKeyword(PyKeywords.FINALLY, PyUnindentingInsertHandler.INSTANCE, TailType.CASE_COLON, result);
         }
       }
     );
@@ -502,7 +503,7 @@
       .andOr(IN_COND_STMT, IN_EXCEPT_BODY, AFTER_COND_STMT_NO_ELSE, AFTER_LOOP_NO_ELSE, AFTER_EXCEPT)
       .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
       ,
-      new PyKeywordCompletionProvider(TailType.CASE_COLON, UnindentingInsertHandler.INSTANCE, "else"));
+      new PyKeywordCompletionProvider(TailType.CASE_COLON, PyUnindentingInsertHandler.INSTANCE, PyKeywords.ELSE));
   }
 
   private void addInfixOperators() {
@@ -516,7 +517,7 @@
       .andNot(AFTER_QUALIFIER).
         andNot(IN_STRING_LITERAL).and(IN_BEGIN_STMT)
       ,
-      new PyKeywordCompletionProvider("and", "or", "is", "in")
+      new PyKeywordCompletionProvider(PyKeywords.AND, PyKeywords.OR, PyKeywords.IS, PyKeywords.IN)
     );
   }
 
@@ -530,7 +531,7 @@
       .andNot(IN_FUNCTION_HEADER)
       .andNot(AFTER_QUALIFIER).andNot(IN_STRING_LITERAL)
       ,
-      new PyKeywordCompletionProvider("not", "lambda")
+      new PyKeywordCompletionProvider(PyKeywords.NOT, PyKeywords.LAMBDA)
     );
   }
 
@@ -545,7 +546,7 @@
       .andNot(AFTER_QUALIFIER)
       .andNot(IN_FUNCTION_HEADER)
       ,
-      new PyKeywordCompletionProvider(TailType.NONE, "True", "False", "None")
+      new PyKeywordCompletionProvider(TailType.NONE, PyKeywords.TRUE, PyKeywords.FALSE, PyKeywords.NONE)
     );
   }
 
@@ -556,7 +557,7 @@
       .andOr(IN_IMPORT_AFTER_REF, IN_WITH_AFTER_REF, IN_EXCEPT_AFTER_REF)
       .andNot(AFTER_QUALIFIER)
       ,
-      new PyKeywordCompletionProvider("as")
+      new PyKeywordCompletionProvider(PyKeywords.AS)
     );
   }
 
@@ -567,7 +568,7 @@
       .and(IN_FROM_IMPORT_AFTER_REF)
       .andNot(AFTER_QUALIFIER)
       ,
-      new PyKeywordCompletionProvider("import")
+      new PyKeywordCompletionProvider(PyKeywords.IMPORT)
     );
   }
 
@@ -603,9 +604,9 @@
       .withLanguage(PythonLanguage.getInstance())
       .afterLeafSkipping(psiElement().whitespace(),
                          psiElement().inside(psiElement(PyConditionalExpression.class))
-                           .and(psiElement().afterLeaf("if")))
+                           .and(psiElement().afterLeaf(PyKeywords.IF)))
       ,
-      new PyKeywordCompletionProvider(TailType.SPACE, "else"));
+      new PyKeywordCompletionProvider(TailType.SPACE, PyKeywords.ELSE));
   }
 
   private void addRaiseFrom() {
@@ -614,7 +615,7 @@
              .withLanguage(PythonLanguage.getInstance())
              .and(PY3K)
              .afterLeaf(psiElement().inside(PyRaiseStatement.class)),
-           new PyKeywordCompletionProvider("from"));
+           new PyKeywordCompletionProvider(PyKeywords.FROM));
   }
 
   private void addYieldFrom() {
@@ -623,7 +624,7 @@
              .withLanguage(PythonLanguage.getInstance())
              .and(PY3K)
              .afterLeaf(psiElement().withElementType(PyTokenTypes.YIELD_KEYWORD)),
-           new PyKeywordCompletionProvider("from"));
+           new PyKeywordCompletionProvider(PyKeywords.FROM));
   }
 
   public PyKeywordCompletionContributor() {
@@ -654,14 +655,14 @@
              .withLanguage(PythonLanguage.getInstance())
              .inside(psiElement(PySequenceExpression.class))
              .andNot(psiElement().afterLeaf(or(psiElement(PyTokenTypes.LBRACE), psiElement(PyTokenTypes.LBRACKET), psiElement(PyTokenTypes.LPAR)))),
-           new PyKeywordCompletionProvider("for"));
+           new PyKeywordCompletionProvider(PyKeywords.FOR));
   }
 
   private void addInToFor() {
     extend(CompletionType.BASIC,
            psiElement()
              .withLanguage(PythonLanguage.getInstance())
-             .and(psiElement()).afterLeaf(psiElement().afterLeaf("for")),
+             .and(psiElement()).afterLeaf(psiElement().afterLeaf(PyKeywords.FOR)),
            new PyKeywordCompletionProvider("in"));
 
   }
diff --git a/python/src/com/jetbrains/python/codeInsight/intentions/ImportToggleAliasIntention.java b/python/src/com/jetbrains/python/codeInsight/intentions/ImportToggleAliasIntention.java
index f9f1ee1..6b79d21 100644
--- a/python/src/com/jetbrains/python/codeInsight/intentions/ImportToggleAliasIntention.java
+++ b/python/src/com/jetbrains/python/codeInsight/intentions/ImportToggleAliasIntention.java
@@ -181,13 +181,16 @@
                 InjectedLanguageManager.getInstance(project).getInjectedPsiFiles(host);
               if (files != null) {
                 for (Pair<PsiElement, TextRange> pair : files) {
-                  final ScopeOwner scopeOwner = (ScopeOwner)pair.getFirst();
-                  PsiTreeUtil.processElements(scopeOwner, new PsiElementProcessor() {
-                    public boolean execute(@NotNull PsiElement element) {
-                      getReferences(element);
-                      return true;
-                    }
-                  });
+                  final PsiElement first = pair.getFirst();
+                  if (first instanceof ScopeOwner) {
+                    final ScopeOwner scopeOwner = (ScopeOwner)first;
+                    PsiTreeUtil.processElements(scopeOwner, new PsiElementProcessor() {
+                      public boolean execute(@NotNull PsiElement element) {
+                        getReferences(element);
+                        return true;
+                      }
+                    });
+                  }
                 }
               }
             }
diff --git a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
index cf6b9ef..9e2989e 100644
--- a/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/stdlib/PyStdlibTypeProvider.java
@@ -37,7 +37,8 @@
  * @author yole
  */
 public class PyStdlibTypeProvider extends PyTypeProviderBase {
-  private static final Set<String> OPEN_FUNCTIONS = ImmutableSet.of("__builtin__.open", "io.open", "os.fdopen");
+  private static final Set<String> OPEN_FUNCTIONS = ImmutableSet.of("__builtin__.open", "io.open", "os.fdopen",
+                                                                    "pathlib.Path.open");
   private static final String BINARY_FILE_TYPE = "io.FileIO[bytes]";
   private static final String TEXT_FILE_TYPE = "io.TextIOWrapper[unicode]";
 
@@ -134,7 +135,10 @@
     for (Map.Entry<PyExpression, PyNamedParameter> entry : arguments.entrySet()) {
       final PyNamedParameter parameter = entry.getValue();
       if ("mode".equals(parameter.getName())) {
-        final PyExpression argument = entry.getKey();
+        PyExpression argument = entry.getKey();
+        if (argument instanceof PyKeywordArgument) {
+          argument = ((PyKeywordArgument)argument).getValueExpression();
+        }
         if (argument instanceof PyStringLiteralExpression) {
           mode = ((PyStringLiteralExpression)argument).getStringValue();
           break;
diff --git a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
index a35d8fd..5ac7fc1 100644
--- a/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
+++ b/python/src/com/jetbrains/python/codeInsight/userSkeletons/PyUserSkeletonsClassMembersProvider.java
@@ -22,6 +22,7 @@
 import com.jetbrains.python.psi.PyTargetExpression;
 import com.jetbrains.python.psi.types.PyClassMembersProviderBase;
 import com.jetbrains.python.psi.types.PyClassType;
+import com.jetbrains.python.psi.types.PyOverridingAncestorsClassMembersProvider;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -33,7 +34,7 @@
 /**
  * @author vlan
  */
-public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase {
+public class PyUserSkeletonsClassMembersProvider extends PyClassMembersProviderBase implements PyOverridingAncestorsClassMembersProvider {
   @NotNull
   @Override
   public Collection<PyDynamicMember> getMembers(@NotNull PyClassType classType, PsiElement location) {
diff --git a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
index 947b3c9..c7b9ceb 100644
--- a/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
+++ b/python/src/com/jetbrains/python/console/PydevConsoleRunner.java
@@ -50,6 +50,7 @@
 import com.intellij.openapi.util.io.StreamUtil;
 import com.intellij.openapi.vfs.CharsetToolkit;
 import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.encoding.EncodingManager;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.impl.source.tree.FileElement;
@@ -61,16 +62,11 @@
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.net.NetUtils;
 import com.intellij.util.ui.UIUtil;
-import com.intellij.xdebugger.impl.frame.XStandaloneVariablesView;
 import com.jetbrains.python.PythonHelpersLocator;
 import com.jetbrains.python.console.completion.PydevConsoleElement;
 import com.jetbrains.python.console.parsing.PythonConsoleData;
 import com.jetbrains.python.console.pydev.ConsoleCommunication;
-import com.jetbrains.python.console.pydev.ConsoleCommunicationListener;
-import com.jetbrains.python.debugger.PyDebuggerEditorsProvider;
 import com.jetbrains.python.debugger.PySourcePosition;
-import com.jetbrains.python.debugger.PyStackFrame;
-import com.jetbrains.python.debugger.PyStackFrameInfo;
 import com.jetbrains.python.remote.PythonRemoteInterpreterManager;
 import com.jetbrains.python.run.ProcessRunner;
 import com.jetbrains.python.run.PythonCommandLineState;
@@ -84,8 +80,8 @@
 import java.awt.event.KeyEvent;
 import java.io.File;
 import java.io.IOException;
+import java.nio.charset.Charset;
 import java.util.*;
-import java.util.List;
 
 import static com.jetbrains.python.sdk.PythonEnvUtil.setPythonIOEncoding;
 import static com.jetbrains.python.sdk.PythonEnvUtil.setPythonUnbuffered;
@@ -134,7 +130,11 @@
   }
 
   public static Map<String, String> addDefaultEnvironments(Sdk sdk, Map<String, String> envs) {
-    setPythonIOEncoding(setPythonUnbuffered(envs), "utf-8");
+    Charset defaultCharset = EncodingManager.getInstance().getDefaultCharset();
+
+    final String encoding = defaultCharset != null ? defaultCharset.name() : "utf-8";
+    setPythonIOEncoding(setPythonUnbuffered(envs), encoding);
+    
     PythonSdkFlavor.initPythonPath(envs, true, PythonCommandLineState.getAddedPaths(sdk));
     return envs;
   }
@@ -304,7 +304,8 @@
                                                                                                      PYDEV_PYDEVCONSOLE_PY)
                                                                                               .getPath(),
                                                                                             PySourcePosition.isWindowsPath(
-                                                                                              data.getInterpreterPath())));
+                                                                                              data.getInterpreterPath())
+    ));
     commandLine.getParametersList().set(2, "0");
     commandLine.getParametersList().set(3, "0");
 
@@ -570,7 +571,7 @@
       new PydevConsoleExecuteActionHandler(getConsoleView(), getProcessHandler(), myPydevConsoleCommunication);
     myConsoleExecuteActionHandler.setEnabled(false);
     myHistoryController = new ConsoleHistoryController(myConsoleType.getTypeId(), "", getLanguageConsole(),
-                                 myConsoleExecuteActionHandler.getConsoleHistoryModel());
+                                                       myConsoleExecuteActionHandler.getConsoleHistoryModel());
     myHistoryController.install();
     return myConsoleExecuteActionHandler;
   }
diff --git a/python/src/com/jetbrains/python/documentation/DocStringParameterReference.java b/python/src/com/jetbrains/python/documentation/DocStringParameterReference.java
index 9e4e63d..5f7a2ee 100644
--- a/python/src/com/jetbrains/python/documentation/DocStringParameterReference.java
+++ b/python/src/com/jetbrains/python/documentation/DocStringParameterReference.java
@@ -38,9 +38,9 @@
  * @author yole
  */
 public class DocStringParameterReference extends PsiReferenceBase<PsiElement> implements PsiReferenceEx {
-  private final String myType;
+  private final StructuredDocStringBase.ReferenceType myType;
 
-  public DocStringParameterReference(PsiElement element, TextRange range, String refType) {
+  public DocStringParameterReference(PsiElement element, TextRange range, StructuredDocStringBase.ReferenceType refType) {
     super(element, range);
     myType = refType;
   }
@@ -55,26 +55,42 @@
       final PyFunction init = ((PyClass)owner).findMethodByName(PyNames.INIT, false);
       if (init != null) {
         PsiElement element = resolveParameter(init);
-        if (element == null)
-          element = resolveClassVariable(owner);
+        if (element == null && (myType.equals(StructuredDocStringBase.ReferenceType.CLASS_VARIABLE) ||
+                                myType.equals(StructuredDocStringBase.ReferenceType.PARAMETER_TYPE)))
+          element = resolveClassVariable((PyClass)owner);
+        if (element == null && (myType.equals(StructuredDocStringBase.ReferenceType.INSTANCE_VARIABLE) ||
+                                myType.equals(StructuredDocStringBase.ReferenceType.PARAMETER_TYPE)))
+          element = resolveInstanceVariable((PyClass)owner);
         return element;
       }
       else {
-        return resolveClassVariable(owner);
+        if (myType.equals(StructuredDocStringBase.ReferenceType.CLASS_VARIABLE) ||
+                                myType.equals(StructuredDocStringBase.ReferenceType.PARAMETER_TYPE))
+          return resolveClassVariable((PyClass)owner);
+        if (myType.equals(StructuredDocStringBase.ReferenceType.INSTANCE_VARIABLE) ||
+                                myType.equals(StructuredDocStringBase.ReferenceType.PARAMETER_TYPE))
+          return resolveInstanceVariable((PyClass)owner);
       }
     }
     return null;
   }
 
   @Nullable
-  private PsiElement resolveClassVariable(final PyDocStringOwner owner) {
-    final PyStatementList statementList = ((PyClass)owner).getStatementList();
-    for (PsiElement element : statementList.getChildren()) {
-      if (element instanceof PyAssignmentStatement) {
-        final PyExpression[] targets = ((PyAssignmentStatement)element).getTargets();
-        if (targets.length > 0 && targets[0].getText().equals(getCanonicalText()))
-          return targets[0];
-      }
+  private PsiElement resolveInstanceVariable(final PyClass owner) {
+    final List<PyTargetExpression> attributes = owner.getInstanceAttributes();
+    for (PyTargetExpression element : attributes) {
+      if (getCanonicalText().equals(element.getName()))
+        return element;
+    }
+    return null;
+  }
+
+  @Nullable
+  private PsiElement resolveClassVariable(@NotNull final PyClass owner) {
+    final List<PyTargetExpression> attributes = owner.getClassAttributes();
+    for (PyTargetExpression element : attributes) {
+      if (getCanonicalText().equals(element.getName()))
+        return element;
     }
     return null;
   }
@@ -123,7 +139,7 @@
     return ArrayUtil.EMPTY_OBJECT_ARRAY;
   }
   
-  public String getType() {
+  public StructuredDocStringBase.ReferenceType getType() {
     return myType;
   }
 
diff --git a/python/src/com/jetbrains/python/documentation/DocStringReferenceProvider.java b/python/src/com/jetbrains/python/documentation/DocStringReferenceProvider.java
index 2891726..d1d8033 100644
--- a/python/src/com/jetbrains/python/documentation/DocStringReferenceProvider.java
+++ b/python/src/com/jetbrains/python/documentation/DocStringReferenceProvider.java
@@ -61,16 +61,22 @@
         if (docString != null) {
           result.addAll(referencesFromNames(element, offset, docString,
                                             docString.getTagArguments(StructuredDocStringBase.PARAM_TAGS),
-                                            StructuredDocStringBase.PARAMETER));
+                                            StructuredDocStringBase.ReferenceType.PARAMETER));
           result.addAll(referencesFromNames(element, offset, docString,
                                             docString.getTagArguments(StructuredDocStringBase.PARAM_TYPE_TAGS),
-                                            StructuredDocStringBase.PARAMETER_TYPE));
+                                            StructuredDocStringBase.ReferenceType.PARAMETER_TYPE));
           result.addAll(referencesFromNames(element, offset, docString,
-                                            docString.getKeywordArgumentSubstrings(), StructuredDocStringBase.KEYWORD));
+                                            docString.getKeywordArgumentSubstrings(), StructuredDocStringBase.ReferenceType.KEYWORD));
 
           result.addAll(referencesFromNames(element, offset, docString,
-                                            docString.getTagArguments(StructuredDocStringBase.VARIABLE_TAGS),
-                                            StructuredDocStringBase.VARIABLE));
+                                            docString.getTagArguments("var"),
+                                            StructuredDocStringBase.ReferenceType.VARIABLE));
+          result.addAll(referencesFromNames(element, offset, docString,
+                                            docString.getTagArguments("cvar"),
+                                            StructuredDocStringBase.ReferenceType.CLASS_VARIABLE));
+          result.addAll(referencesFromNames(element, offset, docString,
+                                            docString.getTagArguments("ivar"),
+                                            StructuredDocStringBase.ReferenceType.INSTANCE_VARIABLE));
           result.addAll(returnTypes(element, docString, offset));
         }
         return result.toArray(new PsiReference[result.size()]);
@@ -94,7 +100,7 @@
                                                         int offset,
                                                         StructuredDocString docString,
                                                         List<Substring> paramNames,
-                                                        String refType) {
+                                                        StructuredDocStringBase.ReferenceType refType) {
     List<PsiReference> result = new ArrayList<PsiReference>();
     for (Substring name : paramNames) {
       final String s = name.toString();
@@ -102,7 +108,7 @@
         final TextRange range = name.getTextRange().shiftRight(offset);
         result.add(new DocStringParameterReference(element, range, refType));
       }
-      if (refType.equals(StructuredDocStringBase.PARAMETER_TYPE)) {
+      if (refType.equals(StructuredDocStringBase.ReferenceType.PARAMETER_TYPE)) {
         final Substring type = docString.getParamTypeSubstring(s);
         if (type != null) {
           result.addAll(parseTypeReferences(element, type, offset));
diff --git a/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java b/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java
index ec4becc..4c3432c 100644
--- a/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java
+++ b/python/src/com/jetbrains/python/documentation/PyDocumentationBuilder.java
@@ -95,7 +95,7 @@
             PyType type = context.getType(qual);
             if (type instanceof PyClassType) {
               cls = ((PyClassType)type).getPyClass();
-              Property property = cls.findProperty(elementName);
+              Property property = cls.findProperty(elementName, true);
               if (property != null) {
                 is_property = true;
                 final AccessDirection dir = AccessDirection.of((PyElement)outer);
diff --git a/python/src/com/jetbrains/python/documentation/StructuredDocStringBase.java b/python/src/com/jetbrains/python/documentation/StructuredDocStringBase.java
index 0e3d9e3..9f6cecb 100644
--- a/python/src/com/jetbrains/python/documentation/StructuredDocStringBase.java
+++ b/python/src/com/jetbrains/python/documentation/StructuredDocStringBase.java
@@ -50,11 +50,9 @@
   public static String[] RAISES_TAGS = new String[] { "raises", "raise", "except", "exception" };
   public static String[] RETURN_TAGS = new String[] { "return", "returns" };
 
-  public static String PARAMETER = "parameter";
+  public enum ReferenceType {PARAMETER, PARAMETER_TYPE, KEYWORD, VARIABLE, CLASS_VARIABLE, INSTANCE_VARIABLE}
+
   public static String TYPE = "type";
-  public static String PARAMETER_TYPE = "parameter_type";
-  public static String KEYWORD = "keyword";
-  public static String VARIABLE = "variable";
 
   protected StructuredDocStringBase(@NotNull String docStringText, String tagPrefix) {
     final Substring docString = new Substring(docStringText);
diff --git a/python/src/com/jetbrains/python/formatter/PyBlock.java b/python/src/com/jetbrains/python/formatter/PyBlock.java
index 2a7343d..8afd35e 100644
--- a/python/src/com/jetbrains/python/formatter/PyBlock.java
+++ b/python/src/com/jetbrains/python/formatter/PyBlock.java
@@ -153,7 +153,9 @@
     if (ourListElementTypes.contains(parentType)) {
       // wrapping in non-parenthesized tuple expression is not allowed (PY-1792)
       if ((parentType != PyElementTypes.TUPLE_EXPRESSION || grandparentType == PyElementTypes.PARENTHESIZED_EXPRESSION) &&
-          !ourBrackets.contains(childType) && childType != PyTokenTypes.COMMA && !isSliceOperand(child) /*&& !isSubscriptionOperand(child)*/) {
+          !ourBrackets.contains(childType) &&
+          childType != PyTokenTypes.COMMA &&
+          !isSliceOperand(child) /*&& !isSubscriptionOperand(child)*/) {
         wrap = Wrap.createWrap(WrapType.NORMAL, true);
       }
       if (needListAlignment(child) && !isEmptyList(_node.getPsi())) {
@@ -161,8 +163,9 @@
       }
     }
     else if (parentType == PyElementTypes.BINARY_EXPRESSION &&
-             (PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens().contains(childType) || PyTokenTypes.OPERATIONS.contains(childType))) {
-      if (isInControlStatement() ) {
+             (PythonDialectsTokenSetProvider.INSTANCE.getExpressionTokens().contains(childType) ||
+              PyTokenTypes.OPERATIONS.contains(childType))) {
+      if (isInControlStatement()) {
         PyParenthesizedExpression parens = PsiTreeUtil.getParentOfType(_node.getPsi(), PyParenthesizedExpression.class, true,
                                                                        PyStatementPart.class);
         childIndent = parens != null ? Indent.getNormalIndent() : Indent.getContinuationIndent();
@@ -196,7 +199,7 @@
       }
     }
     else if (parentType == PyElementTypes.DICT_LITERAL_EXPRESSION || parentType == PyElementTypes.SET_LITERAL_EXPRESSION ||
-      parentType == PyElementTypes.SET_COMP_EXPRESSION || parentType == PyElementTypes.DICT_COMP_EXPRESSION) {
+             parentType == PyElementTypes.SET_COMP_EXPRESSION || parentType == PyElementTypes.DICT_COMP_EXPRESSION) {
       if (childType == PyTokenTypes.RBRACE || !hasLineBreaksBefore(child, 1)) {
         childIndent = Indent.getNoneIndent();
       }
@@ -210,18 +213,22 @@
       }
     }
     else if (parentType == PyElementTypes.FROM_IMPORT_STATEMENT) {
-      if ((childType == PyElementTypes.IMPORT_ELEMENT || childType == PyTokenTypes.RPAR) &&
-          _node.findChildByType(PyTokenTypes.LPAR) != null) {
-        if (myContext.getPySettings().ALIGN_MULTILINE_IMPORTS) {
-          childAlignment = getAlignmentForChildren();
+      if (_node.findChildByType(PyTokenTypes.LPAR) != null) {
+        if (childType == PyElementTypes.IMPORT_ELEMENT) {
+          if (myContext.getPySettings().ALIGN_MULTILINE_IMPORTS) {
+            childAlignment = getAlignmentForChildren();
+          }
+          else {
+            childIndent = Indent.getNormalIndent();
+          }
         }
-        else {
-          childIndent = Indent.getNormalIndent();
+        if (childType == PyTokenTypes.RPAR) {
+          childIndent = Indent.getNoneIndent();
         }
       }
     }
     else if (parentType == PyElementTypes.KEY_VALUE_EXPRESSION) {
-      PyKeyValueExpression keyValue = (PyKeyValueExpression) _node.getPsi();
+      PyKeyValueExpression keyValue = (PyKeyValueExpression)_node.getPsi();
       if (keyValue != null && child.getPsi() == keyValue.getValue()) {
         childIndent = Indent.getNormalIndent();
       }
@@ -255,7 +262,7 @@
     while (prev != null && prev.getElementType() == TokenType.WHITE_SPACE) {
       if (prev.getText().contains("\\") && !childIndent.equals(Indent.getContinuationIndent()) &&
           !childIndent.equals(Indent.getContinuationIndent(true))) {
-        childIndent = Indent.getNormalIndent();
+        childIndent = isIndentNext(child) ? Indent.getContinuationIndent() : Indent.getNormalIndent();
         break;
       }
       prev = prev.getTreePrev();
@@ -264,9 +271,22 @@
     return new PyBlock(this, child, childAlignment, childIndent, wrap, myContext);
   }
 
+  private static boolean isIndentNext(ASTNode child) {
+    PsiElement psi = PsiTreeUtil.getParentOfType(child.getPsi(), PyStatement.class);
+
+    return psi instanceof PyIfStatement ||
+           psi instanceof PyForStatement ||
+           psi instanceof PyWithStatement ||
+           psi instanceof PyClass ||
+           psi instanceof PyFunction ||
+           psi instanceof PyTryExceptStatement ||
+           psi instanceof PyElsePart ||
+           psi instanceof PyIfPart;
+  }
+
   private static boolean isSubscriptionOperand(ASTNode child) {
     return child.getTreeParent().getElementType() == PyElementTypes.SUBSCRIPTION_EXPRESSION &&
-           child.getPsi() == ((PySubscriptionExpression) child.getTreeParent().getPsi()).getOperand();
+           child.getPsi() == ((PySubscriptionExpression)child.getTreeParent().getPsi()).getOperand();
   }
 
   private boolean isInControlStatement() {
@@ -285,10 +305,10 @@
 
   private static boolean isEmptyList(PsiElement psi) {
     if (psi instanceof PyDictLiteralExpression) {
-      return ((PyDictLiteralExpression) psi).getElements().length == 0;
+      return ((PyDictLiteralExpression)psi).getElements().length == 0;
     }
     if (psi instanceof PySequenceExpression) {
-      return ((PySequenceExpression) psi).getElements().length == 0;
+      return ((PySequenceExpression)psi).getElements().length == 0;
     }
     return false;
   }
@@ -322,7 +342,9 @@
     }
     if (PyTokenTypes.CLOSE_BRACES.contains(childType)) {
       ASTNode prevNonSpace = findPrevNonSpaceNode(child);
-      if (prevNonSpace != null && prevNonSpace.getElementType() == PyTokenTypes.COMMA && myContext.getMode() == FormattingMode.ADJUST_INDENT) {
+      if (prevNonSpace != null &&
+          prevNonSpace.getElementType() == PyTokenTypes.COMMA &&
+          myContext.getMode() == FormattingMode.ADJUST_INDENT) {
         return true;
       }
       return false;
@@ -358,7 +380,8 @@
   private static ASTNode findPrevNonSpaceNode(ASTNode node) {
     do {
       node = node.getTreePrev();
-    } while(node != null && (node.getElementType() == TokenType.WHITE_SPACE || PyTokenTypes.WHITESPACE.contains(node.getElementType())));
+    }
+    while (node != null && (node.getElementType() == TokenType.WHITE_SPACE || PyTokenTypes.WHITESPACE.contains(node.getElementType())));
     return node;
   }
 
@@ -372,7 +395,7 @@
     if (node != null && node.getElementType() == TokenType.WHITE_SPACE) {
       String prevNodeText = node.getText();
       int count = 0;
-      for(int i=0; i<prevNodeText.length(); i++) {
+      for (int i = 0; i < prevNodeText.length(); i++) {
         if (prevNodeText.charAt(i) == '\n') {
           count++;
           if (count == minCount) {
@@ -429,10 +452,32 @@
           return Spacing.createSpacing(0, 0, 1, true, myContext.getSettings().KEEP_BLANK_LINES_IN_CODE);
         }
       }
+
+      if ((node1.getElementType() == PyElementTypes.FUNCTION_DECLARATION || node1.getElementType() == PyElementTypes.CLASS_DECLARATION)
+          && _node.getElementType() instanceof PyFileElementType) {
+
+        if (psi2 instanceof PsiComment) {
+          final PsiElement psi3 = PsiTreeUtil.getNextSiblingOfType(psi2, PyElement.class);
+
+          if (psi3 != null) {
+            IElementType type3 = psi3.getNode().getElementType();
+
+            if (type3 == PyElementTypes.CLASS_DECLARATION || type3 == PyElementTypes.FUNCTION_DECLARATION) {
+              return getBlankLinesForOption(myContext.getPySettings().BLANK_LINES_AROUND_TOP_LEVEL_CLASSES_FUNCTIONS);
+            }
+          }
+        }
+      }
     }
     return myContext.getSpacingBuilder().getSpacing(this, child1, child2);
   }
 
+  private Spacing getBlankLinesForOption(final int option) {
+    int blankLines = option + 1;
+    return Spacing
+      .createSpacing(0, 0, blankLines, myContext.getSettings().KEEP_LINE_BREAKS, myContext.getSettings().KEEP_BLANK_LINES_IN_DECLARATIONS);
+  }
+
   private boolean needLineBreakInStatement() {
     PyStatement statement = PsiTreeUtil.getParentOfType(_node.getPsi(), PyStatement.class);
     if (statement != null) {
@@ -614,7 +659,7 @@
     }
 
     if (afterNode != null && afterNode.getElementType() == PyElementTypes.KEY_VALUE_EXPRESSION) {
-      PyKeyValueExpression keyValue = (PyKeyValueExpression) afterNode.getPsi();
+      PyKeyValueExpression keyValue = (PyKeyValueExpression)afterNode.getPsi();
       if (keyValue != null && keyValue.getValue() == null) {  // incomplete
         return Indent.getContinuationIndent();
       }
diff --git a/python/src/com/jetbrains/python/inspections/PyArgumentListInspection.java b/python/src/com/jetbrains/python/inspections/PyArgumentListInspection.java
index 97a5a36..6faea31 100644
--- a/python/src/com/jetbrains/python/inspections/PyArgumentListInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyArgumentListInspection.java
@@ -68,32 +68,29 @@
 
     @Override
     public void visitPyDecoratorList(final PyDecoratorList node) {
-      PyDecorator[] decos = node.getDecorators();
-      for (PyDecorator deco : decos) {
-        if (! deco.hasArgumentList()) {
-          // empty arglist; deco function must have a non-kwarg first arg
-          PyCallExpression.PyMarkedCallee mkfunc = deco.resolveCallee(resolveWithoutImplicits());
-          if (mkfunc != null && !mkfunc.isImplicitlyResolved()) {
-            Callable callable = mkfunc.getCallable();
-            int first_param_offset =  mkfunc.getImplicitOffset();
-            final List<PyParameter> params = PyUtil.getParameters(callable, myTypeEvalContext);
-            final PyNamedParameter alleged_first_param = params.size() < first_param_offset ?
-                                                         null : params.get(first_param_offset-1).getAsNamed();
-            if (alleged_first_param == null || alleged_first_param.isKeywordContainer()) {
-              // no parameters left to pass function implicitly, or wrong param type
-              registerProblem(deco, PyBundle.message("INSP.func.$0.lacks.first.arg", callable.getName())); // TODO: better names for anon lambdas
-            }
-            else {
-              // possible unfilled params
-              for (int i=first_param_offset; i < params.size(); i += 1) {
-                PyNamedParameter par = params.get(i).getAsNamed();
-                // param tuples, non-starred or non-default won't do
-                if (par == null || (! par.isKeywordContainer() && ! par.isPositionalContainer() && !par.hasDefaultValue())) {
-                  String par_name;
-                  if (par != null) par_name = par.getName();
-                  else par_name = "(...)"; // can't be bothered to find the first non-tuple inside it
-                  registerProblem(deco, PyBundle.message("INSP.parameter.$0.unfilled", par_name));
-                }
+      PyDecorator[] decorators = node.getDecorators();
+      for (PyDecorator deco : decorators) {
+        if (deco.hasArgumentList()) continue;
+        final PyCallExpression.PyMarkedCallee markedCallee = deco.resolveCallee(resolveWithoutImplicits());
+        if (markedCallee != null && !markedCallee.isImplicitlyResolved()) {
+          final Callable callable = markedCallee.getCallable();
+          int firstParamOffset =  markedCallee.getImplicitOffset();
+          final List<PyParameter> params = PyUtil.getParameters(callable, myTypeEvalContext);
+          final PyNamedParameter allegedFirstParam = params.size() < firstParamOffset ?
+                                                       null : params.get(firstParamOffset-1).getAsNamed();
+          if (allegedFirstParam == null || allegedFirstParam.isKeywordContainer()) {
+            // no parameters left to pass function implicitly, or wrong param type
+            registerProblem(deco, PyBundle.message("INSP.func.$0.lacks.first.arg", callable.getName())); // TODO: better names for anon lambdas
+          }
+          else { // possible unfilled params
+            for (int i = firstParamOffset; i < params.size(); i += 1) {
+              final PyParameter parameter = params.get(i);
+              if (parameter instanceof PySingleStarParameter) continue;
+              final PyNamedParameter par = parameter.getAsNamed();
+              // param tuples, non-starred or non-default won't do
+              if (par == null || (!par.isKeywordContainer() && !par.isPositionalContainer() &&!par.hasDefaultValue())) {
+                String parameterName = par != null ? par.getName() : "(...)";
+                registerProblem(deco, PyBundle.message("INSP.parameter.$0.unfilled", parameterName));
               }
             }
           }
diff --git a/python/src/com/jetbrains/python/inspections/PyAttributeOutsideInitInspection.java b/python/src/com/jetbrains/python/inspections/PyAttributeOutsideInitInspection.java
index c94ab8d..791a1b5 100644
--- a/python/src/com/jetbrains/python/inspections/PyAttributeOutsideInitInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyAttributeOutsideInitInspection.java
@@ -100,7 +100,7 @@
       for (Map.Entry<String, PyTargetExpression> attribute : attributes.entrySet()) {
         String attributeName = attribute.getKey();
         if (attributeName == null) continue;
-        final Property property = containingClass.findProperty(attributeName);
+        final Property property = containingClass.findProperty(attributeName, true);
         if (!attributesInInit.containsKey(attributeName) && property == null) {
           registerProblem(attribute.getValue(), PyBundle.message("INSP.attribute.$0.outside.init", attributeName),
                           new PyMoveAttributeToInitQuickFix());
diff --git a/python/src/com/jetbrains/python/inspections/PyPropertyAccessInspection.java b/python/src/com/jetbrains/python/inspections/PyPropertyAccessInspection.java
index 425c585..8e48067 100644
--- a/python/src/com/jetbrains/python/inspections/PyPropertyAccessInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyPropertyAccessInspection.java
@@ -86,7 +86,7 @@
               property = myPropertyCache.get(key);
             }
             else {
-              property = cls.findProperty(name);
+              property = cls.findProperty(name, true);
             }
             myPropertyCache.put(key, property); // we store nulls, too, to know that a property does not exist
             if (property != null) {
diff --git a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
index 4005b42..998530a 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnresolvedReferencesInspection.java
@@ -695,7 +695,7 @@
         if (overridesGetAttr(cls, myTypeEvalContext)) {
           return true;
         }
-        if (cls.findProperty(name) != null) {
+        if (cls.findProperty(name, true) != null) {
           return true;
         }
         if (PyUtil.hasUnresolvedAncestors(cls, myTypeEvalContext)) {
diff --git a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
index f770c5d..f788353 100644
--- a/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
+++ b/python/src/com/jetbrains/python/inspections/PyUnusedLocalInspectionVisitor.java
@@ -207,7 +207,8 @@
       owner.acceptChildren(new PyRecursiveElementVisitor(){
         @Override
         public void visitPyCallExpression(final PyCallExpression node) {
-          if ("locals".equals(node.getCallee().getName())){
+          final PyExpression callee = node.getCallee();
+          if (callee != null && "locals".equals(callee.getName())){
             throw new DontPerformException();
           }
           node.acceptChildren(this); // look at call expr in arguments
@@ -290,7 +291,7 @@
                 isEmpty = isEmptyFunction(func);
                 emptyFunctions.put(func, isEmpty);
               }
-              if (isEmpty) {
+              if (isEmpty && !mayBeField) {
                 continue;
               }
             }
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java
index e888add..89de355 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/AddFieldQuickFix.java
@@ -66,20 +66,18 @@
   @Nullable
   public static PsiElement appendToMethod(PyFunction init, Function<String, PyStatement> callback) {
     // add this field as the last stmt of the constructor
-    final PyStatementList stmt_list = init.getStatementList();
-    PyStatement[] stmts = stmt_list.getStatements(); // NOTE: rather wasteful, consider iterable stmt list
-    PyStatement last_stmt = null;
-    if (stmts.length > 0) last_stmt = stmts[stmts.length-1];
+    final PyStatementList statementList = init.getStatementList();
+    assert statementList != null;
     // name of 'self' may be different for fancier styles
     PyParameter[] params = init.getParameterList().getParameters();
-    String self_name = PyNames.CANONICAL_SELF;
+    String selfName = PyNames.CANONICAL_SELF;
     if (params.length > 0) {
-      self_name = params[0].getName();
+      selfName = params[0].getName();
     }
-    PyStatement new_stmt = callback.fun(self_name);
-    if (!FileModificationService.getInstance().preparePsiElementForWrite(stmt_list)) return null;
-    final PsiElement result = stmt_list.addAfter(new_stmt, last_stmt);
-    PyPsiUtils.removeRedundantPass(stmt_list);
+    PyStatement newStmt = callback.fun(selfName);
+    if (!FileModificationService.getInstance().preparePsiElementForWrite(statementList)) return null;
+    final PsiElement result = PyUtil.addElementToStatementList(newStmt, statementList, true);
+    PyPsiUtils.removeRedundantPass(statementList);
     return result;
   }
 
diff --git a/python/src/com/jetbrains/python/inspections/quickfix/AddGlobalQuickFix.java b/python/src/com/jetbrains/python/inspections/quickfix/AddGlobalQuickFix.java
index 349a911..9bf3df0 100644
--- a/python/src/com/jetbrains/python/inspections/quickfix/AddGlobalQuickFix.java
+++ b/python/src/com/jetbrains/python/inspections/quickfix/AddGlobalQuickFix.java
@@ -80,6 +80,7 @@
         statementList = ((PyFunction)owner).getStatementList();
         if (((PyFunction)owner).getDocStringExpression() != null) hasDocString = true;
       }
+      assert statementList != null;
       PyStatement first = statementList.getStatements()[0];
       if (hasDocString)
         first = statementList.getStatements()[1];
diff --git a/python/src/com/jetbrains/python/psi/PyUtil.java b/python/src/com/jetbrains/python/psi/PyUtil.java
index e939857..0cd2994 100644
--- a/python/src/com/jetbrains/python/psi/PyUtil.java
+++ b/python/src/com/jetbrains/python/psi/PyUtil.java
@@ -44,6 +44,7 @@
 import com.intellij.psi.stubs.StubElement;
 import com.intellij.psi.tree.TokenSet;
 import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.QualifiedName;
 import com.intellij.ui.awt.RelativePoint;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
@@ -60,7 +61,6 @@
 import com.jetbrains.python.codeInsight.stdlib.PyNamedTupleType;
 import com.jetbrains.python.psi.impl.PyBuiltinCache;
 import com.jetbrains.python.psi.impl.PyPsiUtils;
-import com.intellij.psi.util.QualifiedName;
 import com.jetbrains.python.psi.resolve.PyResolveContext;
 import com.jetbrains.python.psi.resolve.QualifiedResolveResult;
 import com.jetbrains.python.psi.types.*;
@@ -1313,13 +1313,31 @@
       final PyStatement[] statements = statementList.getStatements();
       if (toTheBeginning && statements.length > 0) {
         final PyDocStringOwner docStringOwner = PsiTreeUtil.getParentOfType(statementList, PyDocStringOwner.class);
-        final PyStatement firstStatement = statements[0];
-        if (docStringOwner != null && firstStatement instanceof PyExpressionStatement &&
-            ((PyExpressionStatement)firstStatement).getExpression() == docStringOwner.getDocStringExpression()) {
-          element = statementList.addAfter(element, firstStatement);
+        PyStatement anchor = statements[0];
+        if (docStringOwner != null && anchor instanceof PyExpressionStatement &&
+            ((PyExpressionStatement)anchor).getExpression() == docStringOwner.getDocStringExpression()) {
+          final PyStatement next = PsiTreeUtil.getNextSiblingOfType(anchor, PyStatement.class);
+          if (next == null) {
+            return statementList.addAfter(element, anchor);
+          }
+          anchor = next;
         }
-        else
-          element = statementList.addBefore(element, firstStatement);
+        while (anchor instanceof PyExpressionStatement) {
+          final PyExpression expression = ((PyExpressionStatement)anchor).getExpression();
+          if (expression instanceof PyCallExpression) {
+            final PyExpression callee = ((PyCallExpression)expression).getCallee();
+            if ((isSuperCall((PyCallExpression)expression) || (callee != null && PyNames.INIT.equals(callee.getName())))) {
+              final PyStatement next = PsiTreeUtil.getNextSiblingOfType(anchor, PyStatement.class);
+              if (next == null) {
+                return statementList.addAfter(element, anchor);
+              }
+              anchor = next;
+            }
+            else break;
+          }
+          else break;
+        }
+        element = statementList.addBefore(element, anchor);
       }
       else {
         element = statementList.add(element);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
index 0a9959d..47fb347 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyClassImpl.java
@@ -585,7 +585,7 @@
 
   @Nullable
   @Override
-  public Property findProperty(@NotNull final String name) {
+  public Property findProperty(@NotNull final String name, boolean inherited) {
     Property property = findLocalProperty(name);
     if (property != null) {
       return property;
@@ -593,10 +593,12 @@
     if (findMethodByName(name, false) != null || findClassAttribute(name, false) != null) {
       return null;
     }
-    for (PyClass aClass : getAncestorClasses()) {
-      final Property ancestorProperty = ((PyClassImpl)aClass).findLocalProperty(name);
-      if (ancestorProperty != null) {
-        return ancestorProperty;
+    if (inherited) {
+      for (PyClass aClass : getAncestorClasses()) {
+        final Property ancestorProperty = ((PyClassImpl)aClass).findLocalProperty(name);
+        if (ancestorProperty != null) {
+          return ancestorProperty;
+        }
       }
     }
     return null;
diff --git a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
index f15a664..f64b533 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyDecoratorImpl.java
@@ -74,8 +74,8 @@
   }
 
   public boolean hasArgumentList() {
-    ASTNode arglist_node = getNode().findChildByType(PyElementTypes.ARGUMENT_LIST);
-    return (arglist_node != null) && (arglist_node.findChildByType(PyTokenTypes.LPAR) != null);
+    final ASTNode arglistNode = getNode().findChildByType(PyElementTypes.ARGUMENT_LIST);
+    return (arglistNode != null) && (arglistNode.findChildByType(PyTokenTypes.LPAR) != null);
   }
 
   public QualifiedName getQualifiedName() {
diff --git a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
index 3f43843..8c71346 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyFunctionImpl.java
@@ -174,29 +174,28 @@
   @Nullable
   @Override
   public PyType getReturnType(@NotNull TypeEvalContext context, @Nullable PyQualifiedExpression callSite) {
-    final PyType type = getGenericReturnType(context, callSite);
-
+    PyType type = getGenericReturnType(context, callSite);
     if (callSite == null) {
       return type;
     }
     final PyTypeChecker.AnalyzeCallResults results = PyTypeChecker.analyzeCallSite(callSite, context);
-
     if (PyTypeChecker.hasGenerics(type, context)) {
       if (results != null) {
         final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, results.getReceiver(), results.getArguments(),
                                                                                         context);
-        if (substitutions != null) {
-          return PyTypeChecker.substitute(type, substitutions, context);
-        }
+        type = substitutions != null ? PyTypeChecker.substitute(type, substitutions, context) : null;
       }
-      return null;
+      else {
+        type = null;
+      }
+    }
+    if (results != null) {
+      type = replaceSelf(type, results.getReceiver(), context);
     }
     if (results != null && isDynamicallyEvaluated(results.getArguments().values(), context)) {
       return PyUnionType.createWeakType(type);
     }
-    else {
-      return type;
-    }
+    return type;
   }
 
   @Nullable
@@ -205,16 +204,36 @@
    */
   public PyType getReturnTypeWithoutCallSite(@NotNull TypeEvalContext context,
                                              @Nullable PyExpression receiver) {
-    final PyType type = getGenericReturnType(context, null);
+    PyType type = getGenericReturnType(context, null);
     if (PyTypeChecker.hasGenerics(type, context)) {
-      final Map<PyGenericType, PyType> substitutions =
-        PyTypeChecker.unifyGenericCall(this, receiver, Maps.<PyExpression, PyNamedParameter>newHashMap(), context);
+      final Map<PyGenericType, PyType> substitutions = PyTypeChecker.unifyGenericCall(this, receiver,
+                                                                                      Maps.<PyExpression, PyNamedParameter>newHashMap(),
+                                                                                      context);
       if (substitutions != null) {
-        return PyTypeChecker.substitute(type, substitutions, context);
+        type = PyTypeChecker.substitute(type, substitutions, context);
       }
-      return null;
+      else {
+        type = null;
+      }
     }
-    return type;
+    return replaceSelf(type, receiver, context);
+  }
+
+  @Nullable
+  private PyType replaceSelf(@Nullable PyType returnType, @Nullable PyExpression receiver, @NotNull TypeEvalContext context) {
+    if (receiver != null) {
+      // TODO: Currently we substitute only simple subclass types, but we could handle union and collection types as well
+      if (returnType instanceof PyClassType) {
+        final PyClassType returnClassType = (PyClassType)returnType;
+        if (returnClassType.getPyClass() == getContainingClass()) {
+          final PyType receiverType = context.getType(receiver);
+          if (receiverType instanceof PyClassType && PyTypeChecker.match(returnType, receiverType, context)) {
+            return returnClassType.isDefinition() ? receiverType : ((PyClassType)receiverType).toInstance();
+          }
+        }
+      }
+    }
+    return returnType;
   }
 
   private static boolean isDynamicallyEvaluated(@NotNull Collection<PyNamedParameter> parameters, @NotNull TypeEvalContext context) {
diff --git a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
index 7b778a5..455d4c5 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyReferenceExpressionImpl.java
@@ -264,7 +264,7 @@
     if (qualifierType instanceof PyClassType) {
       final PyClassType classType = (PyClassType)qualifierType;
       PyClass pyClass = classType.getPyClass();
-      Property property = pyClass.findProperty(name);
+      Property property = pyClass.findProperty(name, true);
       if (property != null) {
         if (classType.isDefinition()) {
           return Ref.<PyType>create(PyBuiltinCache.getInstance(pyClass).getObjectType(PyNames.PROPERTY));
@@ -291,7 +291,7 @@
   }
 
   @Nullable
-  private PyType getTypeFromProviders(TypeEvalContext context) {
+  private PyType getTypeFromProviders(@NotNull TypeEvalContext context) {
     for (PyTypeProvider provider : Extensions.getExtensions(PyTypeProvider.EP_NAME)) {
       try {
         final PyType type = provider.getReferenceExpressionType(this, context);
diff --git a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
index fd49c25..ae2e30f 100644
--- a/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
+++ b/python/src/com/jetbrains/python/psi/impl/PyTargetExpressionImpl.java
@@ -241,8 +241,8 @@
       if (exprType instanceof PyClassType) {
         final PyClass cls = ((PyClassType)exprType).getPyClass();
         final PyFunction enter = cls.findMethodByName(PyNames.ENTER, true);
-        if (enter != null) {
-          final PyType enterType = enter.getReturnType(context, null);
+        if (enter instanceof PyFunctionImpl) {
+          final PyType enterType = ((PyFunctionImpl)enter).getReturnTypeWithoutCallSite(context, expression);
           if (enterType != null) {
             return enterType;
           }
diff --git a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
index 7be077f..e475429 100644
--- a/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
+++ b/python/src/com/jetbrains/python/psi/types/PyClassTypeImpl.java
@@ -23,6 +23,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Key;
 import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.UserDataHolderBase;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiInvalidElementAccessException;
@@ -156,22 +157,9 @@
     }
 
     if (resolveContext.allowProperties()) {
-      Property property = myClass.findProperty(name);
-      if (property != null) {
-        Maybe<Callable> accessor = property.getByDirection(direction);
-        if (accessor.isDefined()) {
-          Callable accessor_code = accessor.value();
-          ResolveResultList ret = new ResolveResultList();
-          if (accessor_code != null) ret.poke(accessor_code, RatedResolveResult.RATE_NORMAL);
-          PyTargetExpression site = property.getDefinitionSite();
-          if (site != null) ret.poke(site, RatedResolveResult.RATE_LOW);
-          if (ret.size() > 0) {
-            return ret;
-          }
-          else {
-            return null;
-          } // property is found, but the required accessor is explicitly absent
-        }
+      final Ref<ResolveResultList> resultRef = findProperty(name, direction, true);
+      if (resultRef != null) {
+        return resultRef.get();
       }
     }
 
@@ -198,6 +186,11 @@
       return ResolveResultList.to(classMember);
     }
 
+    classMember = resolveByOverridingAncestorsMembersProviders(this, name, location);
+    if (classMember != null) {
+      return ResolveResultList.to(classMember);
+    }
+
     if (inherited) {
       for (PyClassLikeType type : myClass.getAncestorTypes(context)) {
         if (type instanceof PyClassType) {
@@ -237,12 +230,10 @@
       for (PyClassLikeType type : myClass.getAncestorTypes(context)) {
         if (type instanceof PyClassType) {
           final PyClass pyClass = ((PyClassType)type).getPyClass();
-          if (pyClass != null) {
-            PsiElement superMember = resolveByMembersProviders(new PyClassTypeImpl(pyClass, isDefinition()), name, location);
+          PsiElement superMember = resolveByMembersProviders(new PyClassTypeImpl(pyClass, isDefinition()), name, location);
 
-            if (superMember != null) {
-              return ResolveResultList.to(superMember);
-            }
+          if (superMember != null) {
+            return ResolveResultList.to(superMember);
           }
         }
       }
@@ -251,6 +242,28 @@
     return Collections.emptyList();
   }
 
+  private Ref<ResolveResultList> findProperty(String name, AccessDirection direction, boolean inherited) {
+    Ref<ResolveResultList> resultRef = null;
+    Property property = myClass.findProperty(name, inherited);
+    if (property != null) {
+      Maybe<Callable> accessor = property.getByDirection(direction);
+      if (accessor.isDefined()) {
+        Callable accessor_code = accessor.value();
+        ResolveResultList ret = new ResolveResultList();
+        if (accessor_code != null) ret.poke(accessor_code, RatedResolveResult.RATE_NORMAL);
+        PyTargetExpression site = property.getDefinitionSite();
+        if (site != null) ret.poke(site, RatedResolveResult.RATE_LOW);
+        if (ret.size() > 0) {
+          resultRef = Ref.create(ret);
+        }
+        else {
+          resultRef = Ref.create();
+        } // property is found, but the required accessor is explicitly absent
+      }
+    }
+    return resultRef;
+  }
+
   @Nullable
   private PyClassType getMetaclassType() {
     final PyClass metaClass = PyUtil.getMetaClass(myClass);
@@ -330,6 +343,17 @@
   }
 
   @Nullable
+  private static PsiElement resolveByOverridingAncestorsMembersProviders(PyClassType type, String name, @Nullable PyExpression location) {
+    for (PyClassMembersProvider provider : Extensions.getExtensions(PyClassMembersProvider.EP_NAME)) {
+      if (provider instanceof PyOverridingAncestorsClassMembersProvider) {
+        final PsiElement resolveResult = provider.resolveMember(type, name, location);
+        if (resolveResult != null) return resolveResult;
+      }
+    }
+    return null;
+  }
+
+  @Nullable
   private static PsiElement resolveInner(@NotNull PyClass cls,
                                          boolean isDefinition,
                                          @NotNull String name,
diff --git a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java
index 8a1bd6b..aeb1efa 100644
--- a/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java
+++ b/python/src/com/jetbrains/python/refactoring/extractmethod/PyExtractMethodUtil.java
@@ -40,7 +40,10 @@
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.hash.HashMap;
-import com.jetbrains.python.*;
+import com.jetbrains.python.PyBundle;
+import com.jetbrains.python.PyNames;
+import com.jetbrains.python.PythonFileType;
+import com.jetbrains.python.PythonLanguage;
 import com.jetbrains.python.codeInsight.codeFragment.PyCodeFragment;
 import com.jetbrains.python.codeInsight.controlflow.ControlFlowCache;
 import com.jetbrains.python.codeInsight.controlflow.ScopeOwner;
@@ -332,9 +335,12 @@
     }
   }
 
-  private static void setSelectionAndCaret(Editor editor, final PsiElement callElement) {
+  private static void setSelectionAndCaret(Editor editor, @Nullable final PsiElement callElement) {
     editor.getSelectionModel().removeSelection();
-    editor.getCaretModel().moveToOffset(callElement.getTextOffset());
+    if (callElement != null) {
+      final int offset = callElement.getTextOffset();
+      editor.getCaretModel().moveToOffset(offset);
+    }
   }
 
   private static PsiElement replaceElements(final List<PsiElement> elementsRange, @NotNull PsiElement callElement) {
diff --git a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
index 3fbc168..077ced3 100644
--- a/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
+++ b/python/src/com/jetbrains/python/sdk/skeletons/PySkeletonRefresher.java
@@ -267,6 +267,7 @@
     final String skeletonsPath = getSkeletonsPath();
     final File skeletonsDir = new File(skeletonsPath);
     if (!skeletonsDir.exists()) {
+      //noinspection ResultOfMethodCallIgnored
       skeletonsDir.mkdirs();
     }
     final String readablePath = FileUtil.getLocationRelativeToUserHome(homePath);
@@ -446,7 +447,7 @@
         reader.close();
       }
     }
-    catch (IOException e) {
+    catch (IOException ignored) {
     }
     return null;
   }
diff --git a/python/src/com/jetbrains/python/testing/PyTestFrameworkService.java b/python/src/com/jetbrains/python/testing/PyTestFrameworkService.java
new file mode 100644
index 0000000..8eac088
--- /dev/null
+++ b/python/src/com/jetbrains/python/testing/PyTestFrameworkService.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2013 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.jetbrains.python.testing;
+
+import com.intellij.openapi.components.*;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.xmlb.XmlSerializerUtil;
+
+import java.util.Map;
+
+@State(
+  name = "PyTestFrameworkService",
+  storages = {
+    @Storage(
+      file = StoragePathMacros.APP_CONFIG + "/other.xml"
+    )}
+)
+public class PyTestFrameworkService implements PersistentStateComponent<PyTestFrameworkService> {
+
+  public static PyTestFrameworkService getInstance() {
+    return ServiceManager.getService(PyTestFrameworkService.class);
+  }
+
+  public Map<String, Boolean> SDK_TO_PYTEST = new HashMap<String, Boolean>();
+  public Map <String, Boolean> SDK_TO_NOSETEST = new HashMap<String, Boolean>();
+  public Map <String, Boolean> SDK_TO_ATTEST = new HashMap<String, Boolean>();
+
+  @Override
+  public PyTestFrameworkService getState() {
+    return this;
+  }
+
+  @Override
+  public void loadState(PyTestFrameworkService state) {
+    XmlSerializerUtil.copyBean(state, this);
+  }
+}
diff --git a/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java b/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
index 7130b1a..69d1ce0 100644
--- a/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
+++ b/python/src/com/jetbrains/python/testing/VFSTestFrameworkListener.java
@@ -16,22 +16,22 @@
 package com.jetbrains.python.testing;
 
 import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.components.*;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.components.ServiceManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.projectRoots.Sdk;
 import com.intellij.openapi.roots.OrderRootType;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.LocalFileSystem;
+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.VFileContentChangeEvent;
 import com.intellij.openapi.vfs.newvfs.events.VFileEvent;
-import com.intellij.util.containers.HashMap;
 import com.intellij.util.messages.MessageBus;
 import com.intellij.util.ui.update.MergingUpdateQueue;
 import com.intellij.util.ui.update.Update;
-import com.intellij.util.xmlb.XmlSerializerUtil;
 import com.jetbrains.python.PyNames;
 import com.jetbrains.python.packaging.PyExternalProcessException;
 import com.jetbrains.python.packaging.PyPackageManager;
@@ -41,25 +41,17 @@
 import org.jetbrains.annotations.NotNull;
 
 import java.util.List;
-import java.util.Map;
 
 /**
  * User: catherine
  */
-@State(
-  name = "VFSTestFrameworkListener",
-  storages = {
-    @Storage(
-      file = StoragePathMacros.APP_CONFIG + "/other.xml"
-    )}
-)
-public class VFSTestFrameworkListener implements ApplicationComponent, PersistentStateComponent<VFSTestFrameworkListener> {
-
+public class VFSTestFrameworkListener implements ApplicationComponent {
   private static final Logger LOG = Logger.getInstance("#com.jetbrains.python.testing.VFSTestFrameworkListener");
-
   private static final MergingUpdateQueue myQueue = new MergingUpdateQueue("TestFrameworkChecker", 5000, true, null);
+  private PyTestFrameworkService myService;
 
   public VFSTestFrameworkListener() {
+    myService = PyTestFrameworkService.getInstance();
     MessageBus messageBus = ApplicationManager.getApplication().getMessageBus();
     messageBus.connect().subscribe(VirtualFileManager.VFS_CHANGES, new BulkFileListener.Adapter() {
       @Override
@@ -76,8 +68,9 @@
             if (PySdkUtil.isRemote(sdk)) {
               continue;
             }
-            for (String root : sdk.getRootProvider().getUrls(OrderRootType.CLASSES)) {
-              if (path.contains(root)) {
+            for (VirtualFile virtualFile : sdk.getRootProvider().getFiles(OrderRootType.CLASSES)) {
+              String root = virtualFile.getCanonicalPath();
+              if (root != null && path.contains(root)) {
                 if (containsNose) {
                   updateTestFrameworks(sdk, PyNames.NOSE_TEST);
                   return;
@@ -152,26 +145,12 @@
     return ServiceManager.getService(VFSTestFrameworkListener.class);
   }
 
-  public Map<String, Boolean> SDK_TO_PYTEST = new HashMap<String, Boolean>();
-  public Map <String, Boolean> SDK_TO_NOSETEST = new HashMap<String, Boolean>();
-  public Map <String, Boolean> SDK_TO_ATTEST = new HashMap<String, Boolean>();
-
-  @Override
-  public VFSTestFrameworkListener getState() {
-    return this;
-  }
-
-  @Override
-  public void loadState(VFSTestFrameworkListener state) {
-    XmlSerializerUtil.copyBean(state, this);
-  }
-
   public void pyTestInstalled(boolean installed, String sdkHome) {
-    SDK_TO_PYTEST.put(sdkHome, installed);
+    myService.SDK_TO_PYTEST.put(sdkHome, installed);
   }
 
   public boolean isPyTestInstalled(final Sdk sdk) {
-    Boolean isInstalled = SDK_TO_PYTEST.get(sdk.getHomePath());
+    Boolean isInstalled = myService.SDK_TO_PYTEST.get(sdk.getHomePath());
     if (isInstalled == null) {
       updateTestFrameworks(sdk, PyNames.PY_TEST);
       return true;
@@ -180,11 +159,11 @@
   }
 
   public void noseTestInstalled(boolean installed, String sdkHome) {
-    SDK_TO_NOSETEST.put(sdkHome, installed);
+    myService.SDK_TO_NOSETEST.put(sdkHome, installed);
   }
 
   public boolean isNoseTestInstalled(final Sdk sdk) {
-    Boolean isInstalled = SDK_TO_NOSETEST.get(sdk.getHomePath());
+    Boolean isInstalled = myService.SDK_TO_NOSETEST.get(sdk.getHomePath());
     if (isInstalled == null) {
       updateTestFrameworks(sdk, PyNames.NOSE_TEST);
       return true;
@@ -193,11 +172,11 @@
   }
 
   public void atTestInstalled(boolean installed, String sdkHome) {
-    SDK_TO_ATTEST.put(sdkHome, installed);
+    myService.SDK_TO_ATTEST.put(sdkHome, installed);
   }
 
   public boolean isAtTestInstalled(final Sdk sdk) {
-    Boolean isInstalled = SDK_TO_ATTEST.get(sdk.getHomePath());
+    Boolean isInstalled = myService.SDK_TO_ATTEST.get(sdk.getHomePath());
     if (isInstalled == null) {
       updateTestFrameworks(sdk, PyNames.AT_TEST);
       return true;
diff --git a/python/testData/formatter/commentBetweenClasses_after.py b/python/testData/formatter/commentBetweenClasses_after.py
index b852394..e97c76b 100644
--- a/python/testData/formatter/commentBetweenClasses_after.py
+++ b/python/testData/formatter/commentBetweenClasses_after.py
@@ -2,6 +2,7 @@
     def m1(self):
         pass
 
+
 # comment about T2
 
 class T2(object):
diff --git a/python/testData/formatter/continuationIndentInIndentingStatement.py b/python/testData/formatter/continuationIndentInIndentingStatement.py
new file mode 100644
index 0000000..5822bc4
--- /dev/null
+++ b/python/testData/formatter/continuationIndentInIndentingStatement.py
@@ -0,0 +1,31 @@
+if True \
+    or False:
+    pass
+elif \
+    False:
+    pass
+
+for i in \
+    range(1, 100):
+    pass
+
+with open('file1') as file1, \
+    open('file2') as file2:
+    pass
+
+
+class \
+    A(object):
+    pass
+
+
+def \
+    foo():
+    pass
+
+
+try:
+    pass
+except \
+    AttributeError:
+    pass
\ No newline at end of file
diff --git a/python/testData/formatter/continuationIndentInIndentingStatement_after.py b/python/testData/formatter/continuationIndentInIndentingStatement_after.py
new file mode 100644
index 0000000..f38dd51
--- /dev/null
+++ b/python/testData/formatter/continuationIndentInIndentingStatement_after.py
@@ -0,0 +1,31 @@
+if True \
+        or False:
+    pass
+elif \
+        False:
+    pass
+
+for i in \
+        range(1, 100):
+    pass
+
+with open('file1') as file1, \
+        open('file2') as file2:
+    pass
+
+
+class \
+        A(object):
+    pass
+
+
+def \
+        foo():
+    pass
+
+
+try:
+    pass
+except \
+        AttributeError:
+    pass
\ No newline at end of file
diff --git a/python/testData/formatter/indentParensInImport.py b/python/testData/formatter/indentParensInImport.py
new file mode 100644
index 0000000..ab20f1b
--- /dev/null
+++ b/python/testData/formatter/indentParensInImport.py
@@ -0,0 +1,3 @@
+from some.module import (
+    thing
+    )
\ No newline at end of file
diff --git a/python/testData/formatter/indentParensInImport_after.py b/python/testData/formatter/indentParensInImport_after.py
new file mode 100644
index 0000000..2ad9216
--- /dev/null
+++ b/python/testData/formatter/indentParensInImport_after.py
@@ -0,0 +1,3 @@
+from some.module import (
+    thing
+)
\ No newline at end of file
diff --git a/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment.py b/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment.py
new file mode 100644
index 0000000..a0f5290
--- /dev/null
+++ b/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment.py
@@ -0,0 +1,18 @@
+class A(object):
+    pass
+
+#comment
+def one():
+    pass
+
+# comment
+def two():
+    pass
+
+#comment
+class B(object):
+    pass
+
+#comment
+class C(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment_after.py b/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment_after.py
new file mode 100644
index 0000000..d582036
--- /dev/null
+++ b/python/testData/formatter/twoLinesBetweenTopLevelDeclarationsWithComment_after.py
@@ -0,0 +1,22 @@
+class A(object):
+    pass
+
+
+#comment
+def one():
+    pass
+
+
+# comment
+def two():
+    pass
+
+
+#comment
+class B(object):
+    pass
+
+
+#comment
+class C(object):
+    pass
\ No newline at end of file
diff --git a/python/testData/inspections/FieldFromUnusedParameterKeyword.py b/python/testData/inspections/FieldFromUnusedParameterKeyword.py
deleted file mode 100644
index 35851f0..0000000
--- a/python/testData/inspections/FieldFromUnusedParameterKeyword.py
+++ /dev/null
@@ -1,3 +0,0 @@
-class A:
-    def __init__(self, <weak_warning descr="Parameter 'foo' value is not used">f<caret>oo=True</weak_warning>):
-        print('hello')
\ No newline at end of file
diff --git a/python/testData/inspections/PyArgumentListInspection/decoratorsPy3K.py b/python/testData/inspections/PyArgumentListInspection/decoratorsPy3K.py
new file mode 100644
index 0000000..07e9942
--- /dev/null
+++ b/python/testData/inspections/PyArgumentListInspection/decoratorsPy3K.py
@@ -0,0 +1,7 @@
+
+def deco(func, *args):
+    return func
+
+@deco  # <= Here is a false positive.
+def myfunc(a, b):
+    print(a, b)
\ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/contextManagerSubclass.py b/python/testData/inspections/PyUnresolvedReferencesInspection/contextManagerSubclass.py
new file mode 100644
index 0000000..f7406de
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/contextManagerSubclass.py
@@ -0,0 +1,12 @@
+class C(object):
+    def __enter__(self):
+        return self
+
+
+class D(C):
+    def foo(self):
+        pass
+
+
+with D() as cm:
+    cm.foo()  # pass
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/ivarInDocstring.py b/python/testData/inspections/PyUnresolvedReferencesInspection/ivarInDocstring.py
new file mode 100644
index 0000000..1fec85f
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/ivarInDocstring.py
@@ -0,0 +1,10 @@
+
+class SomeClass(object):
+    """ Awesome class
+
+    @ivar someVar: great stuff
+    @type someVar: string
+    """
+
+    def __init__(self):
+        self.someVar = None
\ No newline at end of file
diff --git a/python/testData/inspections/PyUnresolvedReferencesInspection/returnSelfInSuperClass.py b/python/testData/inspections/PyUnresolvedReferencesInspection/returnSelfInSuperClass.py
new file mode 100644
index 0000000..79c56a0
--- /dev/null
+++ b/python/testData/inspections/PyUnresolvedReferencesInspection/returnSelfInSuperClass.py
@@ -0,0 +1,13 @@
+class C(object):
+    def get_self(self):
+        return self
+
+
+class D(C):
+    def foo(self):
+        pass
+
+
+d = D()
+print(d.foo())
+print(d.get_self().foo())  # pass
diff --git a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py
index 5edffda..65913e2 100644
--- a/python/testData/inspections/PyUnusedLocalVariableInspection/test.py
+++ b/python/testData/inspections/PyUnusedLocalVariableInspection/test.py
@@ -303,3 +303,16 @@
         x = False #pass
         if c:
             x = True
+
+
+# PY-7527
+def test_unused_empty_init_parameter():
+    class C(object):
+        def __init__(self, <weak_warning descr="Parameter 'foo' value is not used">foo</weak_warning>):
+            pass
+
+        def f(self, bar):
+            pass
+
+    return C
+
diff --git a/python/testData/inspections/ReplaceNotEqOperator.py b/python/testData/inspections/ReplaceNotEqOperator.py
index c0c6300..790a765 100644
--- a/python/testData/inspections/ReplaceNotEqOperator.py
+++ b/python/testData/inspections/ReplaceNotEqOperator.py
@@ -1 +1 @@
-print(<warning descr="Python version 3.0, 3.1, 3.2, 3.3, 3.4 do not support <>, use != instead.">a <> b</warning>)
\ No newline at end of file
+print(<warning descr="Python version 3.0, 3.1, 3.2, 3.3, 3.4 do not support <>, use != instead.">a<caret> <> b</warning>)
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromInstance_after.py b/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromInstance_after.py
index 6862903..7027a39 100644
--- a/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromInstance_after.py
+++ b/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromInstance_after.py
@@ -1,8 +1,7 @@
 class A:
   def __init__(self):
-    self.x = 1
     self.y = None
-
+    self.x = 1
 
 a = A()
 a.y+1
diff --git a/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromMethod_after.py b/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromMethod_after.py
index 3ac2f7e..c0ce40f 100644
--- a/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromMethod_after.py
+++ b/python/testData/quickFixes/AddFieldQuickFixTest/addFieldFromMethod_after.py
@@ -1,7 +1,7 @@
 class A:
   def __init__(self):
-    self.x = 1
     self.y = None
+    self.x = 1
 
   def foo(self):
     a = self.y
diff --git a/python/testData/inspections/FieldFromUnusedParameter.py b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameter.py
similarity index 100%
rename from python/testData/inspections/FieldFromUnusedParameter.py
rename to python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameter.py
diff --git a/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword.py b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword.py
new file mode 100644
index 0000000..27f1600
--- /dev/null
+++ b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword.py
@@ -0,0 +1,3 @@
+class A:
+    def __init__(self, fo<caret>o=True):
+        print('hello')
\ No newline at end of file
diff --git a/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword_after.py
similarity index 98%
rename from python/testData/inspections/FieldFromUnusedParameterKeyword_after.py
rename to python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword_after.py
index 7e0d662..3f86fa4 100644
--- a/python/testData/inspections/FieldFromUnusedParameterKeyword_after.py
+++ b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameterKeyword_after.py
@@ -1,4 +1,4 @@
 class A:
     def __init__(self, foo=True):
-        print('hello')
-        self.foo = foo
\ No newline at end of file
+        self.foo = foo
+        print('hello')
\ No newline at end of file
diff --git a/python/testData/inspections/FieldFromUnusedParameter_after.py b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameter_after.py
similarity index 98%
rename from python/testData/inspections/FieldFromUnusedParameter_after.py
rename to python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameter_after.py
index 7405ba3..58785ed 100644
--- a/python/testData/inspections/FieldFromUnusedParameter_after.py
+++ b/python/testData/quickFixes/AddFieldQuickFixTest/fromUnusedParameter_after.py
@@ -1,4 +1,4 @@
 class A:
     def __init__(self, foo):
-        print('hello')
-        self.foo = foo
\ No newline at end of file
+        self.foo = foo
+        print('hello')
\ No newline at end of file
diff --git a/python/testData/quickFixes/AddMethodQuickFixTest/addMethodFromMethod_after.py b/python/testData/quickFixes/AddMethodQuickFixTest/addMethodFromMethod_after.py
index 978acaf..5c47b58 100644
--- a/python/testData/quickFixes/AddMethodQuickFixTest/addMethodFromMethod_after.py
+++ b/python/testData/quickFixes/AddMethodQuickFixTest/addMethodFromMethod_after.py
@@ -8,6 +8,7 @@
     def y(self, param, a):
         pass
 
+
 # Some comment
 
 class B:
diff --git a/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/addPass_after.py b/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/addPass_after.py
index da65a03..040de73 100644
--- a/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/addPass_after.py
+++ b/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/addPass_after.py
@@ -3,8 +3,8 @@
 
 class A:
     def __init__(self):
-        self._a = 1
         self.b = 1
+        self._a = 1
 
     def foo(self):
         pass
diff --git a/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/moveToInit_after.py b/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/moveToInit_after.py
index 2dc8074..9a83f67 100644
--- a/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/moveToInit_after.py
+++ b/python/testData/quickFixes/PyMoveAttributeToInitQuickFixTest/moveToInit_after.py
@@ -3,8 +3,8 @@
 
 class A:
     def __init__(self):
-        self._a = 1
         self.b = 1
+        self._a = 1
 
     def foo(self):
         c = 1
\ No newline at end of file
diff --git a/python/testData/refactoring/introduceField/py4437.after.py b/python/testData/refactoring/introduceField/py4437.after.py
index e9c7d75..07a1331 100644
--- a/python/testData/refactoring/introduceField/py4437.after.py
+++ b/python/testData/refactoring/introduceField/py4437.after.py
@@ -1,7 +1,7 @@
 class SomeClass():
     def __init__(self):
-        self.x = 1
         self.a = ''
+        self.x = 1
 
     def foo(self):
         self.a
diff --git a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java
index 7947ffb..2e55003 100644
--- a/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java
+++ b/python/testSrc/com/jetbrains/python/PyClassicPropertyTest.java
@@ -38,7 +38,7 @@
   public void testV1() throws Exception {
     Property p;
     Maybe<Callable> accessor;
-    p = myClass.findProperty("v1");
+    p = myClass.findProperty("v1", true);
     assertNotNull(p);
     assertNull(p.getDoc());
     PyTargetExpression site = p.getDefinitionSite();
@@ -62,7 +62,7 @@
   public void testV2() throws Exception {
     Property p;
     Maybe<Callable> accessor;
-    p = myClass.findProperty("v2");
+    p = myClass.findProperty("v2", true);
     assertNotNull(p);
     assertEquals("doc of v2", p.getDoc());
     PyTargetExpression site = p.getDefinitionSite();
@@ -86,7 +86,7 @@
 
   public void testV3() throws Exception {
     Maybe<Callable> accessor;
-    Property p = myClass.findProperty("v3");
+    Property p = myClass.findProperty("v3", true);
     assertNotNull(p);
     assertNull(p.getDoc());
     PyTargetExpression site = p.getDefinitionSite();
diff --git a/python/testSrc/com/jetbrains/python/PyDecoratedPropertyTest.java b/python/testSrc/com/jetbrains/python/PyDecoratedPropertyTest.java
index 414c355..ac9f83a 100644
--- a/python/testSrc/com/jetbrains/python/PyDecoratedPropertyTest.java
+++ b/python/testSrc/com/jetbrains/python/PyDecoratedPropertyTest.java
@@ -35,7 +35,7 @@
     Property p;
     Maybe<Callable> accessor;
     final String name = "w1";
-    p = myClass.findProperty(name);
+    p = myClass.findProperty(name, true);
     assertNotNull(p);
     assertNull(p.getDoc());
     assertNull(p.getDefinitionSite());
@@ -60,7 +60,7 @@
     Property p;
     Maybe<Callable> accessor;
     final String name = "w2";
-    p = myClass.findProperty(name);
+    p = myClass.findProperty(name, true);
     assertNotNull(p);
     assertNull(p.getDoc());
     assertNull(p.getDefinitionSite());
diff --git a/python/testSrc/com/jetbrains/python/PyEditingTest.java b/python/testSrc/com/jetbrains/python/PyEditingTest.java
index 6619bf8..5f0e7c2 100644
--- a/python/testSrc/com/jetbrains/python/PyEditingTest.java
+++ b/python/testSrc/com/jetbrains/python/PyEditingTest.java
@@ -26,6 +26,8 @@
 import com.intellij.openapi.editor.ex.EditorSettingsExternalizable;
 import com.intellij.openapi.util.Computable;
 import com.intellij.psi.PsiFile;
+import com.jetbrains.python.documentation.DocStringFormat;
+import com.jetbrains.python.documentation.PyDocumentationSettings;
 import com.jetbrains.python.fixtures.PyTestCase;
 
 /**
@@ -142,7 +144,7 @@
   }
 
   public void testEnterInStatement() {
-    doTestEnter("if a <caret>and b: pass", "if a \\\n    and b: pass");
+    doTestEnter("if a <caret>and b: pass", "if a \\\n        and b: pass");
   }
 
   public void testEnterBeforeStatement() {
@@ -202,10 +204,17 @@
   }
 
   public void testEnterStubInDocstring() {  // CR-PY-144
-    doTestEnter("def foo():\n  \"\"\"<caret>", "def foo():\n" +
-                                               "  \"\"\"\n" +
-                                               "  \n" +
-                                               "  \"\"\"");
+    final PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
+    final String oldFormat = documentationSettings.getFormat();
+    documentationSettings.setFormat(DocStringFormat.PLAIN);
+    try {
+      doTestEnter("def foo():\n  \"\"\"<caret>", "def foo():\n" +
+                                                 "  \"\"\"\n" +
+                                                 "  \n" +
+                                                 "  \"\"\"");
+    } finally {
+      documentationSettings.setFormat(oldFormat);
+    }
   }
 
   public void testEnterInString() {  // PY-1738
@@ -216,7 +225,7 @@
   public void testEnterInImportWithParens() {  // PY-2661
     doTestEnter("from django.http import (HttpResponse,<caret>)",
                 "from django.http import (HttpResponse,\n" +
-                "                         )");
+                ")");
   }
 
   public void testEnterInKeyword() {
diff --git a/python/testSrc/com/jetbrains/python/PyFormatterTest.java b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
index d25a62f..3ca878b 100644
--- a/python/testSrc/com/jetbrains/python/PyFormatterTest.java
+++ b/python/testSrc/com/jetbrains/python/PyFormatterTest.java
@@ -126,6 +126,10 @@
     doTest();
   }
 
+  public void testTwoLinesBetweenTopLevelDeclarationsWithComment() { // PY-9923
+    doTest();
+  }
+
   public void testSpecialSlice() {  // PY-1928
     doTest();
   }
@@ -199,6 +203,10 @@
     doTest();
   }
 
+  public void testContinuationIndentInIndentingStatement() { // PY-9573
+    doTest();
+  }
+
   public void testBlankLineAfterDecorator() {
     doTest();
   }
@@ -358,6 +366,10 @@
     doTest();
   }
 
+  public void testIndentParensInImport() { // PY-9075
+    doTest();
+  }
+
   private void doTest() {
     doTest(false);
   }
diff --git a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
index 0b78bd5..fb45fae 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickDocTest.java
@@ -20,6 +20,8 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.PsiElement;
 import com.intellij.testFramework.TestDataFile;
+import com.jetbrains.python.documentation.DocStringFormat;
+import com.jetbrains.python.documentation.PyDocumentationSettings;
 import com.jetbrains.python.documentation.PythonDocumentationProvider;
 import com.jetbrains.python.fixtures.LightMarkedTestCase;
 import com.jetbrains.python.fixtures.PyTestCase;
@@ -35,12 +37,23 @@
  */
 public class PyQuickDocTest extends LightMarkedTestCase {
   private PythonDocumentationProvider myProvider;
+  private String myFormat;
 
   @Override
   protected void setUp() throws Exception {
     super.setUp();
     // the provider is stateless, can be reused, as in real life
     myProvider = new PythonDocumentationProvider();
+    final PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
+    myFormat = documentationSettings.getFormat();
+    documentationSettings.setFormat(DocStringFormat.PLAIN);
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    final PyDocumentationSettings documentationSettings = PyDocumentationSettings.getInstance(myFixture.getModule());
+    documentationSettings.setFormat(myFormat);
+    super.tearDown();
   }
 
   private void checkByHTML(String text) {
diff --git a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
index e0f82b0..4083775 100644
--- a/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/PyQuickFixTest.java
@@ -173,13 +173,6 @@
     doInspectionTest("AddClass.py", PyUnresolvedReferencesInspection.class, "Create class 'Xyzzy'", true, true);
   }
 
-  public void testFieldFromUnusedParameter() {  // PY-1398
-    doInspectionTest("FieldFromUnusedParameter.py", PyUnusedLocalInspection.class, "Add field 'foo' to class A", true, true);
-  }
-
-  public void testFieldFromUnusedParameterKeyword() {  // PY-1602
-    doInspectionTest("FieldFromUnusedParameterKeyword.py", PyUnusedLocalInspection.class, "Add field 'foo' to class A", true, true);
-  }
 
   public void testAddFunctionToModule() {  // PY-1602
     doInspectionTest(
diff --git a/python/testSrc/com/jetbrains/python/PyStubsTest.java b/python/testSrc/com/jetbrains/python/PyStubsTest.java
index 6ad2dc4..7706dd7 100644
--- a/python/testSrc/com/jetbrains/python/PyStubsTest.java
+++ b/python/testSrc/com/jetbrains/python/PyStubsTest.java
@@ -118,12 +118,12 @@
       pyClass = classes.get(1);
       assertEquals("BarClass", pyClass.getName());
 
-      Property prop = pyClass.findProperty("value");
+      Property prop = pyClass.findProperty("value", true);
       Maybe<Callable> maybe_function = prop.getGetter();
       assertTrue(maybe_function.isDefined());
       assertEquals(pyClass.getMethods()[0], maybe_function.value());
 
-      Property setvalueProp = pyClass.findProperty("setvalue");
+      Property setvalueProp = pyClass.findProperty("setvalue", true);
       Maybe<Callable> setter = setvalueProp.getSetter();
       assertTrue(setter.isDefined());
       assertEquals("__set", setter.value().getName());
@@ -131,7 +131,7 @@
       // properties by decorator
       pyClass = classes.get(2);
       assertEquals("BazClass", pyClass.getName());
-      prop = pyClass.findProperty("x");
+      prop = pyClass.findProperty("x", true);
       maybe_function = prop.getGetter();
       assertTrue(maybe_function.isDefined());
       assertEquals(pyClass.getMethods()[0], maybe_function.value());
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
index fabba0c..c0b20d8 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyArgumentListInspectionTest.java
@@ -34,6 +34,16 @@
   public void testDecorators() {
     doTest();
   }
+
+  public void testDecoratorsPy3K() {
+    PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), LanguageLevel.PYTHON30);
+    try {
+      doTest();
+    }
+    finally {
+      PythonLanguageLevelPusher.setForcedLanguageLevel(myFixture.getProject(), null);
+    }
+  }
   
   public void testTupleVsLiteralList() {
     doTest();
diff --git a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
index 54cbf2e..53bcbc3 100644
--- a/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
+++ b/python/testSrc/com/jetbrains/python/inspections/PyUnresolvedReferencesInspectionTest.java
@@ -133,6 +133,10 @@
     doTest();
   }
 
+  public void testIvarInDocstring() {
+    doTest();
+  }
+
   // PY-6634
   public void testModuleAttribute() {
     doTest();
@@ -322,6 +326,16 @@
     doTest();
   }
 
+  // PY-10977
+  public void testContextManagerSubclass() {
+    doTest();
+  }
+
+  // PY-11413
+  public void testReturnSelfInSuperClass() {
+    doTest();
+  }
+
   private void doTest() {
     myFixture.configureByFile(TEST_DIRECTORY + getTestName(true) + ".py");
     myFixture.enableInspections(PyUnresolvedReferencesInspection.class);
diff --git a/python/testSrc/com/jetbrains/python/quickFixes/AddFieldQuickFixTest.java b/python/testSrc/com/jetbrains/python/quickFixes/AddFieldQuickFixTest.java
index 5ffe1a6..c93553d2 100644
--- a/python/testSrc/com/jetbrains/python/quickFixes/AddFieldQuickFixTest.java
+++ b/python/testSrc/com/jetbrains/python/quickFixes/AddFieldQuickFixTest.java
@@ -15,13 +15,16 @@
  */
 package com.jetbrains.python.quickFixes;
 
+import com.intellij.testFramework.TestDataPath;
 import com.jetbrains.python.PyBundle;
 import com.jetbrains.python.PyQuickFixTestCase;
 import com.jetbrains.python.inspections.PyUnresolvedReferencesInspection;
+import com.jetbrains.python.inspections.PyUnusedLocalInspection;
 
 /**
  * User: ktisha
  */
+@TestDataPath("$CONTENT_ROOT/../testData//quickFixes/AddFieldQuickFixTest/")
 public class AddFieldQuickFixTest extends PyQuickFixTestCase {
 
   public void testAddClassField() {
@@ -44,4 +47,12 @@
     doQuickFixTest(PyUnresolvedReferencesInspection.class, PyBundle.message("QFIX.NAME.add.field.$0.to.class.$1", "x", "B"));
   }
 
+  public void testFromUnusedParameter() {  // PY-1398
+    doQuickFixTest(PyUnusedLocalInspection.class, "Add field 'foo' to class A");
+  }
+
+  public void testFromUnusedParameterKeyword() {  // PY-1602
+    doQuickFixTest(PyUnusedLocalInspection.class, "Add field 'foo' to class A");
+  }
+
 }
diff --git a/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java b/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java
index 4e6ec59..01c0bf7 100644
--- a/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java
+++ b/xml/dom-impl/src/com/intellij/util/xml/impl/DomAnchorImpl.java
@@ -82,7 +82,6 @@
 
     final int index = values.indexOf(t);
     if (index < 0) {
-      t.equals(values.get(10));
       diagnoseNegativeIndex2(t, parent, description, values);
     }
     return new IndexedAnchor<T>(parentAnchor, description, index);
diff --git a/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java
index 568a265..11ee96f 100644
--- a/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java
+++ b/xml/impl/src/com/intellij/ide/browsers/impl/BrowserSettingsProviderImpl.java
@@ -43,7 +43,7 @@
   }
 
   public boolean isModified() {
-    return mySettingsPanel.isModified();
+    return mySettingsPanel != null && mySettingsPanel.isModified();
   }
 
   public void apply() throws ConfigurationException {