Snapshot 568f05589922685b8c8f9a2f2f465043b8128542 from master branch of git://git.jetbrains.org/idea/community.git

Change-Id: I47fe8cb5d8a3c9876cd4c313dca1a8cc531288ec
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
index e64ff40..12d4f5b 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/CompileDriver.java
@@ -1959,8 +1959,7 @@
     finally {
       CompilerUtil.refreshIOFiles(filesToRefresh);
       if (!generatedFiles.isEmpty()) {
-        DumbService.getInstance(myProject).waitForSmartMode();
-        List<VirtualFile> vFiles = ApplicationManager.getApplication().runReadAction(new Computable<List<VirtualFile>>() {
+        List<VirtualFile> vFiles = DumbService.getInstance(myProject).runReadActionInSmartMode(new Computable<List<VirtualFile>>() {
           public List<VirtualFile> compute() {
             final ArrayList<VirtualFile> vFiles = new ArrayList<VirtualFile>(generatedFiles.size());
             for (File generatedFile : generatedFiles) {
@@ -2162,8 +2161,7 @@
     final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
     final Set<String> allUrls = new HashSet<String>();
     final IOException[] ex = {null};
-    DumbService.getInstance(myProject).waitForSmartMode();
-    ApplicationManager.getApplication().runReadAction(new Runnable() {
+    DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
       public void run() {
         try {
           for (FileProcessingCompiler.ProcessingItem item : items) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
index 6cbb54b..38468aa 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/FileProcessingCompilerAdapterTask.java
@@ -64,11 +64,10 @@
       final List<FileProcessingCompiler.ProcessingItem> toProcess = new ArrayList<FileProcessingCompiler.ProcessingItem>();
       final Ref<IOException> ex = new Ref<IOException>(null);
 
-      DumbService.getInstance(project).waitForSmartMode();
 
       final FileProcessingCompilerStateCache cache = CompilerCacheManager.getInstance(project).getFileProcessingCompilerCache(myCompiler);
       final boolean isMake = context.isMake();
-      ApplicationManager.getApplication().runReadAction(new Runnable() {
+      DumbService.getInstance(project).runReadActionInSmartMode(new Runnable() {
         public void run() {
           try {
             for (FileProcessingCompiler.ProcessingItem item : items) {
diff --git a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
index 3cba065..36021fd 100644
--- a/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
+++ b/java/compiler/impl/src/com/intellij/compiler/impl/GenericCompilerRunner.java
@@ -186,9 +186,8 @@
     final List<GenericCompilerProcessingItem<Item, SourceState, OutputState>> toProcess = new ArrayList<GenericCompilerProcessingItem<Item,SourceState,OutputState>>();
     final THashSet<Key> keySet = new THashSet<Key>(new SourceItemHashingStrategy<Key>(compiler));
     final Ref<IOException> exception = Ref.create(null);
-    DumbService.getInstance(myProject).waitForSmartMode();
     final Map<Item, SourceState> sourceStates = new HashMap<Item,SourceState>();
-    ApplicationManager.getApplication().runReadAction(new Runnable() {
+    DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
       @Override
       public void run() {
         try {
diff --git a/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
index bd919a6..ade4034 100644
--- a/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
+++ b/java/compiler/impl/src/com/intellij/compiler/make/ChangedConstantsDependencyProcessor.java
@@ -24,7 +24,6 @@
 import com.intellij.compiler.impl.ExitException;
 import com.intellij.compiler.impl.ExitStatus;
 import com.intellij.lang.StdLanguages;
-import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.compiler.CompileContext;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProcessCanceledException;
@@ -73,9 +72,7 @@
   public void run() throws CacheCorruptedException, ExitException {
     final Ref<CacheCorruptedException> _ex = new Ref<CacheCorruptedException>();
     final Ref<ExitException> exitException = new Ref<ExitException>(null);
-    DumbService.getInstance(myProject).waitForSmartMode(); // ensure running in smart mode
-
-    ApplicationManager.getApplication().runReadAction(new Runnable() {
+    DumbService.getInstance(myProject).runReadActionInSmartMode(new Runnable() {
       public void run() {
         try {
           final String qName = myDependencyCache.resolve(myQName);
diff --git a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
index 1edb774..d0c7c23 100644
--- a/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
+++ b/java/compiler/impl/src/com/intellij/packaging/impl/compiler/ArtifactsCompilerInstance.java
@@ -151,12 +151,12 @@
       return Collections.emptyList();
     }
 
-    DumbService.getInstance(getProject()).waitForSmartMode();
-    new ReadAction() {
-      protected void run(final Result result) {
+    DumbService.getInstance(getProject()).runReadActionInSmartMode(new Runnable() {
+      @Override
+      public void run() {
         collectItems(artifact, outputPath);
       }
-    }.execute();
+    });
     return new ArrayList<ArtifactCompilerCompileItem>(myBuilderContext.getProcessingItems());
   }
 
diff --git a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
index 220b079..f0f15f2 100644
--- a/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
+++ b/java/compiler/openapi/src/com/intellij/packaging/ui/ArtifactPropertiesEditor.java
@@ -16,6 +16,7 @@
 package com.intellij.packaging.ui;
 
 import com.intellij.openapi.options.UnnamedConfigurable;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author nik
@@ -28,4 +29,9 @@
   public abstract String getTabName();
 
   public abstract void apply();
+
+  @Nullable
+  public String getHelpId() {
+    return null;
+  }
 }
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
index 9074ae6..084f458 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/DebugProcessImpl.java
@@ -762,6 +762,7 @@
         getManagerThread().close();
       }
       finally {
+        final VirtualMachineProxyImpl vm = myVirtualMachineProxy;
         myVirtualMachineProxy = null;
         myPositionManager = null;
         myReturnValueWatcher = null;
@@ -774,6 +775,13 @@
         }
         finally {
           setBreakpointsMuted(false);
+          if (vm != null) {
+            try {
+              vm.dispose(); // to be on the safe side ensure that VM mirror, if present, is disposed and invalidated
+            }
+            catch (Throwable ignored) {
+            }
+          }
           myWaitFor.up();
         }
       }
@@ -1343,8 +1351,12 @@
         else {
           // some VM's (like IBM VM 1.4.2 bundled with WebSpere) does not
           // resume threads on dispose() like it should
-          virtualMachineProxy.resume();
-          virtualMachineProxy.dispose();
+          try {
+            virtualMachineProxy.resume();
+          }
+          finally {
+            virtualMachineProxy.dispose();
+          }
         }
       }
       else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
index e7ef657..aeadbf7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/engine/evaluation/expression/EvaluatorBuilderImpl.java
@@ -23,6 +23,7 @@
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
 import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.debugger.DebuggerBundle;
 import com.intellij.debugger.SourcePosition;
 import com.intellij.debugger.engine.ContextUtil;
@@ -1029,7 +1030,8 @@
 
       if (castType != null && operandType != null && !TypeConversionUtil.areTypesConvertible(operandType, castType)) {
         throw new EvaluateRuntimeException(
-          new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", HighlightUtil.formatType(operandType), HighlightUtil.formatType(castType)))
+          new EvaluateException(JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+            .formatType(castType)))
         );
       }
 
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
index 206aef2..b2e86d4 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.form
@@ -36,7 +36,7 @@
         </children>
       </grid>
       <grid id="763d0" layout-manager="GridLayoutManager" row-count="1" column-count="5" same-size-horizontally="false" same-size-vertically="false" hgap="-1" vgap="-1">
-        <margin top="0" left="5" bottom="0" right="0"/>
+        <margin top="0" left="0" bottom="0" right="0"/>
         <constraints>
           <grid row="1" column="0" row-span="1" col-span="1" vsize-policy="3" hsize-policy="3" anchor="0" fill="3" indent="0" use-parent-layout="true"/>
         </constraints>
@@ -173,7 +173,7 @@
                       <grid row="2" column="0" row-span="1" col-span="1" vsize-policy="0" hsize-policy="3" anchor="8" fill="0" indent="0" use-parent-layout="false"/>
                     </constraints>
                     <properties>
-                      <text value="&amp;Temporary"/>
+                      <text value="&amp;Remove once hit"/>
                     </properties>
                   </component>
                 </children>
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
index f70c6ce..1217e16 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointPropertiesPanel.java
@@ -43,7 +43,6 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.ui.FieldPanel;
 import com.intellij.ui.MultiLineTooltipUI;
-import com.intellij.ui.components.JBCheckBox;
 import com.intellij.ui.popup.util.DetailView;
 import com.intellij.util.IJSwingUtilities;
 import com.intellij.xdebugger.impl.DebuggerSupport;
@@ -533,13 +532,22 @@
     myLogMessageCheckBox.setSelected(breakpoint.LOG_ENABLED);
     myTemporaryCheckBox.setSelected(breakpoint.REMOVE_AFTER_HIT);
     myEnabledCheckbox.setSelected(breakpoint.ENABLED);
-    myEnabledCheckbox.setText(breakpoint.getDisplayName());
+    myEnabledCheckbox.setText(breakpoint.getShortName() + " enabled");
+
+    DebuggerManagerEx.getInstanceEx(myProject).getBreakpointManager().addBreakpointManagerListener(new BreakpointManagerListener() {
+      @Override
+      public void breakpointsChanged() {
+        myEnabledCheckbox.setSelected(myBreakpoint.ENABLED);
+      }
+    });
+
     myEnabledCheckbox.addActionListener(new ActionListener() {
       @Override
       public void actionPerformed(ActionEvent event) {
         if (myBreakpoint.ENABLED != myEnabledCheckbox.isSelected()) {
           myBreakpoint.ENABLED = myEnabledCheckbox.isSelected();
           getBreakpointManager(myProject).fireBreakpointChanged(myBreakpoint);
+          myBreakpoint.updateUI();
         }
       }
     });
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
index abd786f..2da2753 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/BreakpointWithHighlighter.java
@@ -26,11 +26,9 @@
 import com.intellij.debugger.impl.DebuggerContextImpl;
 import com.intellij.debugger.settings.DebuggerSettings;
 import com.intellij.debugger.ui.JavaDebuggerSupport;
-import com.intellij.idea.ActionsBundle;
 import com.intellij.openapi.actionSystem.ActionGroup;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.actionSystem.AnActionEvent;
-import com.intellij.openapi.actionSystem.DefaultActionGroup;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.colors.EditorColorsManager;
@@ -52,8 +50,6 @@
 import com.intellij.util.StringBuilderSpinAllocator;
 import com.intellij.xdebugger.impl.DebuggerSupport;
 import com.intellij.xdebugger.impl.actions.EditBreakpointAction;
-import com.intellij.xdebugger.impl.actions.ViewBreakpointsAction;
-import com.intellij.xdebugger.impl.actions.XDebuggerActions;
 import com.intellij.xdebugger.ui.DebuggerColors;
 import com.intellij.xml.util.XmlStringUtil;
 import com.sun.jdi.ReferenceType;
@@ -346,6 +342,7 @@
         if (debugProcess == null || !debugProcess.isAttached()) {
           updateCaches(null);
           updateGutter();
+
           afterUpdate.run();
         }
         else {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
index 5b94044..052cfd7 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/JavaBreakpointItem.java
@@ -139,6 +139,8 @@
   @Override
   public void setEnabled(boolean state) {
     myBreakpoint.ENABLED = state;
+    myBreakpoint.updateUI();
+    DebuggerManagerEx.getInstanceEx(myBreakpoint.getProject()).getBreakpointManager().fireBreakpointChanged(myBreakpoint);
   }
 
   @Override
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
index 2be7f16..76f1b79 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/breakpoints/LineBreakpoint.java
@@ -125,6 +125,9 @@
 
   protected void createRequestForPreparedClass(final DebugProcessImpl debugProcess, final ReferenceType classType) {
     if (!isInScopeOf(debugProcess, classType.name())) {
+      if (LOG.isDebugEnabled()) {
+        LOG.debug(classType.name() + " is out of debug-process scope, breakpoint request won't be created for line " + getLineIndex());
+      }
       return;
     }
     try {
@@ -186,10 +189,16 @@
       if (breakpointFile != null && fileIndex.isInSourceContent(breakpointFile)) {
         // apply filtering to breakpoints from content sources only, not for sources attached to libraries
         final Collection<VirtualFile> candidates = findClassCandidatesInSourceContent(className, debugProcess.getSearchScope(), fileIndex);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Found "+ (candidates == null? "null" : candidates.size()) + " candidate containing files for class " + className);
+        }
         if (candidates == null) {
           return true;
         }
         for (VirtualFile classFile : candidates) {
+          if (LOG.isDebugEnabled()) {
+            LOG.debug("Breakpoint file: " + breakpointFile.getPath()+ "; candidate file: " + classFile.getPath());
+          }
           if (breakpointFile.equals(classFile)) {
             return true;
           }
@@ -208,12 +217,30 @@
       @Nullable
       public Collection<VirtualFile> compute() {
         final PsiClass[] classes = JavaPsiFacade.getInstance(myProject).findClasses(topLevelClassName, scope);
+        if (LOG.isDebugEnabled()) {
+          LOG.debug("Found "+ classes.length + " classes " + topLevelClassName + " in scope");
+        }
         if (classes.length == 0) {
           return null;
         }
         final List<VirtualFile> list = new ArrayList<VirtualFile>(classes.length);
         for (PsiClass aClass : classes) {
           final PsiFile psiFile = aClass.getContainingFile();
+          
+          if (LOG.isDebugEnabled()) {
+            final StringBuilder msg = new StringBuilder();
+            msg.append("Checking class ").append(aClass.getQualifiedName());
+            msg.append("\n\t").append("PsiFile=").append(psiFile);
+            if (psiFile != null) {
+              final VirtualFile vFile = psiFile.getVirtualFile();
+              msg.append("\n\t").append("VirtualFile=").append(vFile);
+              if (vFile != null) {
+                msg.append("\n\t").append("isInSourceContent=").append(fileIndex.isInSourceContent(vFile));
+              }
+            }
+            LOG.debug(msg.toString());
+          }
+          
           if (psiFile != null) {
             final VirtualFile vFile = psiFile.getVirtualFile();
             if (vFile != null && fileIndex.isInSourceContent(vFile)) {
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
index c23bcfe..32ace10 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/DebuggerTree.java
@@ -324,6 +324,9 @@
     }
     else {
       showMessage(session != null? session.getStateDescription() : DebuggerBundle.message("status.debug.stopped"));
+      if (session == null || session.isStopped()) {
+        getNodeFactory().clearHistory(); // save memory by clearing references on JDI objects
+      }
     }
   }
 
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
index 905f7b0..53e820d 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/NodeManagerImpl.java
@@ -122,10 +122,14 @@
   }
 
   public void dispose() {
-    myHistories.clear();
+    clearHistory();
     super.dispose();
   }
 
+  public void clearHistory() {
+    myHistories.clear();
+  }
+
   private DebuggerTree getTree() {
     return myDebuggerTree;
   }
diff --git a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
index 3e11145..098c42c 100644
--- a/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
+++ b/java/debugger/impl/src/com/intellij/debugger/ui/impl/watch/ValueDescriptorImpl.java
@@ -217,6 +217,9 @@
       }
       catch (ClassNotLoadedException ignored) {
       }
+      catch (Throwable e) {
+        LOG.info(e); // catch all exceptions to ensure the method returns gracefully
+      }
     }
     return exceptionObj;
   }
diff --git a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
index 1fe5df7..6052487 100644
--- a/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
+++ b/java/execution/impl/src/com/intellij/execution/ui/AlternativeJREPanel.java
@@ -22,6 +22,7 @@
 import com.intellij.openapi.ui.ComponentWithBrowseButton;
 import com.intellij.openapi.ui.TextComponentAccessor;
 import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.ui.GuiUtils;
 import com.intellij.ui.InsertPathAction;
 import com.intellij.ui.PanelWithAnchor;
@@ -49,6 +50,12 @@
 
     myFieldWithHistory = new TextFieldWithHistory();
     final ArrayList<String> foundJDKs = new ArrayList<String>();
+    for (JreProvider provider : JreProvider.EP_NAME.getExtensions()) {
+      String path = provider.getJrePath();
+      if (!StringUtil.isEmpty(path)) {
+        foundJDKs.add(path);
+      }
+    }
     final Sdk[] allJDKs = ProjectJdkTable.getInstance().getAllJdks();
     for (Sdk jdk : allJDKs) {
       foundJDKs.add(jdk.getHomePath());
diff --git a/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java b/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java
new file mode 100644
index 0000000..9b70053
--- /dev/null
+++ b/java/execution/impl/src/com/intellij/execution/ui/JreProvider.java
@@ -0,0 +1,33 @@
+/*
+ * 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.execution.ui;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Extension point for providing custom jre to be shown at run configuration control.
+ * 
+ * @author Denis Zhdanov
+ * @since 5/9/13 10:04 PM
+ */
+public interface JreProvider {
+
+  ExtensionPointName<JreProvider> EP_NAME = new ExtensionPointName<JreProvider>("com.intellij.jreProvider");
+  
+  @NotNull
+  String getJrePath();
+}
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java b/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
index bd626e5..02bf071 100644
--- a/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkGroup.java
@@ -9,7 +9,7 @@
 /**
  * @author nik
  */
-public abstract class FrameworkGroup {
+public abstract class FrameworkGroup<V extends FrameworkGroupVersion> {
   private final String myId;
 
   public FrameworkGroup(String id) {
@@ -28,7 +28,7 @@
   public abstract Icon getIcon();
 
   @NotNull
-  public List<String> getGroupVersions() {
+  public List<V> getGroupVersions() {
     return Collections.emptyList();
   }
 }
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java b/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java
new file mode 100644
index 0000000..ea0f310
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkGroupVersion.java
@@ -0,0 +1,11 @@
+package com.intellij.framework;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface FrameworkGroupVersion {
+  @NotNull String getId();
+  @NotNull String getPresentableName();
+}
diff --git a/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java b/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
index 4c8e59e..02c0298 100644
--- a/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
+++ b/java/idea-ui/src/com/intellij/framework/FrameworkTypeEx.java
@@ -31,7 +31,7 @@
   }
 
   @Nullable
-  public FrameworkGroup getParentGroup() {
+  public FrameworkGroup<?> getParentGroup() {
     return null;
   }
 
diff --git a/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java b/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
index f5e3304..dbaa6d0 100644
--- a/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
+++ b/java/idea-ui/src/com/intellij/framework/library/impl/DownloadableLibraryServiceImpl.java
@@ -15,11 +15,14 @@
  */
 package com.intellij.framework.library.impl;
 
-import com.intellij.framework.library.DownloadableLibraryDescription;
-import com.intellij.framework.library.DownloadableLibraryService;
-import com.intellij.framework.library.DownloadableLibraryType;
-import com.intellij.framework.library.LibraryVersionProperties;
+import com.intellij.facet.frameworks.beans.Artifact;
+import com.intellij.facet.frameworks.beans.RequiredFrameworkVersion;
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
+import com.intellij.framework.library.*;
 import com.intellij.ide.util.frameworkSupport.CustomLibraryDescriptionImpl;
+import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
+import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.roots.libraries.LibraryType;
 import com.intellij.openapi.roots.libraries.ui.LibraryEditorComponent;
@@ -37,8 +40,18 @@
 
   @NotNull
   @Override
-  public DownloadableLibraryDescription createLibraryDescription(@NotNull String groupId, @NotNull URL... localUrls) {
-    return new LibraryVersionsFetcher(groupId, localUrls);
+  public DownloadableLibraryDescription createLibraryDescription(@NotNull String groupId, @NotNull final URL... localUrls) {
+    return new LibraryVersionsFetcher(groupId, localUrls) {
+      //todo[nik] pull up this method after moving corresponding API to lang-api
+      @NotNull
+      protected FrameworkAvailabilityFilter createAvailabilityFilter(Artifact version) {
+        RequiredFrameworkVersion groupVersion = version.getRequiredFrameworkVersion();
+        if (groupVersion != null) {
+          return new FrameworkLibraryAvailabilityFilter(groupVersion.myGroupId, groupVersion.myVersion);
+        }
+        return FrameworkAvailabilityFilter.ALWAYS;
+      }
+    };
   }
 
   @NotNull
@@ -56,4 +69,26 @@
                                                                  @NotNull DownloadableLibraryType libraryType) {
     return new DownloadableLibraryPropertiesEditor(description, editorComponent, libraryType);
   }
+
+  private static class FrameworkLibraryAvailabilityFilter extends FrameworkAvailabilityFilter {
+    private final String myGroupId;
+    private final String myVersionId;
+
+    public FrameworkLibraryAvailabilityFilter(String groupId, String versionId) {
+      myGroupId = groupId;
+      myVersionId = versionId;
+    }
+
+    @Override
+    public boolean isAvailable(@NotNull FrameworkSupportModel model) {
+      FrameworkSupportModelBase modelBase = (FrameworkSupportModelBase)model;
+      for (FrameworkGroup<?> group : modelBase.getFrameworkGroups()) {
+        if (group.getId().equals(myGroupId)) {
+          FrameworkGroupVersion selectedVersion = modelBase.getSelectedVersion(group);
+          return selectedVersion != null && myVersionId.equals(selectedVersion.getId());
+        }
+      }
+      return true;
+    }
+  }
 }
diff --git a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
index 7e53c09..1adad9b 100644
--- a/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
+++ b/java/idea-ui/src/com/intellij/ide/util/frameworkSupport/OldCustomLibraryDescription.java
@@ -20,6 +20,7 @@
 import com.intellij.facet.ui.libraries.LibraryInfo;
 import com.intellij.framework.library.DownloadableLibraryDescription;
 import com.intellij.framework.library.DownloadableLibraryFileDescription;
+import com.intellij.framework.library.FrameworkAvailabilityFilter;
 import com.intellij.framework.library.FrameworkLibraryVersion;
 import com.intellij.framework.library.impl.DownloadableLibraryDescriptionImpl;
 import com.intellij.framework.library.impl.DownloadableLibraryFileDescriptionImpl;
@@ -61,7 +62,7 @@
                                                                    downloadingInfo.getFileNameSuffix(), null, null, false));
         }
       }
-      libraryVersions.add(new FrameworkLibraryVersionImpl(version.getVersionName(), downloads, version.getLibraryName()));
+      libraryVersions.add(new FrameworkLibraryVersionImpl(version.getVersionName(), FrameworkAvailabilityFilter.ALWAYS, downloads, version.getLibraryName()));
     }
     myDownloadableDescription = !libraryVersions.isEmpty() ? new DownloadableLibraryDescriptionImpl(libraryVersions) : null;
   }
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
index bb54043..7cccf0a 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/AddSupportForFrameworksPanel.java
@@ -34,14 +34,11 @@
 import com.intellij.openapi.roots.ModifiableRootModel;
 import com.intellij.openapi.roots.libraries.Library;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
-import com.intellij.openapi.ui.ComboBox;
 import com.intellij.openapi.ui.Splitter;
-import com.intellij.openapi.ui.VerticalFlowLayout;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.ui.CheckedTreeNode;
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.ui.FormBuilder;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -69,7 +66,7 @@
   private final JPanel myOptionsPanel;
   private final FrameworksTree myFrameworksTree;
   private final Map<FrameworkSupportNode, FrameworkSupportOptionsComponent> myInitializedOptionsComponents = new HashMap<FrameworkSupportNode, FrameworkSupportOptionsComponent>();
-  private final Map<FrameworkGroup, JPanel> myInitializedGroupPanels = new HashMap<FrameworkGroup, JPanel>();
+  private final Map<FrameworkGroup<?>, JPanel> myInitializedGroupPanels = new HashMap<FrameworkGroup<?>, JPanel>();
   private FrameworkSupportNodeBase myLastSelectedNode;
 
   public AddSupportForFrameworksPanel(final List<FrameworkSupportInModuleProvider> providers, final FrameworkSupportModelBase model) {
@@ -151,7 +148,7 @@
       frameworkSupportNode.getConfigurable().onFrameworkSelectionChanged(node.isChecked());
     }
     else if (node instanceof FrameworkGroupNode) {
-      FrameworkGroup group = ((FrameworkGroupNode)node).getGroup();
+      FrameworkGroup<?> group = ((FrameworkGroupNode)node).getGroup();
       initializeGroupPanel(group);
       showCard(group.getId());
     }
@@ -160,19 +157,11 @@
     }
   }
 
-  private void initializeGroupPanel(FrameworkGroup group) {
+  private void initializeGroupPanel(FrameworkGroup<?> group) {
     if (!myInitializedGroupPanels.containsKey(group)) {
-      JPanel panel = new JPanel(new VerticalFlowLayout());
-      List<String> versions = group.getGroupVersions();
-      if (!versions.isEmpty()) {
-        ComboBox versionsBox = new ComboBox();
-        for (String version : versions) {
-          versionsBox.addItem(version);
-        }
-        panel.add(FormBuilder.createFormBuilder().addLabeledComponent("Version:", versionsBox).getPanel());
-      }
-      myInitializedGroupPanels.put(group, panel);
-      myOptionsPanel.add(group.getId(), panel);
+      FrameworkGroupOptionsComponent component = new FrameworkGroupOptionsComponent(group, myModel);
+      myInitializedGroupPanels.put(group, component.getMainPanel());
+      myOptionsPanel.add(group.getId(), component.getMainPanel());
     }
   }
 
@@ -188,6 +177,9 @@
       if (parentNode instanceof FrameworkSupportNode) {
         initializeOptionsPanel((FrameworkSupportNode)parentNode);
       }
+      else if (parentNode instanceof FrameworkGroupNode) {
+        initializeGroupPanel(((FrameworkGroupNode)parentNode).getGroup());
+      }
 
       FrameworkSupportOptionsComponent optionsComponent = new FrameworkSupportOptionsComponent(myModel, myLibrariesContainer, this,
                                                                                                node.getProvider(), node.getConfigurable());
@@ -227,7 +219,7 @@
 
   private void createNodes() {
     Map<String, FrameworkSupportNode> nodes = new HashMap<String, FrameworkSupportNode>();
-    Map<FrameworkGroup, FrameworkGroupNode> groups = new HashMap<FrameworkGroup, FrameworkGroupNode>();
+    Map<FrameworkGroup<?>, FrameworkGroupNode> groups = new HashMap<FrameworkGroup<?>, FrameworkGroupNode>();
     List<FrameworkSupportNodeBase> roots = new ArrayList<FrameworkSupportNodeBase>();
     for (FrameworkSupportInModuleProvider provider : myProviders) {
       createNode(provider, nodes, groups, roots);
@@ -239,13 +231,13 @@
 
   @Nullable
   private FrameworkSupportNode createNode(final FrameworkSupportInModuleProvider provider, final Map<String, FrameworkSupportNode> nodes,
-                                          final Map<FrameworkGroup, FrameworkGroupNode> groupNodes,
+                                          final Map<FrameworkGroup<?>, FrameworkGroupNode> groupNodes,
                                           List<FrameworkSupportNodeBase> roots) {
     FrameworkSupportNode node = nodes.get(provider.getFrameworkType().getId());
     if (node == null) {
       String underlyingTypeId = provider.getFrameworkType().getUnderlyingFrameworkTypeId();
       FrameworkSupportNodeBase parentNode = null;
-      final FrameworkGroup group = provider.getFrameworkType().getParentGroup();
+      final FrameworkGroup<?> group = provider.getFrameworkType().getParentGroup();
       if (underlyingTypeId != null) {
         FrameworkSupportInModuleProvider parentProvider = FrameworkSupportUtil.findProvider(underlyingTypeId, myProviders);
         if (parentProvider == null) {
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
index 2a513d3..807110f 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupNode.java
@@ -9,14 +9,14 @@
  * @author nik
  */
 public class FrameworkGroupNode extends FrameworkSupportNodeBase {
-  private final FrameworkGroup myGroup;
+  private final FrameworkGroup<?> myGroup;
 
-  public FrameworkGroupNode(@NotNull FrameworkGroup group, FrameworkSupportNodeBase parent) {
+  public FrameworkGroupNode(@NotNull FrameworkGroup<?> group, FrameworkSupportNodeBase parent) {
     super(group, parent);
     myGroup = group;
   }
 
-  public FrameworkGroup getGroup() {
+  public FrameworkGroup<?> getGroup() {
     return myGroup;
   }
 
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java
new file mode 100644
index 0000000..b83dd0c
--- /dev/null
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkGroupOptionsComponent.java
@@ -0,0 +1,53 @@
+package com.intellij.ide.util.newProjectWizard;
+
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
+import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
+import com.intellij.openapi.ui.ComboBox;
+import com.intellij.openapi.ui.VerticalFlowLayout;
+import com.intellij.ui.ListCellRendererWrapper;
+import com.intellij.util.ui.FormBuilder;
+
+import javax.swing.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+import java.util.List;
+
+/**
+ * @author nik
+ */
+public class FrameworkGroupOptionsComponent {
+  private final JPanel myMainPanel;
+
+  public FrameworkGroupOptionsComponent(final FrameworkGroup<?> group, final FrameworkSupportModelBase model) {
+    JPanel panel = new JPanel(new VerticalFlowLayout());
+    List<? extends FrameworkGroupVersion> versions = group.getGroupVersions();
+    if (!versions.isEmpty()) {
+      final ComboBox versionsBox = new ComboBox();
+      versionsBox.setRenderer(new ListCellRendererWrapper<FrameworkGroupVersion>() {
+        @Override
+        public void customize(JList list, FrameworkGroupVersion value, int index, boolean selected, boolean hasFocus) {
+          setText(value != null ? value.getPresentableName() : "");
+        }
+      });
+      versionsBox.addActionListener(new ActionListener() {
+        @Override
+        public void actionPerformed(ActionEvent e) {
+          model.setSelectedVersion(group, (FrameworkGroupVersion)versionsBox.getSelectedItem());
+        }
+      });
+      for (FrameworkGroupVersion version : versions) {
+        versionsBox.addItem(version);
+      }
+      FrameworkGroupVersion latestVersion = versions.get(versions.size() - 1);
+      versionsBox.setSelectedItem(latestVersion);
+      model.setSelectedVersion(group, latestVersion);
+      panel.add(FormBuilder.createFormBuilder().addLabeledComponent("Version:", versionsBox).getPanel());
+    }
+    myMainPanel = panel;
+  }
+
+  public JPanel getMainPanel() {
+    return myMainPanel;
+  }
+}
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
index 6b5e1f7..0f84009 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/FrameworkSupportOptionsComponent.java
@@ -19,6 +19,9 @@
 import com.intellij.facet.impl.ui.libraries.LibraryOptionsPanel;
 import com.intellij.framework.addSupport.FrameworkSupportInModuleConfigurable;
 import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
+import com.intellij.framework.library.FrameworkLibraryVersion;
+import com.intellij.framework.library.FrameworkLibraryVersionFilter;
+import com.intellij.framework.library.impl.FrameworkLibraryVersionImpl;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurableListener;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelAdapter;
 import com.intellij.ide.util.newProjectWizard.impl.FrameworkSupportModelBase;
@@ -29,6 +32,7 @@
 import com.intellij.openapi.util.Disposer;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.SeparatorFactory;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
@@ -82,7 +86,7 @@
 
     final CustomLibraryDescription description = myConfigurable.createLibraryDescription();
     if (description != null) {
-      myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), myConfigurable.getLibraryVersionFilter(),
+      myLibraryOptionsPanel = new LibraryOptionsPanel(description, myModel.getBaseDirectoryForLibrariesPath(), createLibraryVersionFilter(),
                                                       container, !myConfigurable.isOnlyLibraryAdded());
       Disposer.register(myConfigurable, myLibraryOptionsPanel);
       if (addSeparator) {
@@ -98,11 +102,20 @@
   public void updateLibrariesPanel() {
     if (myLibraryOptionsPanel != null) {
       myLibraryOptionsPanel.changeBaseDirectoryPath(myModel.getBaseDirectoryForLibrariesPath());
-      myLibraryOptionsPanel.setVersionFilter(myConfigurable.getLibraryVersionFilter());
+      myLibraryOptionsPanel.setVersionFilter(createLibraryVersionFilter());
       myLibraryOptionsPanelWrapper.setVisible(myConfigurable.isVisible());
     }
   }
 
+  private FrameworkLibraryVersionFilter createLibraryVersionFilter() {
+    return new FrameworkLibraryVersionFilter() {
+      @Override
+      public boolean isAccepted(@NotNull FrameworkLibraryVersion version) {
+        return myConfigurable.getLibraryVersionFilter().isAccepted(version) && ((FrameworkLibraryVersionImpl)version).getAvailabilityFilter().isAvailable(myModel);
+      }
+    };
+  }
+
 
   public JPanel getMainPanel() {
     return myMainPanel;
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
index afb5c60..cfdcf81 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/SelectTemplateStep.java
@@ -305,7 +305,6 @@
 
   @Override
   public void addSettingsField(@NotNull String label, @NotNull JComponent field) {
-
     JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
     addField(label, field, panel);
   }
@@ -321,8 +320,9 @@
 
   @Override
   public void addSettingsComponent(@NotNull JComponent component) {
-    myNamePathComponent.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
-                                                        GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
+    JPanel panel = myWizardContext.isCreatingNewProject() ? myNamePathComponent : myModulePanel;
+    panel.add(component, new GridBagConstraints(0, GridBagConstraints.RELATIVE, 2, 1, 1.0, 0, GridBagConstraints.NORTHWEST,
+                                                   GridBagConstraints.HORIZONTAL, new Insets(0, 0, 0, 0), 0, 0));
   }
 
   @Override
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
index e82e67e..acfa5e8 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/impl/FrameworkSupportModelBase.java
@@ -15,24 +15,26 @@
  */
 package com.intellij.ide.util.newProjectWizard.impl;
 
+import com.intellij.framework.FrameworkGroup;
+import com.intellij.framework.FrameworkGroupVersion;
 import com.intellij.framework.addSupport.FrameworkSupportInModuleProvider;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportConfigurable;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportModel;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportModelListener;
 import com.intellij.ide.util.frameworkSupport.FrameworkSupportProvider;
-import com.intellij.ide.util.newProjectWizard.FrameworkSupportNode;
-import com.intellij.ide.util.newProjectWizard.FrameworkSupportOptionsComponent;
-import com.intellij.ide.util.newProjectWizard.OldFrameworkSupportProviderWrapper;
+import com.intellij.ide.util.newProjectWizard.*;
 import com.intellij.ide.util.projectWizard.ModuleBuilder;
 import com.intellij.openapi.Disposable;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ui.configuration.projectRoot.LibrariesContainer;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.UserDataHolderBase;
 import com.intellij.util.EventDispatcher;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
+import java.util.Collection;
 import java.util.HashMap;
 import java.util.Map;
 
@@ -46,6 +48,7 @@
   private final EventDispatcher<FrameworkSupportModelListener> myDispatcher = EventDispatcher.create(FrameworkSupportModelListener.class);
   private final Map<String, FrameworkSupportNode> mySettingsMap = new HashMap<String, FrameworkSupportNode>();
   private final Map<String, FrameworkSupportOptionsComponent> myOptionsComponentsMap = new HashMap<String, FrameworkSupportOptionsComponent>();
+  private final Map<FrameworkGroup<?>, FrameworkGroupVersion> mySelectedVersions = new HashMap<FrameworkGroup<?>, FrameworkGroupVersion>();
 
   public FrameworkSupportModelBase(final @Nullable Project project, @Nullable ModuleBuilder builder, @NotNull LibrariesContainer librariesContainer) {
     myProject = project;
@@ -123,6 +126,36 @@
     return ((OldFrameworkSupportProviderWrapper.FrameworkSupportConfigurableWrapper)node.getConfigurable()).getConfigurable();
   }
 
+  public void setSelectedVersion(@NotNull FrameworkGroup<?> group, @Nullable FrameworkGroupVersion version) {
+    FrameworkGroupVersion oldVersion = mySelectedVersions.put(group, version);
+    if (!Comparing.equal(oldVersion, version)) {
+      for (Map.Entry<String, FrameworkSupportNode> entry : mySettingsMap.entrySet()) {
+        FrameworkGroup<?> parentGroup = getParentGroup(entry.getValue());
+        if (group.equals(parentGroup)) {
+          updateFrameworkLibraryComponent(entry.getKey());
+        }
+      }
+    }
+  }
+
+  @Nullable
+  private static FrameworkGroup<?> getParentGroup(final FrameworkSupportNode node) {
+    FrameworkSupportNodeBase current = node;
+    while (current instanceof FrameworkSupportNode) {
+      current = current.getParentNode();
+    }
+    return current instanceof FrameworkGroupNode ? ((FrameworkGroupNode)current).getGroup() : null;
+  }
+
+  public Collection<FrameworkGroup<?>> getFrameworkGroups() {
+    return mySelectedVersions.keySet();
+  }
+
+  @Nullable
+  public <V extends FrameworkGroupVersion> V getSelectedVersion(@NotNull FrameworkGroup<V> group) {
+    return (V)mySelectedVersions.get(group);
+  }
+
   public void onFrameworkSelectionChanged(FrameworkSupportNode node) {
     final FrameworkSupportModelListener multicaster = myDispatcher.getMulticaster();
     final FrameworkSupportInModuleProvider provider = node.getProvider();
diff --git a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
index cb66981..e8f8c90 100644
--- a/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
+++ b/java/idea-ui/src/com/intellij/ide/util/newProjectWizard/modes/CreateFromTemplateMode.java
@@ -22,12 +22,9 @@
 import com.intellij.ide.util.projectWizard.WizardContext;
 import com.intellij.openapi.project.ProjectBundle;
 import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
-import com.intellij.openapi.util.Condition;
-import com.intellij.platform.DirectoryProjectGenerator;
 import com.intellij.platform.ProjectTemplate;
 import com.intellij.platform.ProjectTemplatesFactory;
 import com.intellij.platform.templates.LocalArchivedTemplate;
-import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -44,12 +41,6 @@
  */
 public class CreateFromTemplateMode extends WizardMode {
 
-  private static final Condition<ProjectTemplate> TEMPLATE_CONDITION = new Condition<ProjectTemplate>() {
-    @Override
-    public boolean value(ProjectTemplate template) {
-      return !(template instanceof DirectoryProjectGenerator);
-    }
-  };
   private SelectTemplateStep mySelectTemplateStep;
 
   public static MultiMap<TemplatesGroup, ProjectTemplate> getTemplatesMap(WizardContext context) {
@@ -58,8 +49,7 @@
     for (ProjectTemplatesFactory factory : factories) {
       for (String group : factory.getGroups()) {
         ProjectTemplate[] templates = factory.createTemplates(group, context);
-        List<ProjectTemplate> values = context.isCreatingNewProject() ? Arrays.asList(templates) : ContainerUtil.filter(templates,
-                                                                                                                        TEMPLATE_CONDITION);
+        List<ProjectTemplate> values = Arrays.asList(templates);
         if (!values.isEmpty()) {
           Icon icon = factory.getGroupIcon(group);
           TemplatesGroup templatesGroup = new TemplatesGroup(group, null, icon, factory.getGroupWeight(group));
diff --git a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
index 8f380dd..0f8e3c3 100644
--- a/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
+++ b/java/idea-ui/src/com/intellij/ide/util/projectWizard/ProjectWizardUtil.java
@@ -46,7 +46,7 @@
     if (!dir.exists()) {
       if (promptUser) {
         final int answer = Messages.showOkCancelDialog(IdeBundle.message("promot.projectwizard.directory.does.not.exist", promptPrefix,
-                                                                         dir.getPath(), ApplicationNamesInfo.getInstance().getProductName()),
+                                                                         dir.getPath(), ApplicationNamesInfo.getInstance().getFullProductName()),
                                                        IdeBundle.message("title.directory.does.not.exist"), Messages.getQuestionIcon());
         if (answer != 0) {
           return false;
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
index cdea51f..47e9015 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/ModuleEditor.java
@@ -189,7 +189,16 @@
     ModuleConfigurationEditorProvider[] providers = collectProviders(module);
     ModuleConfigurationState state = createModuleConfigurationState();
     for (ModuleConfigurationEditorProvider provider : providers) {
-      ContainerUtil.addAll(myEditors, provider.createEditors(state));
+      ModuleConfigurationEditor[] editors = provider.createEditors(state);
+      if (editors.length > 0 && provider instanceof ModuleConfigurationEditorProviderEx &&
+          ((ModuleConfigurationEditorProviderEx)provider).isCompleteEditorSet()) {
+        myEditors.clear();
+        ContainerUtil.addAll(myEditors, editors);
+        break;
+      }
+      else {
+        ContainerUtil.addAll(myEditors, editors);
+      }
     }
 
     for (final Configurable moduleConfigurable : myModule.getComponents(Configurable.class)) {
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
index 8fe693c..f3c4102 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactEditorImpl.java
@@ -554,7 +554,7 @@
     if (tab == 0) {
       return "reference.project.structure.artifacts.output";
     }
-    String helpId = ArtifactPropertiesEditors.getHelpId(myTabbedPane.getSelectedTitle());
+    String helpId = myPropertiesEditors.getHelpId(myTabbedPane.getSelectedTitle());
     return helpId != null ? helpId : "reference.settingsdialog.project.structure.artifacts";
   }
 
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
index 53b0bc1..1828daa 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/artifacts/ArtifactPropertiesEditors.java
@@ -108,7 +108,7 @@
   }
 
   @Nullable
-  public static String getHelpId(String title) {
+  public String getHelpId(String title) {
     if (ArtifactPropertiesEditor.VALIDATION_TAB.equals(title)) {
       return "reference.project.structure.artifacts.validation";
     }
@@ -118,6 +118,12 @@
     else if (ArtifactPropertiesEditor.POST_PROCESSING_TAB.equals(title)) {
       return "reference.project.structure.artifacts.postprocessing";
     }
+    for (PropertiesEditorInfo editorInfo : myEditors) {
+      final ArtifactPropertiesEditor editor = editorInfo.myEditor;
+      if (editor.getTabName().equals(title)) {
+        return editor.getHelpId();
+      }
+    }
     return null;
   }
 
diff --git a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
index b5881c1..0614771 100644
--- a/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
+++ b/java/idea-ui/src/com/intellij/openapi/roots/ui/configuration/projectRoot/ModuleStructureConfigurable.java
@@ -330,8 +330,7 @@
           return moduleStructureExtension.getNodeComparator();
         }
       });
-    comparators.add(NODE_COMPARATOR);
-    return new MergingComparator<MyNode>(comparators);
+    return new MergingComparator<MyNode>(ContainerUtil.concat(comparators, Collections.singletonList(NODE_COMPARATOR)));
   }
 
   @Override
@@ -678,7 +677,7 @@
       extension.copy(configurable, TREE_UPDATER);
     }
   }
-  
+
   private class MyDataProviderWrapper extends JPanel implements DataProvider {
     public MyDataProviderWrapper(final JComponent component) {
       super(new BorderLayout());
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
index f11f627..adc9ddd 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ArchivedProjectTemplate.java
@@ -36,7 +36,7 @@
 
   protected final String myDisplayName;
 
-  public ArchivedProjectTemplate(String displayName) {
+  public ArchivedProjectTemplate(@NotNull String displayName) {
     myDisplayName = displayName;
   }
 
diff --git a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
index 00563cf..1b9f3c2 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/LocalArchivedTemplate.java
@@ -51,8 +51,9 @@
   private List<WizardInputField> myInputFields = Collections.emptyList();
   private Icon myIcon;
 
-  public LocalArchivedTemplate(String displayName,
-                               URL archivePath, ClassLoader classLoader) {
+  public LocalArchivedTemplate(@NotNull String displayName,
+                               @NotNull URL archivePath,
+                               @NotNull ClassLoader classLoader) {
     super(displayName);
 
     myArchivePath = archivePath;
diff --git a/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java b/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
index 81d9b7f..3a8a97b 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/ManageProjectTemplatesDialog.java
@@ -35,7 +35,6 @@
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.io.File;
-import java.net.URISyntaxException;
 import java.net.URL;
 import java.util.Arrays;
 
@@ -61,11 +60,7 @@
         super.remove(index);
         if (template instanceof LocalArchivedTemplate) {
           URL path = ((LocalArchivedTemplate)template).getArchivePath();
-          try {
-            new File(path.toURI()).delete();
-          }
-          catch (URISyntaxException ignore) {
-          }
+          new File(path.getPath()).delete();
         }
       }
     };
diff --git a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
index 3ce17ab..adea904 100644
--- a/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
+++ b/java/idea-ui/src/com/intellij/platform/templates/PlainModuleTemplatesFactory.java
@@ -28,6 +28,7 @@
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
+import java.util.HashSet;
 import java.util.List;
 import java.util.Set;
 
@@ -47,8 +48,9 @@
         return builder.getGroupName();
       }
     });
-    groups.add(OTHER_GROUP);
-    return ArrayUtil.toStringArray(groups);
+    HashSet<String> set = new HashSet<String>(groups);
+    set.add(OTHER_GROUP);
+    return ArrayUtil.toStringArray(set);
   }
 
   @NotNull
diff --git a/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java b/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
index 1c96c8d..6a5d840 100644
--- a/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
+++ b/java/java-analysis-api/src/com/intellij/codeInspection/BatchSuppressManager.java
@@ -26,6 +26,8 @@
 import java.util.Collection;
 
 public interface BatchSuppressManager {
+  String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
+
   class SERVICE {
     public static BatchSuppressManager getInstance() {
       return ServiceManager.getService(BatchSuppressManager.class);
diff --git a/java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java b/java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
similarity index 87%
rename from java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
rename to java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
index 9a0fb12..1bf588c 100644
--- a/java/java-psi-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
+++ b/java/java-analysis-api/src/com/intellij/openapi/module/EffectiveLanguageLevelUtil.java
@@ -25,7 +25,8 @@
   @NotNull
   public static LanguageLevel getEffectiveLanguageLevel(@NotNull final Module module) {
     ApplicationManager.getApplication().assertReadAccessAllowed();
-    LanguageLevel level = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+    LanguageLevelModuleExtension moduleLevel = LanguageLevelModuleExtension.getInstance(module);
+    LanguageLevel level = moduleLevel == null ? null : moduleLevel.getLanguageLevel();
     if (level != null) return level;
     return LanguageLevelProjectExtension.getInstance(module.getProject()).getLanguageLevel();
   }
diff --git a/java/java-psi-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java b/java/java-analysis-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
similarity index 100%
rename from java/java-psi-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
rename to java/java-analysis-api/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
diff --git a/java/java-analysis-impl/java-analysis-impl.iml b/java/java-analysis-impl/java-analysis-impl.iml
index d4756de..ad06d8c 100644
--- a/java/java-analysis-impl/java-analysis-impl.iml
+++ b/java/java-analysis-impl/java-analysis-impl.iml
@@ -12,6 +12,7 @@
     <orderEntry type="module" module-name="java-psi-impl" exported="" />
     <orderEntry type="module" module-name="projectModel-impl" exported="" />
     <orderEntry type="module" module-name="java-analysis-api" exported="" />
+    <orderEntry type="module" module-name="resources-en" />
   </component>
 </module>
 
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java
new file mode 100644
index 0000000..8e29318
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaGenericsUtil.java
@@ -0,0 +1,298 @@
+/*
+ * 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.codeInsight.daemon.impl.analysis;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Iterator;
+
+public class JavaGenericsUtil {
+  public static boolean isReifiableType(PsiType type) {
+    if (type instanceof PsiArrayType) {
+      return isReifiableType(((PsiArrayType)type).getComponentType());
+    }
+
+    if (type instanceof PsiPrimitiveType) {
+      return true;
+    }
+
+    if (PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) {
+      return false;
+    }
+
+    if (type instanceof PsiClassType) {
+      final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type);
+      if (classType.isRaw()) {
+        return true;
+      }
+      PsiType[] parameters = classType.getParameters();
+
+      for (PsiType parameter : parameters) {
+        if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) {
+          return true;
+        }
+      }
+      final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
+      if (resolved instanceof PsiTypeParameter) {
+        return false;
+      }
+      if (parameters.length == 0) {
+        if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
+          final PsiClass containingClass = resolved.getContainingClass();
+          if (containingClass != null) {
+            final PsiTypeParameter[] containingClassTypeParameters = containingClass.getTypeParameters();
+            if (containingClassTypeParameters.length > 0) {
+              return false;
+            }
+          }
+        }
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, JavaResolveResult resolveResult) {
+    final PsiElement resolve = resolveResult.getElement();
+    if (resolve instanceof PsiMethod) {
+      final PsiMethod psiMethod = (PsiMethod)resolve;
+
+      final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression);
+
+      if (psiMethod.isVarArgs()) {
+        if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) {
+          final int parametersCount = psiMethod.getParameterList().getParametersCount();
+          final PsiParameter varargParameter =
+            psiMethod.getParameterList().getParameters()[parametersCount - 1];
+          final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType();
+          if (!isReifiableType(resolveResult.getSubstitutor().substitute(componentType))) {
+            final PsiElement parent = expression.getParent();
+            if (parent instanceof PsiCall) {
+              final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
+              if (argumentList != null) {
+                final PsiExpression[] args = argumentList.getExpressions();
+                if (args.length == parametersCount) {
+                  final PsiExpression lastArg = args[args.length - 1];
+                  if (lastArg instanceof PsiReferenceExpression) {
+                    final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve();
+                    if (lastArgsResolve instanceof PsiParameter) {
+                      if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) {
+                        return false;
+                      }
+                    }
+                  }
+                  else if (lastArg instanceof PsiMethodCallExpression) {
+                    if (lastArg.getType() instanceof PsiArrayType) {
+                      return false;
+                    }
+                  }
+                }
+                for (int i = parametersCount - 1; i < args.length; i++) {
+                  if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))) {
+                    return true;
+                  }
+                }
+                return args.length < parametersCount;
+              }
+            }
+          }
+        }
+      }
+    }
+    return false;
+  }
+
+  public static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
+    if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false;
+
+    castType = castType.getDeepComponentType();
+    if (castType instanceof PsiClassType) {
+      final PsiClassType castClassType = (PsiClassType)castType;
+      operandType = operandType.getDeepComponentType();
+
+      if (!(operandType instanceof PsiClassType)) return false;
+      final PsiClassType operandClassType = (PsiClassType)operandType;
+      final PsiClassType.ClassResolveResult castResult = castClassType.resolveGenerics();
+      final PsiClassType.ClassResolveResult operandResult = operandClassType.resolveGenerics();
+      final PsiClass operandClass = operandResult.getElement();
+      final PsiClass castClass = castResult.getElement();
+
+      if (operandClass == null || castClass == null) return false;
+      if (castClass instanceof PsiTypeParameter) return true;
+
+      if (castClassType.hasNonTrivialParameters()) {
+        if (operandClassType.isRaw()) return true;
+        if (castClass.isInheritor(operandClass, true)) {
+          PsiSubstitutor castSubstitutor = castResult.getSubstitutor();
+          PsiElementFactory factory = JavaPsiFacade.getInstance(castClass.getProject()).getElementFactory();
+          for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(castClass)) {
+            PsiSubstitutor modifiedSubstitutor = castSubstitutor.put(typeParameter, null);
+            PsiClassType otherType = factory.createType(castClass, modifiedSubstitutor);
+            if (TypeConversionUtil.isAssignable(operandType, otherType, false)) return true;
+          }
+          for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(operandClass)) {
+            final PsiType operand = operandResult.getSubstitutor().substitute(typeParameter);
+            if (operand instanceof PsiCapturedWildcardType) return true;
+          }
+          return false;
+        }
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  public static boolean isRawToGeneric(PsiType lType, PsiType rType) {
+    if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false;
+    if (lType.equals(rType)) return false;
+    if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) {
+      return isRawToGeneric(((PsiArrayType)lType).getComponentType(), ((PsiArrayType)rType).getComponentType());
+    }
+    if (lType instanceof PsiArrayType || rType instanceof PsiArrayType) return false;
+
+    if (rType instanceof PsiIntersectionType) {
+      for (PsiType type : ((PsiIntersectionType)rType).getConjuncts()) {
+        if (isRawToGeneric(lType, type)) return true;
+      }
+      return false;
+    }
+    if (lType instanceof PsiIntersectionType) {
+      for (PsiType type : ((PsiIntersectionType)lType).getConjuncts()) {
+        if (isRawToGeneric(type, rType)) return true;
+      }
+      return false;
+    }
+
+    if (!(lType instanceof PsiClassType) || !(rType instanceof PsiClassType)) return false;
+
+    PsiClassType.ClassResolveResult lResolveResult = ((PsiClassType)lType).resolveGenerics();
+    PsiClassType.ClassResolveResult rResolveResult = ((PsiClassType)rType).resolveGenerics();
+    PsiClass lClass = lResolveResult.getElement();
+    PsiClass rClass = rResolveResult.getElement();
+
+    if (rClass instanceof PsiAnonymousClass) {
+      return isRawToGeneric(lType, ((PsiAnonymousClass)rClass).getBaseClassType());
+    }
+
+    PsiSubstitutor lSubstitutor = lResolveResult.getSubstitutor();
+    PsiSubstitutor rSubstitutor = rResolveResult.getSubstitutor();
+    if (lClass == null || rClass == null) return false;
+    if (lClass instanceof PsiTypeParameter &&
+        !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) {
+      return true;
+    }
+
+    if (!lClass.getManager().areElementsEquivalent(lClass, rClass)) {
+      if (lClass.isInheritor(rClass, true)) {
+        lSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(rClass, lClass, lSubstitutor);
+        lClass = rClass;
+      }
+      else if (rClass.isInheritor(lClass, true)) {
+        rSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(lClass, rClass, rSubstitutor);
+        rClass = lClass;
+      }
+      else {
+        return false;
+      }
+    }
+
+    Iterator<PsiTypeParameter> lIterator = PsiUtil.typeParametersIterator(lClass);
+    Iterator<PsiTypeParameter> rIterator = PsiUtil.typeParametersIterator(rClass);
+    while (lIterator.hasNext()) {
+      if (!rIterator.hasNext()) return false;
+      PsiTypeParameter lParameter = lIterator.next();
+      PsiTypeParameter rParameter = rIterator.next();
+      PsiType lTypeArg = lSubstitutor.substitute(lParameter);
+      PsiType rTypeArg = rSubstitutor.substituteWithBoundsPromotion(rParameter);
+      if (lTypeArg == null) continue;
+      if (rTypeArg == null) {
+        if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType)lTypeArg).getBound() == null) {
+          continue;
+        }
+        else {
+          return true;
+        }
+      }
+      if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, true)) return true;
+    }
+    return false;
+  }
+
+  @Nullable
+  public static PsiType getCollectionItemType(@NotNull PsiExpression expression) {
+    final PsiType type = expression.getType();
+    if (type == null) return null;
+    return getCollectionItemType(type, expression.getResolveScope());
+  }
+
+  @Nullable
+  public static PsiType getCollectionItemType(final PsiType type, final GlobalSearchScope scope) {
+    if (type instanceof PsiArrayType) {
+      return ((PsiArrayType)type).getComponentType();
+    }
+    if (type instanceof PsiClassType) {
+      final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
+      PsiClass aClass = resolveResult.getElement();
+      if (aClass == null) return null;
+      final PsiManager manager = aClass.getManager();
+      final String qName = aClass.getQualifiedName();
+      PsiSubstitutor substitutor = resolveResult.getSubstitutor();
+      JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
+      if (qName != null) {
+        PsiClass myClass = facade.findClass(qName, scope);
+        if (myClass != null && myClass != aClass) {
+          //different JDKs
+          PsiTypeParameter thisTypeParameter = getIterableTypeParameter(facade, myClass);
+          if (thisTypeParameter == null) return null;
+          PsiTypeParameter thatTypeParameter = getIterableTypeParameter(facade, aClass);
+          if (thatTypeParameter != null) { //it can be null if we reference collection in JDK1.4 module from JDK5 source
+            substitutor = substitutor.put(thisTypeParameter, substitutor.substitute(thatTypeParameter));
+          }
+          aClass = myClass;
+        }
+      }
+      PsiTypeParameter typeParameter = getIterableTypeParameter(facade, aClass);
+      if (typeParameter == null) return null;
+      PsiClass owner = (PsiClass)typeParameter.getOwner();
+      if (owner == null) return null;
+      PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(owner, aClass, PsiSubstitutor.EMPTY);
+      if (superClassSubstitutor == null) return null;
+      PsiType itemType = superClassSubstitutor.substitute(typeParameter);
+      itemType = substitutor.substitute(itemType);
+      return itemType == null ? PsiType.getJavaLangObject(manager, aClass.getResolveScope()) : itemType;
+    }
+    return null;
+  }
+
+  @Nullable
+  private static PsiTypeParameter getIterableTypeParameter(final JavaPsiFacade facade, final PsiClass context) {
+    PsiClass iterable = facade.findClass("java.lang.Iterable", context.getResolveScope());
+    if (iterable == null) return null;
+    PsiTypeParameter[] typeParameters = iterable.getTypeParameters();
+    if (typeParameters.length != 1) return null;
+    return typeParameters[0];
+  }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java
new file mode 100644
index 0000000..c1e2b18
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/analysis/JavaHighlightUtil.java
@@ -0,0 +1,127 @@
+/*
+ * 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.codeInsight.daemon.impl.analysis;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiFormatUtilBase;
+import com.intellij.psi.util.TypeConversionUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public class JavaHighlightUtil {
+  public static boolean isSerializable(@NotNull PsiClass aClass) {
+    PsiManager manager = aClass.getManager();
+    PsiClass serializableClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", aClass.getResolveScope());
+    return serializableClass != null && aClass.isInheritor(serializableClass, true);
+  }
+
+  public static boolean isSerializationRelatedMethod(PsiMethod method, PsiClass containingClass) {
+    if (containingClass == null || method.isConstructor()) return false;
+    if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
+    @NonNls String name = method.getName();
+    PsiParameter[] parameters = method.getParameterList().getParameters();
+    PsiType returnType = method.getReturnType();
+    if ("readObjectNoData".equals(name)) {
+      return parameters.length == 0 && TypeConversionUtil.isVoidType(returnType) && isSerializable(containingClass);
+    }
+    if ("readObject".equals(name)) {
+      return parameters.length == 1
+             && parameters[0].getType().equalsToText("java.io.ObjectInputStream")
+             && TypeConversionUtil.isVoidType(returnType) && method.hasModifierProperty(PsiModifier.PRIVATE)
+             && isSerializable(containingClass);
+    }
+    if ("readResolve".equals(name)) {
+      return parameters.length == 0
+             && returnType != null
+             && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
+             && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || isSerializable(containingClass));
+    }
+    if ("writeReplace".equals(name)) {
+      return parameters.length == 0
+             && returnType != null
+             && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
+             && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || isSerializable(containingClass));
+    }
+    if ("writeObject".equals(name)) {
+      return parameters.length == 1
+             && TypeConversionUtil.isVoidType(returnType)
+             && parameters[0].getType().equalsToText("java.io.ObjectOutputStream")
+             && method.hasModifierProperty(PsiModifier.PRIVATE)
+             && isSerializable(containingClass);
+    }
+    return false;
+  }
+
+  @NotNull
+  public static String formatType(@Nullable PsiType type) {
+    if (type == null) return PsiKeyword.NULL;
+    String text = type.getInternalCanonicalText();
+    return text == null ? PsiKeyword.NULL : text;
+  }
+
+  @Nullable
+  private static PsiType getArrayInitializerType(@NotNull final PsiArrayInitializerExpression element) {
+    final PsiType typeCheckResult = sameType(element.getInitializers());
+    if (typeCheckResult != null) {
+      return typeCheckResult.createArrayType();
+    }
+    return null;
+  }
+
+  @Nullable
+  public static PsiType sameType(@NotNull PsiExpression[] expressions) {
+    PsiType type = null;
+    for (PsiExpression expression : expressions) {
+      final PsiType currentType;
+      if (expression instanceof PsiArrayInitializerExpression) {
+        currentType = getArrayInitializerType((PsiArrayInitializerExpression)expression);
+      }
+      else {
+        currentType = expression.getType();
+      }
+      if (type == null) {
+        type = currentType;
+      }
+      else if (!type.equals(currentType)) {
+        return null;
+      }
+    }
+    return type;
+  }
+
+  @NotNull
+  public static String formatMethod(@NotNull PsiMethod method) {
+    return PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
+                                      PsiFormatUtilBase.SHOW_TYPE);
+  }
+
+  public static boolean isSuperOrThisCall(PsiStatement statement, boolean testForSuper, boolean testForThis) {
+    if (!(statement instanceof PsiExpressionStatement)) return false;
+    PsiExpression expression = ((PsiExpressionStatement)statement).getExpression();
+    if (!(expression instanceof PsiMethodCallExpression)) return false;
+    final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression();
+    if (testForSuper) {
+      if ("super".equals(methodExpression.getText())) return true;
+    }
+    if (testForThis) {
+      if ("this".equals(methodExpression.getText())) return true;
+    }
+
+    return false;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
similarity index 84%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
index 3ebfb21..61adfb6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MethodThrowsFix.java
@@ -17,10 +17,9 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
 import com.intellij.openapi.command.undo.UndoUtil;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
@@ -28,16 +27,15 @@
 import com.intellij.psi.util.PsiFormatUtilBase;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
-public class MethodThrowsFix extends LocalQuickFixAndIntentionActionOnPsiElement {
+public class MethodThrowsFix extends LocalQuickFixOnPsiElement {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix");
 
   private final String myThrowsCanonicalText;
   private final boolean myShouldThrow;
   private final String myMethodName;
 
-  public MethodThrowsFix(PsiMethod method, PsiClassType exceptionType, boolean shouldThrow, boolean showContainingClass) {
+  public MethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionType, boolean shouldThrow, boolean showContainingClass) {
     super(method);
     myThrowsCanonicalText = exceptionType.getCanonicalText();
     myShouldThrow = shouldThrow;
@@ -73,11 +71,7 @@
   }
 
   @Override
-  public void invoke(@NotNull Project project,
-                     @NotNull PsiFile file,
-                     @Nullable("is null when called from inspection") Editor editor,
-                     @NotNull PsiElement startElement,
-                     @NotNull PsiElement endElement) {
+  public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
     final PsiMethod myMethod = (PsiMethod)startElement;
     if (!FileModificationService.getInstance().prepareFileForWrite(myMethod.getContainingFile())) return;
     PsiJavaCodeReferenceElement[] referenceElements = myMethod.getThrowsList().getReferenceElements();
@@ -100,7 +94,8 @@
         myMethod.getThrowsList().add(ref);
       }
       UndoUtil.markPsiFileForUndo(file);
-    } catch (IncorrectOperationException e) {
+    }
+    catch (IncorrectOperationException e) {
       LOG.error(e);
     }
   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java
new file mode 100644
index 0000000..4515cc8
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableUtil.java
@@ -0,0 +1,261 @@
+/*
+ * 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.codeInsight.daemon.impl.quickfix;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PropertyUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.IncorrectOperationException;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.*;
+
+public class RemoveUnusedVariableUtil {
+  public static final int MAKE_STATEMENT = 1;
+  public static final int DELETE_ALL = 2;
+  public static final int CANCEL = 0;
+  private static final Set<String> ourSideEffectFreeClasses = new THashSet<String>();
+  static {
+    ourSideEffectFreeClasses.add(Object.class.getName());
+    ourSideEffectFreeClasses.add(Short.class.getName());
+    ourSideEffectFreeClasses.add(Character.class.getName());
+    ourSideEffectFreeClasses.add(Byte.class.getName());
+    ourSideEffectFreeClasses.add(Integer.class.getName());
+    ourSideEffectFreeClasses.add(Long.class.getName());
+    ourSideEffectFreeClasses.add(Float.class.getName());
+    ourSideEffectFreeClasses.add(Double.class.getName());
+    ourSideEffectFreeClasses.add(String.class.getName());
+    ourSideEffectFreeClasses.add(StringBuffer.class.getName());
+    ourSideEffectFreeClasses.add(Boolean.class.getName());
+
+    ourSideEffectFreeClasses.add(ArrayList.class.getName());
+    ourSideEffectFreeClasses.add(Date.class.getName());
+    ourSideEffectFreeClasses.add(HashMap.class.getName());
+    ourSideEffectFreeClasses.add(HashSet.class.getName());
+    ourSideEffectFreeClasses.add(Hashtable.class.getName());
+    ourSideEffectFreeClasses.add(LinkedHashMap.class.getName());
+    ourSideEffectFreeClasses.add(LinkedHashSet.class.getName());
+    ourSideEffectFreeClasses.add(LinkedList.class.getName());
+    ourSideEffectFreeClasses.add(Stack.class.getName());
+    ourSideEffectFreeClasses.add(TreeMap.class.getName());
+    ourSideEffectFreeClasses.add(TreeSet.class.getName());
+    ourSideEffectFreeClasses.add(Vector.class.getName());
+    ourSideEffectFreeClasses.add(WeakHashMap.class.getName());
+  }
+
+  static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
+    PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
+    PsiClass aClass = classReference == null ? null : (PsiClass)classReference.resolve();
+    String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
+    if (qualifiedName == null) return false;
+    if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;
+
+    PsiFile file = aClass.getContainingFile();
+    PsiDirectory directory = file.getContainingDirectory();
+    PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
+    String packageName = classPackage == null ? null : classPackage.getQualifiedName();
+
+    // all Throwable descendants from java.lang are side effects free
+    if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
+      PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.lang.Throwable", aClass.getResolveScope());
+      if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  public static boolean checkSideEffects(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects) {
+  if (sideEffects == null || element == null) return false;
+  if (element instanceof PsiMethodCallExpression) {
+    final PsiMethod psiMethod = ((PsiMethodCallExpression)element).resolveMethod();
+    if (psiMethod == null || !PropertyUtil.isSimpleGetter(psiMethod) && !PropertyUtil.isSimpleSetter(psiMethod)) {
+      sideEffects.add(element);
+      return true;
+    }
+  }
+  if (element instanceof PsiNewExpression) {
+    PsiNewExpression newExpression = (PsiNewExpression)element;
+    if (newExpression.getArrayDimensions().length == 0
+        && newExpression.getArrayInitializer() == null
+        && !isSideEffectFreeConstructor(newExpression)) {
+      sideEffects.add(element);
+      return true;
+    }
+  }
+  if (element instanceof PsiAssignmentExpression
+      && !(((PsiAssignmentExpression)element).getLExpression() instanceof PsiReferenceExpression
+           && ((PsiReferenceExpression)((PsiAssignmentExpression)element).getLExpression()).resolve() == variable)) {
+    sideEffects.add(element);
+    return true;
+  }
+  PsiElement[] children = element.getChildren();
+
+    for (PsiElement child : children) {
+      checkSideEffects(child, variable, sideEffects);
+    }
+  return !sideEffects.isEmpty();
+}
+
+  static PsiElement replaceElementWithExpression(PsiExpression expression,
+                                                 PsiElementFactory factory,
+                                                 PsiElement element) throws IncorrectOperationException {
+    PsiElement elementToReplace = element;
+    PsiElement expressionToReplaceWith = expression;
+    if (element.getParent() instanceof PsiExpressionStatement) {
+      elementToReplace = element.getParent();
+      expressionToReplaceWith =
+      factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+    }
+    else if (element.getParent() instanceof PsiDeclarationStatement) {
+      expressionToReplaceWith =
+      factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+    }
+    return elementToReplace.replace(expressionToReplaceWith);
+  }
+
+  static PsiElement createStatementIfNeeded(PsiExpression expression,
+                                            PsiElementFactory factory,
+                                            PsiElement element) throws IncorrectOperationException {
+    // if element used in expression, subexpression will do
+    if (!(element.getParent() instanceof PsiExpressionStatement) &&
+        !(element.getParent() instanceof PsiDeclarationStatement)) {
+      return expression;
+    }
+    return factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
+  }
+
+  static void deleteWholeStatement(PsiElement element, PsiElementFactory factory)
+    throws IncorrectOperationException {
+    // just delete it altogether
+    if (element.getParent() instanceof PsiExpressionStatement) {
+      PsiExpressionStatement parent = (PsiExpressionStatement)element.getParent();
+      if (parent.getParent() instanceof PsiCodeBlock) {
+        parent.delete();
+      }
+      else {
+        // replace with empty statement (to handle with 'if (..) i=0;' )
+        parent.replace(createStatementIfNeeded(null, factory, element));
+      }
+    }
+    else {
+      element.delete();
+    }
+  }
+
+  static void deleteReferences(PsiVariable variable, List<PsiElement> references, int mode) throws IncorrectOperationException {
+    for (PsiElement expression : references) {
+      processUsage(expression, variable, null, mode);
+    }
+  }
+
+  static void collectReferences(@NotNull PsiElement context, final PsiVariable variable, final List<PsiElement> references) {
+    context.accept(new JavaRecursiveElementWalkingVisitor() {
+      @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+        if (expression.resolve() == variable) references.add(expression);
+        super.visitReferenceExpression(expression);
+      }
+    });
+  }
+
+  /**
+   * @param sideEffects if null, delete usages, otherwise collect side effects
+   * @return true if there are at least one unrecoverable side effect found, false if no side effects,
+   *         null if read usage found (may happen if interval between fix creation in invoke() call was long enough)
+   * @throws com.intellij.util.IncorrectOperationException
+   */
+  static Boolean processUsage(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
+    throws IncorrectOperationException {
+    if (!element.isValid()) return null;
+    PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
+    while (element != null) {
+      if (element instanceof PsiAssignmentExpression) {
+        PsiAssignmentExpression expression = (PsiAssignmentExpression)element;
+        PsiExpression lExpression = expression.getLExpression();
+        // there should not be read access to the variable, otherwise it is not unused
+        if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression)lExpression).resolve()) {
+          return null;
+        }
+        PsiExpression rExpression = expression.getRExpression();
+        rExpression = PsiUtil.deparenthesizeExpression(rExpression);
+        if (rExpression == null) return true;
+        // replace assignment with expression and resimplify
+        boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
+        if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) {
+          if (deleteMode == MAKE_STATEMENT ||
+              deleteMode == DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) {
+            element = replaceElementWithExpression(rExpression, factory, element);
+            while (element.getParent() instanceof PsiParenthesizedExpression) {
+              element = element.getParent().replace(element);
+            }
+            List<PsiElement> references = new ArrayList<PsiElement>();
+            collectReferences(element, variable, references);
+            deleteReferences(variable, references, deleteMode);
+          }
+          else if (deleteMode == DELETE_ALL) {
+            deleteWholeStatement(element, factory);
+          }
+          return true;
+        }
+        else {
+          if (deleteMode != CANCEL) {
+            deleteWholeStatement(element, factory);
+          }
+          return !sideEffectFound;
+        }
+      }
+      else if (element instanceof PsiExpressionStatement && deleteMode != CANCEL) {
+        element.delete();
+        break;
+      }
+      else if (element instanceof PsiVariable && element == variable) {
+        PsiExpression expression = variable.getInitializer();
+        if (expression != null) {
+          expression = PsiUtil.deparenthesizeExpression(expression);
+        }
+        boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
+        if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable
+            &&
+            !(variable.getParent() instanceof PsiDeclarationStatement &&
+              ((PsiDeclarationStatement)variable.getParent()).getDeclaredElements().length > 1)) {
+          if (deleteMode == MAKE_STATEMENT) {
+            element = element.replace(createStatementIfNeeded(expression, factory, element));
+            List<PsiElement> references = new ArrayList<PsiElement>();
+            collectReferences(element, variable, references);
+            deleteReferences(variable, references, deleteMode);
+          }
+          else if (deleteMode == DELETE_ALL) {
+            element.delete();
+          }
+          return true;
+        }
+        else {
+          if (deleteMode != CANCEL) {
+            if (element instanceof PsiField) {
+              ((PsiField)element).normalizeDeclaration();
+            }
+            element.delete();
+          }
+          return !sideEffectsFound;
+        }
+      }
+      element = element.getParent();
+    }
+    return true;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
index 83395ef..612c6c6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SimplifyBooleanExpressionFix.java
@@ -21,9 +21,9 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
-import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
 import com.intellij.openapi.util.text.StringUtil;
@@ -40,45 +40,54 @@
 import java.util.ArrayList;
 import java.util.List;
 
-public class SimplifyBooleanExpressionFix implements IntentionAction {
+public class SimplifyBooleanExpressionFix extends LocalQuickFixOnPsiElement {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpression");
+  public static final String FAMILY_NAME = QuickFixBundle.message("simplify.boolean.expression.family");
 
-  private final PsiExpression mySubExpression;
   private final Boolean mySubExpressionValue;
 
   // subExpressionValue == Boolean.TRUE or Boolean.FALSE if subExpression evaluates to boolean constant and needs to be replaced
   //   otherwise subExpressionValue= null and we starting to simplify expression without any further knowledge
-  public SimplifyBooleanExpressionFix(PsiExpression subExpression, Boolean subExpressionValue) {
-    mySubExpression = subExpression;
+  public SimplifyBooleanExpressionFix(@NotNull PsiExpression subExpression, Boolean subExpressionValue) {
+    super(subExpression);
     mySubExpressionValue = subExpressionValue;
   }
 
   @Override
   @NotNull
   public String getText() {
-    return QuickFixBundle.message("simplify.boolean.expression.text", mySubExpression.getText(), mySubExpressionValue);
+    PsiExpression expression = getSubExpression();
+    return QuickFixBundle.message("simplify.boolean.expression.text", expression.getText(), mySubExpressionValue);
   }
 
   @Override
   @NotNull
   public String getFamilyName() {
-    return QuickFixBundle.message("simplify.boolean.expression.family");
+    return FAMILY_NAME;
   }
 
   @Override
-  public boolean isAvailable(@NotNull Project project, Editor editor, PsiFile file) {
-    return mySubExpression.isValid()
-           && mySubExpression.getManager().isInProject(mySubExpression)
-           && !PsiUtil.isAccessedForWriting(mySubExpression)
-      ;
+  public boolean isAvailable() {
+    PsiExpression expression = getSubExpression();
+    return super.isAvailable()
+           && expression != null
+           && expression.isValid()
+           && expression.getManager().isInProject(expression)
+           && !PsiUtil.isAccessedForWriting(expression);
   }
 
   @Override
-  public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
-    if (!isAvailable(project, editor, file)) return;
-    LOG.assertTrue(mySubExpression.isValid());
-    if (!FileModificationService.getInstance().preparePsiElementForWrite(mySubExpression)) return;
-    simplifyExpression(project, mySubExpression, mySubExpressionValue);
+  public void invoke(@NotNull final Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
+    if (!isAvailable()) return;
+    final PsiExpression expression = getSubExpression();
+    LOG.assertTrue(expression.isValid());
+    if (!FileModificationService.getInstance().preparePsiElementForWrite(expression)) return;
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        simplifyExpression(project, expression, mySubExpressionValue);
+      }
+    });
   }
 
   public static void simplifyExpression(Project project, final PsiExpression subExpression, final Boolean subExpressionValue) {
@@ -226,6 +235,11 @@
     return canBeSimplified.get().booleanValue();
   }
 
+  private PsiExpression getSubExpression() {
+    PsiElement element = getStartElement();
+    return element instanceof PsiExpression ? (PsiExpression)element : null;
+  }
+
   private static class ExpressionVisitor extends JavaElementVisitor {
     private PsiExpression resultExpression;
     private final PsiExpression trueExpression;
@@ -420,9 +434,4 @@
     String text = operand.getText();
     return PsiKeyword.TRUE.equals(text) ? Boolean.TRUE : PsiKeyword.FALSE.equals(text) ? Boolean.FALSE : null;
   }
-
-  @Override
-  public boolean startInWriteAction() {
-    return true;
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
similarity index 83%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
index 0b87b3d..1087e2e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableArrayTypeFix.java
@@ -17,18 +17,20 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
+import com.intellij.ide.TypePresentationService;
+import com.intellij.lang.findUsages.FindUsagesProvider;
+import com.intellij.lang.findUsages.LanguageFindUsages;
 import com.intellij.openapi.command.undo.UndoUtil;
-import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class VariableArrayTypeFix extends LocalQuickFixAndIntentionActionOnPsiElement {
-
+public class VariableArrayTypeFix extends LocalQuickFixOnPsiElement {
   @NotNull
   private final PsiArrayType myTargetType;
   private final String myName;
@@ -48,12 +50,22 @@
     PsiVariable myVariable = getVariableLocal(arrayInitializer);
     myName = myVariable == null ? null : myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
              QuickFixBundle.message("change.new.operator.type.text", getNewText(myNewExpression,arrayInitializer), myTargetType.getCanonicalText(), "") :
-             QuickFixBundle.message("fix.variable.type.text", myVariable.getName(), myTargetType.getCanonicalText());
+             QuickFixBundle.message("fix.variable.type.text", formatType(myVariable), myVariable.getName(), myTargetType.getCanonicalText());
     myFamilyName = myVariable == null ? null : myTargetType.equals(myVariable.getType()) && myNewExpression != null ?
                    QuickFixBundle.message("change.new.operator.type.family") :
                    QuickFixBundle.message("fix.variable.type.family");
   }
 
+  private static String formatType(@NotNull PsiVariable variable) {
+    FindUsagesProvider provider = LanguageFindUsages.INSTANCE.forLanguage(variable.getLanguage());
+    final String type = provider.getType(variable);
+    if (StringUtil.isNotEmpty(type)) {
+      return type;
+    }
+
+    return TypePresentationService.getService().getTypePresentableName(variable.getClass());
+  }
+
   private static PsiArrayInitializerExpression getInitializer(PsiArrayInitializerExpression initializer) {
     PsiArrayInitializerExpression arrayInitializer = initializer;
     while (arrayInitializer.getParent() instanceof PsiArrayInitializerExpression) {
@@ -63,7 +75,7 @@
     return arrayInitializer;
   }
 
-  private static PsiVariable getVariableLocal(PsiArrayInitializerExpression initializer) {
+  private static PsiVariable getVariableLocal(@NotNull PsiArrayInitializerExpression initializer) {
     PsiVariable variableLocal = null;
 
     final PsiElement parent = initializer.getParent();
@@ -86,14 +98,15 @@
     return variableLocal;
   }
 
-  private static PsiNewExpression getNewExpressionLocal(PsiArrayInitializerExpression initializer) {
+  private static PsiNewExpression getNewExpressionLocal(@NotNull PsiArrayInitializerExpression initializer) {
     PsiNewExpression newExpressionLocal = null;
 
     final PsiElement parent = initializer.getParent();
     if (parent instanceof PsiVariable) {
 
-    } else if (parent instanceof PsiNewExpression) {
-      newExpressionLocal = (PsiNewExpression) parent;
+    }
+    else if (parent instanceof PsiNewExpression) {
+      newExpressionLocal = (PsiNewExpression)parent;
     }
 
     return newExpressionLocal;
@@ -143,11 +156,7 @@
   }
 
   @Override
-  public void invoke(@NotNull Project project,
-                     @NotNull PsiFile file,
-                     @Nullable("is null when called from inspection") Editor editor,
-                     @NotNull PsiElement startElement,
-                     @NotNull PsiElement endElement) {
+  public void invoke(@NotNull Project project, @NotNull PsiFile file, @NotNull PsiElement startElement, @NotNull PsiElement endElement) {
     final PsiArrayInitializerExpression myInitializer = (PsiArrayInitializerExpression)startElement;
     final PsiVariable myVariable = getVariableLocal(myInitializer);
     if (myVariable == null) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/GuessManager.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/GuessManager.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/GuessManager.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/GuessManager.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
similarity index 94%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
index 9e30492..7a74783 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/ExpressionTypeMemoryState.java
@@ -15,8 +15,9 @@
  */
 package com.intellij.codeInsight.guess.impl;
 
-import com.intellij.codeInsight.CodeInsightUtil;
+import com.intellij.codeInsight.JavaPsiEquivalenceUtil;
 import com.intellij.codeInspection.dataFlow.DfaMemoryStateImpl;
+import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue;
 import com.intellij.codeInspection.dataFlow.value.DfaValue;
 import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
 import com.intellij.openapi.diagnostic.Logger;
@@ -41,7 +42,7 @@
 
     @Override
     public boolean equals(PsiExpression o1, PsiExpression o2) {
-      if (CodeInsightUtil.areExpressionsEquivalent(o1, o2)) {
+      if (JavaPsiEquivalenceUtil.areExpressionsEquivalent(o1, o2)) {
         if (computeHashCode(o1) != computeHashCode(o2)) {
           LOG.error("different hashCodes: " + o1 + "; " + o2 + "; " + computeHashCode(o1) + "!=" + computeHashCode(o2));
         }
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
index c6716c3..39d7520 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/GuessManagerImpl.java
@@ -1,6 +1,6 @@
 
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -22,6 +22,7 @@
 import com.intellij.codeInspection.dataFlow.instructions.TypeCastInstruction;
 import com.intellij.codeInspection.dataFlow.instructions.InstanceofInstruction;
 import com.intellij.codeInspection.dataFlow.instructions.MethodCallInstruction;
+import com.intellij.codeInspection.dataFlow.value.DfaInstanceofValue;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
@@ -140,7 +141,7 @@
 
   @Nullable
   private static Map<PsiExpression, PsiType> buildDataflowTypeMap(PsiExpression forPlace) {
-    PsiElement scope = DfaUtil.getTopmostBlockInSameClass(forPlace);
+    PsiElement scope = DfaPsiUtil.getTopmostBlockInSameClass(forPlace);
     if (scope == null) {
       PsiFile file = forPlace.getContainingFile();
       if (!(file instanceof PsiCodeFragment)) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPattern.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java b/java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/guess/impl/MethodPatternMap.java
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
similarity index 100%
rename from java/java-psi-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/AddAnnotationPsiFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNotNullAnnotationFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableAnnotationFix.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
similarity index 88%
rename from java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
index 8ab713b..6684613 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInsight/intention/impl/AddNullableNotNullAnnotationFix.java
@@ -23,14 +23,14 @@
 package com.intellij.codeInsight.intention.impl;
 
 import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import org.jetbrains.annotations.NotNull;
 
-public class AddNullableNotNullAnnotationFix extends AddAnnotationFix {
+public class AddNullableNotNullAnnotationFix extends AddAnnotationPsiFix {
   public AddNullableNotNullAnnotationFix(@NotNull String fqn, @NotNull PsiModifierListOwner owner, @NotNull String... annotationToRemove) {
-    super(fqn, owner, annotationToRemove);
+    super(fqn, owner, PsiNameValuePair.EMPTY_ARRAY, annotationToRemove);
   }
 
   @Override
@@ -38,7 +38,7 @@
                              @NotNull PsiFile file,
                              @NotNull PsiElement startElement,
                              @NotNull PsiElement endElement) {
-     if (!super.isAvailable(project, file, startElement, endElement)) {
+    if (!super.isAvailable(project, file, startElement, endElement)) {
       return false;
     }
     PsiModifierListOwner owner = getContainer(startElement);
diff --git a/java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
similarity index 96%
rename from java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
index d57631f..4bdf058 100644
--- a/java/java-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AddAssertStatementFix.java
@@ -54,7 +54,7 @@
     PsiElement anchorElement = PsiTreeUtil.getParentOfType(element, PsiStatement.class);
     LOG.assertTrue(anchorElement != null);
     PsiElement prev = PsiTreeUtil.skipSiblingsBackward(anchorElement, PsiWhiteSpace.class);
-    if (prev instanceof PsiComment && SuppressManager.getInstance().getSuppressedInspectionIdsIn(prev) != null) {
+    if (prev instanceof PsiComment && JavaSuppressionUtil.getSuppressedInspectionIdsIn(prev) != null) {
       anchorElement = prev;
     }
 
diff --git a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
similarity index 73%
rename from java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
index 45e8c7b..6d4ac0c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/AnnotateMethodFix.java
@@ -17,20 +17,18 @@
 
 import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
 import com.intellij.openapi.command.undo.UndoUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.ui.Messages;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiModifier;
+import com.intellij.psi.PsiNameValuePair;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.searches.OverridingMethodsSearch;
 import com.intellij.psi.util.ClassUtil;
 import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
@@ -45,7 +43,7 @@
   protected final String myAnnotation;
   private final String[] myAnnotationsToRemove;
 
-  public AnnotateMethodFix(final String fqn, String... annotationsToRemove) {
+  public AnnotateMethodFix(@NotNull String fqn, @NotNull String... annotationsToRemove) {
     myAnnotation = fqn;
     myAnnotationsToRemove = annotationsToRemove;
   }
@@ -68,7 +66,7 @@
     for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
       PsiMethod superMethod = superMethodSignature.getMethod();
       if (!AnnotationUtil.isAnnotated(superMethod, myAnnotation, false, false) && superMethod.getManager().isInProject(superMethod)) {
-        int ret = annotateBaseMethod(method, superMethod, project);
+        int ret = shouldAnnotateBaseMethod(method, superMethod, project);
         if (ret != 0 && ret != 1) return;
         if (ret == 0) {
           toAnnotate.add(superMethod);
@@ -91,15 +89,9 @@
     UndoUtil.markPsiFileForUndo(method.getContainingFile());
   }
 
-  public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
-    String implement = !method.hasModifierProperty(PsiModifier.ABSTRACT) && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
-                  ? InspectionsBundle.message("inspection.annotate.quickfix.implements")
-                  : InspectionsBundle.message("inspection.annotate.quickfix.overrides");
-    String message = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.messages",
-                                               UsageViewUtil.getDescriptiveName(method), implement,
-                                               UsageViewUtil.getDescriptiveName(superMethod));
-    String title = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.warning");
-    return Messages.showYesNoCancelDialog(project, message, title, Messages.getQuestionIcon());
+  // 0-annotate, 1-do not annotate, 2- cancel
+  public int shouldAnnotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
+    return 0;
   }
 
   protected boolean annotateOverriddenMethods() {
@@ -114,7 +106,8 @@
 
   private void annotateMethod(@NotNull PsiMethod method) {
     try {
-      new AddAnnotationFix(myAnnotation, method, myAnnotationsToRemove).invoke(method.getProject(), null, method.getContainingFile());
+      AddAnnotationPsiFix fix = new AddAnnotationPsiFix(myAnnotation, method, PsiNameValuePair.EMPTY_ARRAY, myAnnotationsToRemove);
+      fix.invoke(method.getProject(), method.getContainingFile(), method, method);
     }
     catch (IncorrectOperationException e) {
       LOG.error(e);
diff --git a/java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
similarity index 78%
rename from java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
index a8203d7..1a3ce0b 100644
--- a/java/java-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/DeleteThrowsFix.java
@@ -19,9 +19,10 @@
 import com.intellij.codeInsight.daemon.impl.quickfix.MethodThrowsFix;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiElement;
+import com.intellij.psi.util.PsiTreeUtil;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -30,7 +31,7 @@
 public class DeleteThrowsFix implements LocalQuickFix {
   private final MethodThrowsFix myQuickFix;
 
-  public DeleteThrowsFix(PsiMethod method, PsiClassType exceptionClass) {
+  public DeleteThrowsFix(@NotNull PsiMethod method, PsiClassType exceptionClass) {
     myQuickFix = new MethodThrowsFix(method, exceptionClass, false, false);
   }
 
@@ -49,10 +50,11 @@
   @Override
   public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
     PsiElement element = descriptor.getPsiElement();
-    if (element == null) return;
-    final PsiFile psiFile = element.getContainingFile();
-    if (myQuickFix.isAvailable(project, null, psiFile)) {
-      myQuickFix.invoke(project, null, psiFile);
+    PsiMethod method = PsiTreeUtil.getParentOfType(element, PsiMethod.class);
+    if (method == null) return;
+    final PsiFile psiFile = method.getContainingFile();
+    if (myQuickFix.isAvailable(project, psiFile, method, method)) {
+      myQuickFix.invoke(project, psiFile, method, method);
     }
   }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
index 5f5b0e2..e4c583d 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ExplicitTypeCanBeDiamondInspection.java
@@ -28,7 +28,7 @@
  * User: anna
  * Date: 1/28/11
  */
-public class ExplicitTypeCanBeDiamondInspection extends BaseJavaLocalInspectionTool {
+public class ExplicitTypeCanBeDiamondInspection extends BaseJavaBatchLocalInspectionTool {
   public static final Logger LOG = Logger.getInstance("#" + ExplicitTypeCanBeDiamondInspection.class.getName());
 
   @Nls
diff --git a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
index 565ebbd..b49f7e3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/PossibleHeapPollutionVarargsInspection.java
@@ -17,8 +17,8 @@
 
 import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.pom.java.LanguageLevel;
@@ -33,7 +33,7 @@
  * User: anna
  * Date: 1/28/11
  */
-public class PossibleHeapPollutionVarargsInspection extends BaseJavaLocalInspectionTool {
+public class PossibleHeapPollutionVarargsInspection extends BaseJavaBatchLocalInspectionTool {
   public static final Logger LOG = Logger.getInstance("#" + PossibleHeapPollutionVarargsInspection.class.getName());
   @Nls
   @NotNull
@@ -110,7 +110,7 @@
       if (psiElement instanceof PsiIdentifier) {
         final PsiMethod psiMethod = (PsiMethod)psiElement.getParent();
         if (psiMethod != null) {
-          new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
+          new AddAnnotationPsiFix("java.lang.SafeVarargs", psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
         }
       }
     }
@@ -135,13 +135,12 @@
       if (psiElement instanceof PsiIdentifier) {
         final PsiMethod psiMethod = (PsiMethod)psiElement.getParent();
         psiMethod.getModifierList().setModifierProperty(PsiModifier.FINAL, true);
-        new AddAnnotationFix("java.lang.SafeVarargs", psiMethod).applyFix(project, descriptor);
+        new AddAnnotationPsiFix("java.lang.SafeVarargs", psiMethod, PsiNameValuePair.EMPTY_ARRAY).applyFix(project, descriptor);
       }
     }
   }
 
-  public static abstract class HeapPollutionVisitor extends JavaElementVisitor {
-
+  public abstract static class HeapPollutionVisitor extends JavaElementVisitor {
     @Override
     public void visitMethod(PsiMethod method) {
       super.visitMethod(method);
@@ -151,7 +150,7 @@
 
       final PsiParameter psiParameter = method.getParameterList().getParameters()[method.getParameterList().getParametersCount() - 1];
       final PsiType componentType = ((PsiEllipsisType)psiParameter.getType()).getComponentType();
-      if (GenericsHighlightUtil.isReifiableType(componentType)) {
+      if (JavaGenericsUtil.isReifiableType(componentType)) {
         return;
       }
       for (PsiReference reference : ReferencesSearch.search(psiParameter)) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
index 04d6533..fdb547c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/RedundantLambdaCodeBlockInspection.java
@@ -19,10 +19,8 @@
 import com.intellij.codeInsight.intention.HighPriorityAction;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.Function;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -30,7 +28,7 @@
 /**
  * User: anna
  */
-public class RedundantLambdaCodeBlockInspection extends BaseJavaLocalInspectionTool {
+public class RedundantLambdaCodeBlockInspection extends BaseJavaBatchLocalInspectionTool {
   public static final Logger LOG = Logger.getInstance("#" + RedundantLambdaCodeBlockInspection.class.getName());
 
   @Nls
diff --git a/java/java-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/RemoveAnnotationQuickFix.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
similarity index 79%
rename from java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
index d492b7b..212662f 100644
--- a/java/java-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/ReplaceWithTernaryOperatorFix.java
@@ -16,14 +16,12 @@
 package com.intellij.codeInspection;
 
 import com.intellij.codeInsight.FileModificationService;
-import com.intellij.openapi.editor.Editor;
-import com.intellij.openapi.editor.ScrollType;
+import com.intellij.ide.SelectInEditorManager;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.TextRange;
+import com.intellij.pom.Navigatable;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.util.PsiTypesUtil;
-import com.intellij.psi.util.PsiUtilBase;
 import org.jetbrains.annotations.NotNull;
 
 /**
@@ -66,24 +64,15 @@
 
     final PsiFile file = expression.getContainingFile();
     if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
-    final PsiConditionalExpression conditionalExpression = replaceWthConditionalExpression(project, myText + "!=null", expression, suggestDefaultValue(expression));
+    PsiConditionalExpression conditionalExpression = replaceWthConditionalExpression(project, myText + "!=null", expression, suggestDefaultValue(expression));
 
-    final PsiExpression elseExpression = conditionalExpression.getElseExpression();
+    PsiExpression elseExpression = conditionalExpression.getElseExpression();
     if (elseExpression != null) {
-      selectInEditor(elseExpression);
+      ((Navigatable)elseExpression).navigate(true);
+      SelectInEditorManager.getInstance(project).selectInEditor(file.getVirtualFile(), elseExpression.getTextRange().getStartOffset(), elseExpression.getTextRange().getEndOffset(), false, true);
     }
   }
 
-  private static void selectInEditor(@NotNull PsiElement element) {
-    final Editor editor = PsiUtilBase.findEditor(element);
-    if (editor == null) return;
-
-    final TextRange expressionRange = element.getTextRange();
-    editor.getCaretModel().moveToOffset(expressionRange.getStartOffset());
-    editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
-    editor.getSelectionModel().setSelection(expressionRange.getStartOffset(), expressionRange.getEndOffset());
-  }
-
   @NotNull
   private static PsiConditionalExpression replaceWthConditionalExpression(@NotNull Project project,
                                                                           @NotNull String condition,
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java
new file mode 100644
index 0000000..6c75f8b
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstanceBase.java
@@ -0,0 +1,107 @@
+/*
+ * 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.codeInspection.accessStaticViaInstance;
+
+import com.intellij.codeInsight.daemon.JavaErrorMessages;
+import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+
+public class AccessStaticViaInstanceBase extends BaseJavaBatchLocalInspectionTool {
+  @NonNls public static final String ACCESS_STATIC_VIA_INSTANCE = "AccessStaticViaInstance";
+
+  @Override
+  @NotNull
+  public String getGroupDisplayName() {
+    return "";
+  }
+
+  @Override
+  @NotNull
+  public String getDisplayName() {
+    return InspectionsBundle.message("access.static.via.instance");
+  }
+
+  @Override
+  @NotNull
+  @NonNls
+  public String getShortName() {
+    return ACCESS_STATIC_VIA_INSTANCE;
+  }
+
+  @Override
+  public String getAlternativeID() {
+    return "static-access";
+  }
+
+  @Override
+  public boolean isEnabledByDefault() {
+    return true;
+  }
+
+  @Override
+  @NotNull
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+    return new JavaElementVisitor() {
+      @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+        checkAccessStaticMemberViaInstanceReference(expression, holder, isOnTheFly);
+      }
+    };
+  }
+
+  private void checkAccessStaticMemberViaInstanceReference(PsiReferenceExpression expr, ProblemsHolder holder, boolean onTheFly) {
+    JavaResolveResult result = expr.advancedResolve(false);
+    PsiElement resolved = result.getElement();
+
+    if (!(resolved instanceof PsiMember)) return;
+    PsiExpression qualifierExpression = expr.getQualifierExpression();
+    if (qualifierExpression == null) return;
+
+    if (qualifierExpression instanceof PsiReferenceExpression) {
+      final PsiElement qualifierResolved = ((PsiReferenceExpression)qualifierExpression).resolve();
+      if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) {
+        return;
+      }
+    }
+    if (!((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC)) return;
+
+    String description = JavaErrorMessages.message("static.member.accessed.via.instance.reference",
+                                                   JavaHighlightUtil.formatType(qualifierExpression.getType()),
+                                                   HighlightMessageUtil.getSymbolName(resolved, result.getSubstitutor()));
+    if (!onTheFly) {
+      if (RemoveUnusedVariableUtil.checkSideEffects(qualifierExpression, null, new ArrayList<PsiElement>())) {
+        holder.registerProblem(expr, description);
+        return;
+      }
+    }
+    holder.registerProblem(expr, description, createAccessStaticViaInstanceFix(expr, onTheFly, result));
+  }
+
+  protected LocalQuickFix createAccessStaticViaInstanceFix(PsiReferenceExpression expr,
+                                                           boolean onTheFly,
+                                                           JavaResolveResult result) {
+    return null;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java b/java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/canBeFinal/CanBeFinalHandler.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
index 458cc0f..2586344 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/FieldAccessNotGuardedInspection.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -24,7 +24,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class FieldAccessNotGuardedInspection extends BaseJavaLocalInspectionTool {
+public class FieldAccessNotGuardedInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
index 9c66ee5..2c87a58 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/InstanceGuardedByStaticInspection.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.psi.*;
 import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
-public class InstanceGuardedByStaticInspection extends BaseJavaLocalInspectionTool {
+public class InstanceGuardedByStaticInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/JCiPUtil.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
index 4f3bb97..d3bcce5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalFieldInImmutableInspection.java
@@ -16,13 +16,13 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.psi.*;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
-public class NonFinalFieldInImmutableInspection extends BaseJavaLocalInspectionTool {
+public class NonFinalFieldInImmutableInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
index 33ac244..ef4d0d5 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/NonFinalGuardInspection.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.psi.*;
 import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
-public class NonFinalGuardInspection extends BaseJavaLocalInspectionTool {
+public class NonFinalGuardInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
index 9a8ed2b..d267fcd 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/StaticGuardedByInstanceInspection.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.psi.*;
 import com.intellij.psi.javadoc.PsiDocTag;
@@ -24,7 +24,7 @@
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NotNull;
 
-public class StaticGuardedByInstanceInspection extends BaseJavaLocalInspectionTool {
+public class StaticGuardedByInstanceInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
index b64bdb0..431bb40 100644
--- a/java/java-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/concurrencyAnnotations/UnknownGuardInspection.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInspection.concurrencyAnnotations;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
+import com.intellij.codeInspection.BaseJavaBatchLocalInspectionTool;
 import com.intellij.codeInspection.ProblemsHolder;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.text.StringUtil;
@@ -30,7 +30,7 @@
 /**
  * check locks according to http://www.javaconcurrencyinpractice.com/annotations/doc/net/jcip/annotations/GuardedBy.html
  */
-public class UnknownGuardInspection extends BaseJavaLocalInspectionTool {
+public class UnknownGuardInspection extends BaseJavaBatchLocalInspectionTool {
 
   @Override
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/AnnotationsAwareDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
index 537d656..8f901b6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlow.java
@@ -19,7 +19,7 @@
  * User: max
  * Date: Jan 11, 2002
  * Time: 3:05:34 PM
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.codeInspection.dataFlow;
@@ -33,9 +33,10 @@
 import gnu.trove.TObjectIntHashMap;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public class ControlFlow {
-  private final ArrayList<Instruction> myInstructions = new ArrayList<Instruction>();
+  private final List<Instruction> myInstructions = new ArrayList<Instruction>();
   private final TObjectIntHashMap<PsiElement> myElementToStartOffsetMap = new TObjectIntHashMap<PsiElement>();
   private final TObjectIntHashMap<PsiElement> myElementToEndOffsetMap = new TObjectIntHashMap<PsiElement>();
   private DfaVariableValue[] myFields;
@@ -92,7 +93,7 @@
 
   public String toString() {
     StringBuilder result = new StringBuilder();
-    final ArrayList<Instruction> instructions = myInstructions;
+    final List<Instruction> instructions = myInstructions;
 
     for (int i = 0; i < instructions.size(); i++) {
       Instruction instruction = instructions.get(i);
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
index 664ffe4..369f6ec 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ControlFlowAnalyzer.java
@@ -25,11 +25,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.refactoring.psi.PropertyUtils;
+import com.intellij.psi.util.*;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.Stack;
 import org.jetbrains.annotations.NonNls;
@@ -182,6 +178,11 @@
           generateDefaultBinOp(lExpr, rExpr, type);
         }
       }
+      else if (op == JavaTokenType.PLUSEQ && type != null && type.equalsToText(JAVA_LANG_STRING)) {
+        lExpr.accept(this);
+        rExpr.accept(this);
+        addInstruction(new BinopInstruction(JavaTokenType.PLUS, null, lExpr.getProject()));
+      }
       else {
         generateDefaultBinOp(lExpr, rExpr, type);
       }
@@ -1050,10 +1051,10 @@
     PsiType exprType = expression.getType();
 
     if (TypeConversionUtil.isPrimitiveAndNotNull(expectedType) && TypeConversionUtil.isPrimitiveWrapper(exprType)) {
-      addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING));
+      addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.UNBOXING, expectedType));
     }
     else if (TypeConversionUtil.isPrimitiveWrapper(expectedType) && TypeConversionUtil.isPrimitiveAndNotNull(exprType)) {
-      addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING));
+      addInstruction(new MethodCallInstruction(expression, MethodCallInstruction.MethodType.BOXING, expectedType));
     }
     else if (exprType != expectedType &&
              TypeConversionUtil.isPrimitiveAndNotNull(exprType) &&
@@ -1253,11 +1254,7 @@
         }
       }
 
-      MethodCallInstruction callInstruction = new MethodCallInstruction(expression, createChainedVariableValue(expression));
-      if (!DfaValueFactory.isEffectivelyUnqualified(methodExpression)) {
-        callInstruction.setShouldFlushFields(false);
-      }
-      addInstruction(callInstruction);
+      addInstruction(new MethodCallInstruction(expression, createChainedVariableValue(expression)));
 
       if (!myCatchStack.isEmpty()) {
         addMethodThrows(expression.resolveMethod());
@@ -1347,7 +1344,7 @@
         } else if (type == ConditionChecker.Type.IS_NULL_METHOD || type == ConditionChecker.Type.IS_NOT_NULL_METHOD) {
           addInstruction(new PushInstruction(myFactory.getConstFactory().getNull(), null));
           addInstruction(new BinopInstruction(type == ConditionChecker.Type.IS_NULL_METHOD ? JavaTokenType.EQEQ : JavaTokenType.NE, null, expression.getProject()));
-          
+
           ConditionalGotoInstruction ifFails = new ConditionalGotoInstruction(-1, true, null);
           GotoInstruction gotoEnd = new GotoInstruction(exitPoint);
 
@@ -1576,7 +1573,7 @@
     }
     if (dfaValue == null) {
       PsiType type = expression.getType();
-      return myFactory.createTypeValueWithNullability(type, DfaUtil.getElementNullability(type, field));
+      return myFactory.createTypeValueWithNullability(type, DfaPsiUtil.getElementNullability(type, field));
     }
     return dfaValue;
   }
@@ -1613,7 +1610,7 @@
       return result;
     }
 
-    if (DfaUtil.isFinalField(var) || DfaUtil.isPlainMutableField(var)) {
+    if (DfaPsiUtil.isFinalField(var) || DfaPsiUtil.isPlainMutableField(var)) {
       DfaVariableValue qualifierValue = createChainedVariableValue(qualifier);
       if (qualifierValue != null) {
         return myFactory.getVarFactory().createVariableValue(var, refExpr.getType(), false, qualifierValue, isCall || qualifierValue.isViaMethods());
@@ -1630,8 +1627,8 @@
     }
     if (target instanceof PsiMethod) {
       PsiMethod method = (PsiMethod)target;
-      if (PropertyUtils.isSimpleGetter(method)) {
-        return PropertyUtils.getSimplyReturnedField(method, PropertyUtils.getSingleReturnValue(method));
+      if (PropertyUtil.isSimpleGetter(method)) {
+        return PropertyUtil.getSimplyReturnedField(method, PropertyUtil.getSingleReturnValue(method));
       }
     }
     return null;
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
new file mode 100644
index 0000000..391fa1b
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspectionBase.java
@@ -0,0 +1,590 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: max
+ * Date: Dec 24, 2001
+ * Time: 2:46:32 PM
+ * To change template for new class use
+ * Code Style | Class Templates options (Tools | IDE Options).
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix;
+import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.dataFlow.instructions.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.SmartList;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.util.*;
+
+public class DataFlowInspectionBase extends BaseJavaBatchLocalInspectionTool {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection");
+  @NonNls private static final String SHORT_NAME = "ConstantConditions";
+  public boolean SUGGEST_NULLABLE_ANNOTATIONS = false;
+  public boolean DONT_REPORT_TRUE_ASSERT_STATEMENTS = false;
+
+  @Override
+  public JComponent createOptionsPanel() {
+    throw new RuntimeException("no UI in headless mode");
+  }
+
+  @Override
+  @NotNull
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+    return new JavaElementVisitor() {
+      @Override
+      public void visitField(PsiField field) {
+        analyzeCodeBlock(field, holder);
+      }
+
+      @Override
+      public void visitMethod(PsiMethod method) {
+        analyzeCodeBlock(method.getBody(), holder);
+      }
+
+      @Override
+      public void visitClassInitializer(PsiClassInitializer initializer) {
+        analyzeCodeBlock(initializer.getBody(), holder);
+      }
+    };
+  }
+
+  private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) {
+    if (scope == null) return;
+    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS);
+    final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
+    final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor);
+    if (rc == RunnerResult.OK) {
+      if (dfaRunner.problemsDetected(visitor)) {
+        createDescription(dfaRunner, holder, visitor);
+      }
+    }
+    else if (rc == RunnerResult.TOO_COMPLEX) {
+      if (scope.getParent() instanceof PsiMethod) {
+        PsiMethod method = (PsiMethod)scope.getParent();
+        final PsiIdentifier name = method.getNameIdentifier();
+        if (name != null) { // Might be null for synthetic methods like JSP page.
+          holder.registerProblem(name, InspectionsBundle.message("dataflow.too.complex"), ProblemHighlightType.WEAK_WARNING);
+        }
+      }
+    }
+  }
+
+  @Nullable
+  private LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression) {
+    if (qualifier == null || expression == null) return null;
+    if (qualifier instanceof PsiMethodCallExpression) return null;
+    if (qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null) return null;
+
+    try {
+      final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>();
+
+      if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) {
+        final Project project = qualifier.getProject();
+        final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
+        final PsiBinaryExpression binary = (PsiBinaryExpression)elementFactory.createExpressionFromText("a != null", null);
+        binary.getLOperand().replace(qualifier);
+        fixes.add(new AddAssertStatementFix(binary));
+      }
+
+      addSurroundWithIfFix(qualifier, fixes);
+
+      if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) {
+        fixes.add(new ReplaceWithTernaryOperatorFix(qualifier));
+      }
+      return fixes.toArray(new LocalQuickFix[fixes.size()]);
+    }
+    catch (IncorrectOperationException e) {
+      LOG.error(e);
+      return null;
+    }
+  }
+
+  protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
+  }
+
+  private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
+    Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
+    Set<Instruction> trueSet = constConditions.getFirst();
+    Set<Instruction> falseSet = constConditions.getSecond();
+
+    ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
+    allProblems.addAll(trueSet);
+    allProblems.addAll(falseSet);
+    allProblems.addAll(runner.getNPEInstructions());
+    allProblems.addAll(runner.getCCEInstructions());
+    allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
+
+    Collections.sort(allProblems, new Comparator<Instruction>() {
+      @Override
+      public int compare(Instruction i1, Instruction i2) {
+        return i1.getIndex() - i2.getIndex();
+      }
+    });
+
+    HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
+
+    for (Instruction instruction : allProblems) {
+      if (instruction instanceof MethodCallInstruction) {
+        reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction);
+      }
+      else if (instruction instanceof FieldReferenceInstruction) {
+        reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
+      }
+      else if (instruction instanceof TypeCastInstruction) {
+        reportCastMayFail(holder, (TypeCastInstruction)instruction);
+      }
+      else if (instruction instanceof BranchingInstruction) {
+        handleBranchingInstruction(holder, visitor, trueSet, falseSet, reportedAnchors, (BranchingInstruction)instruction);
+      }
+    }
+
+    reportNullableArguments(runner, holder);
+    reportNullableAssignments(runner, holder);
+    reportUnboxedNullables(runner, holder);
+    reportNullableReturns(runner, holder);
+    reportNullableArgumentsPassedToNonAnnotated(runner, holder);
+  }
+
+  private void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder) {
+    Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
+    for (PsiExpression expr : exprs) {
+      final String text = isNullLiteralExpression(expr)
+                          ? "Passing <code>null</code> argument to non annotated parameter"
+                          : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
+      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+      final PsiElement parent = expr.getParent();
+      if (parent instanceof PsiExpressionList) {
+        final int idx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), expr);
+        if (idx > -1) {
+          final PsiElement gParent = parent.getParent();
+          if (gParent instanceof PsiCallExpression) {
+            final PsiMethod psiMethod = ((PsiCallExpression)gParent).resolveMethod();
+            if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod) && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
+              final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+              if (idx < parameters.length) {
+                final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]);
+                fixes = fixes == null ? new LocalQuickFix[]{addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix);
+                holder.registerProblem(expr, text, fixes);
+              }
+            }
+          }
+        }
+      }
+
+    }
+  }
+
+  private void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction) {
+    if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
+      PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
+      LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
+
+      holder.registerProblem(callExpression,
+                             InspectionsBundle.message("dataflow.message.npe.method.invocation"),
+                             fix);
+    }
+  }
+
+  private void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
+    PsiElement elementToAssert = frInstruction.getElementToAssert();
+    PsiExpression expression = frInstruction.getExpression();
+    if (expression instanceof PsiArrayAccessExpression) {
+      LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
+      holder.registerProblem(expression,
+                             InspectionsBundle.message("dataflow.message.npe.array.access"),
+                             fix);
+    }
+    else {
+      LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
+      holder.registerProblem(elementToAssert,
+                             InspectionsBundle.message("dataflow.message.npe.field.access"),
+                             fix);
+    }
+  }
+
+  private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
+    PsiTypeCastExpression typeCast = instruction.getCastExpression();
+    holder.registerProblem(typeCast.getCastType(),
+                           InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
+  }
+
+  private void handleBranchingInstruction(ProblemsHolder holder,
+                                          StandardInstructionVisitor visitor,
+                                          Set<Instruction> trueSet,
+                                          Set<Instruction> falseSet, HashSet<PsiElement> reportedAnchors, BranchingInstruction instruction) {
+    PsiElement psiAnchor = instruction.getPsiAnchor();
+    boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
+    if (instruction instanceof InstanceofInstruction && visitor.isInstanceofRedundant((InstanceofInstruction)instruction)) {
+      if (visitor.canBeNull((BinopInstruction)instruction)) {
+        holder.registerProblem(psiAnchor,
+                               InspectionsBundle.message("dataflow.message.redundant.instanceof"),
+                               new RedundantInstanceofFix());
+      }
+      else {
+        final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
+        holder.registerProblem(psiAnchor,
+                               InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.when.reached" : "dataflow.message.constant.condition", Boolean.toString(true)),
+                               localQuickFix == null ? null : new LocalQuickFix[]{localQuickFix});
+      }
+    }
+    else if (psiAnchor instanceof PsiSwitchLabelStatement) {
+      if (falseSet.contains(instruction)) {
+        holder.registerProblem(psiAnchor,
+                               InspectionsBundle.message("dataflow.message.unreachable.switch.label"));
+      }
+    }
+    else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
+      boolean evaluatesToTrue = trueSet.contains(instruction);
+      if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
+        holder.registerProblem(
+          psiAnchor,
+          InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
+          createSimplifyToAssignmentFix()
+        );
+      }
+      else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) {
+        final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
+        String message = InspectionsBundle.message(underBinary ?
+                                                   "dataflow.message.constant.condition.when.reached" :
+                                                   "dataflow.message.constant.condition", Boolean.toString(evaluatesToTrue));
+        holder.registerProblem(psiAnchor, message, fix == null ? null : new LocalQuickFix[]{fix});
+      }
+      reportedAnchors.add(psiAnchor);
+    }
+  }
+
+  private boolean skipReportingConstantCondition(StandardInstructionVisitor visitor, PsiElement psiAnchor, boolean evaluatesToTrue) {
+    return DONT_REPORT_TRUE_ASSERT_STATEMENTS && isAssertionEffectively(psiAnchor, evaluatesToTrue) ||
+           visitor.silenceConstantCondition(psiAnchor);
+  }
+
+  private void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder) {
+    Set<PsiExpression> exprs = runner.getNullableArguments();
+    for (PsiExpression expr : exprs) {
+      final String text = isNullLiteralExpression(expr)
+                          ? InspectionsBundle.message("dataflow.message.passing.null.argument")
+                          : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
+      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
+      holder.registerProblem(expr, text, fixes);
+    }
+  }
+
+  private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder) {
+    for (PsiExpression expr : runner.getNullableAssignments()) {
+      final String text = isNullLiteralExpression(expr)
+                          ? InspectionsBundle.message("dataflow.message.assigning.null")
+                          : InspectionsBundle.message("dataflow.message.assigning.nullable");
+      holder.registerProblem(expr, text);
+    }
+  }
+
+  private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder) {
+    for (PsiExpression expr : runner.getUnboxedNullables()) {
+      holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
+    }
+  }
+
+  private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder) {
+    for (PsiReturnStatement statement : runner.getNullableReturns()) {
+      final PsiExpression expr = statement.getReturnValue();
+      if (runner.isInNotNullMethod()) {
+        final String text = isNullLiteralExpression(expr)
+                            ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
+                            : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
+        holder.registerProblem(expr, text);
+      }
+      else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
+        final String text = isNullLiteralExpression(expr)
+                            ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable")
+                            : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable");
+        final NullableNotNullManager manager = NullableNotNullManager.getInstance(expr.getProject());
+        holder.registerProblem(expr, text, new AnnotateMethodFix(manager.getDefaultNullable(), ArrayUtil.toStringArray(manager.getNotNulls())){
+          @Override
+          public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+            return 1;
+          }
+        });
+      }
+    }
+  }
+
+  private static boolean isAssertionEffectively(PsiElement psiAnchor, boolean evaluatesToTrue) {
+    PsiElement parent = psiAnchor.getParent();
+    if (parent instanceof PsiAssertStatement) {
+      return evaluatesToTrue;
+    }
+    if (parent instanceof PsiIfStatement && psiAnchor == ((PsiIfStatement)parent).getCondition()) {
+      PsiStatement thenBranch = ((PsiIfStatement)parent).getThenBranch();
+      if (thenBranch instanceof PsiThrowStatement) {
+        return !evaluatesToTrue;
+      }
+      if (thenBranch instanceof PsiBlockStatement) {
+        PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
+        if (statements.length == 1 && statements[0] instanceof PsiThrowStatement) {
+          return !evaluatesToTrue;
+        }
+      }
+    }
+    return false;
+  }
+
+  private static boolean isAtRHSOfBooleanAnd(PsiElement expr) {
+    PsiElement cur = expr;
+
+    while (cur != null && !(cur instanceof PsiMember)) {
+      PsiElement parent = cur.getParent();
+
+      if (parent instanceof PsiBinaryExpression && cur == ((PsiBinaryExpression)parent).getROperand()) {
+        return true;
+      }
+
+      cur = parent;
+    }
+
+    return false;
+  }
+
+  private static boolean isCompileConstantInIfCondition(PsiElement element) {
+    if (!(element instanceof PsiReferenceExpression)) return false;
+    PsiElement resolved = ((PsiReferenceExpression)element).resolve();
+    if (!(resolved instanceof PsiField)) return false;
+    PsiField field = (PsiField)resolved;
+
+    if (!field.hasModifierProperty(PsiModifier.FINAL)) return false;
+    if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
+
+    PsiElement parent = element.getParent();
+    if (parent instanceof PsiPrefixExpression && ((PsiPrefixExpression)parent).getOperationTokenType() == JavaTokenType.EXCL) {
+      element = parent;
+      parent = parent.getParent();
+    }
+    return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
+  }
+
+  private static boolean isNullLiteralExpression(PsiExpression expr) {
+    if (expr instanceof PsiLiteralExpression) {
+      final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
+      return PsiType.NULL.equals(literalExpression.getType());
+    }
+    return false;
+  }
+
+  private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
+    final PsiElement parent = psiAnchor.getParent();
+    if (parent instanceof PsiAssignmentExpression) {
+      final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
+      if (expression.getLExpression() == psiAnchor) return true;
+    }
+    return false;
+  }
+
+  @Nullable
+  private static LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
+    SimplifyBooleanExpressionFix fix = createIntention(element, value);
+    if (fix == null) return null;
+    final String text = fix.getText();
+    return new LocalQuickFix() {
+      @Override
+      @NotNull
+      public String getName() {
+        return text;
+      }
+
+      @Override
+      public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+        final PsiElement psiElement = descriptor.getPsiElement();
+        if (psiElement == null) return;
+        final SimplifyBooleanExpressionFix fix = createIntention(psiElement, value);
+        if (fix == null) return;
+        try {
+          LOG.assertTrue(psiElement.isValid());
+          fix.applyFix();
+        }
+        catch (IncorrectOperationException e) {
+          LOG.error(e);
+        }
+      }
+
+      @Override
+      @NotNull
+      public String getFamilyName() {
+        return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
+      }
+    };
+  }
+
+  @NotNull
+  private static LocalQuickFix createSimplifyToAssignmentFix() {
+    return new LocalQuickFix() {
+      @NotNull
+      @Override
+      public String getName() {
+        return InspectionsBundle.message("inspection.data.flow.simplify.to.assignment.quickfix.name");
+      }
+
+      @NotNull
+      @Override
+      public String getFamilyName() {
+        return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
+      }
+
+      @Override
+      public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+        final PsiElement psiElement = descriptor.getPsiElement();
+        if (psiElement == null) return;
+
+        final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class);
+        if (assignmentExpression == null) {
+          return;
+        }
+
+        final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
+        final String lExpressionText = assignmentExpression.getLExpression().getText();
+        final PsiExpression rExpression = assignmentExpression.getRExpression();
+        final String rExpressionText = rExpression != null ? rExpression.getText() : "";
+        assignmentExpression.replace(factory.createExpressionFromText(lExpressionText + " = " + rExpressionText, psiElement));
+      }
+    };
+  }
+
+  private static SimplifyBooleanExpressionFix createIntention(PsiElement element, boolean value) {
+    if (!(element instanceof PsiExpression)) return null;
+    final PsiExpression expression = (PsiExpression)element;
+    while (element.getParent() instanceof PsiExpression) {
+      element = element.getParent();
+    }
+    final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
+    // simplify intention already active
+    if (!fix.isAvailable() ||
+        SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
+      return null;
+    }
+    return fix;
+  }
+
+  private static class RedundantInstanceofFix implements LocalQuickFix {
+    @Override
+    @NotNull
+    public String getName() {
+      return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
+    }
+
+    @Override
+    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
+      if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) return;
+      final PsiElement psiElement = descriptor.getPsiElement();
+      if (psiElement instanceof PsiInstanceOfExpression) {
+        try {
+          final PsiExpression compareToNull = JavaPsiFacade.getInstance(psiElement.getProject()).getElementFactory().
+            createExpressionFromText(((PsiInstanceOfExpression)psiElement).getOperand().getText() + " != null", psiElement.getParent());
+          psiElement.replace(compareToNull);
+        }
+        catch (IncorrectOperationException e) {
+          LOG.error(e);
+        }
+      }
+    }
+
+    @Override
+    @NotNull
+    public String getFamilyName() {
+      return getName();
+    }
+  }
+
+
+  @Override
+  @NotNull
+  public String getDisplayName() {
+    return InspectionsBundle.message("inspection.data.flow.display.name");
+  }
+
+  @Override
+  @NotNull
+  public String getGroupDisplayName() {
+    return GroupNames.BUGS_GROUP_NAME;
+  }
+
+  @Override
+  @NotNull
+  public String getShortName() {
+    return SHORT_NAME;
+  }
+
+  private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
+    private final StandardDataFlowRunner myRunner;
+
+    private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
+      myRunner = runner;
+    }
+
+    @Override
+    protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
+      myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
+    }
+
+    @Override
+    protected void onNullableReturn(CheckReturnValueInstruction instruction) {
+      myRunner.onNullableReturn(instruction.getReturn());
+    }
+
+    @Override
+    protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
+      myRunner.onInstructionProducesCCE(instruction);
+    }
+
+    @Override
+    protected void onInstructionProducesNPE(Instruction instruction) {
+      if (instruction instanceof MethodCallInstruction &&
+          ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
+        myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
+      }
+      else {
+        myRunner.onInstructionProducesNPE(instruction);
+      }
+    }
+
+    @Override
+    protected void onPassingNullParameter(PsiExpression arg) {
+      myRunner.onPassingNullParameter(arg);
+    }
+
+    @Override
+    protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
+      myRunner.onPassingNullParameterToNonAnnotated(arg);
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
index 0340029..4e30cdd 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DataFlowRunner.java
@@ -19,7 +19,7 @@
  * User: max
  * Date: Jan 28, 2002
  * Time: 10:16:39 PM
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.codeInspection.dataFlow;
@@ -73,7 +73,7 @@
     PsiClass containingClass = PsiTreeUtil.getParentOfType(psiBlock, PsiClass.class);
     if (containingClass != null && PsiUtil.isLocalOrAnonymousClass(containingClass)) {
       final PsiElement parent = containingClass.getParent();
-      final PsiCodeBlock block = DfaUtil.getTopmostBlockInSameClass(parent);
+      final PsiCodeBlock block = DfaPsiUtil.getTopmostBlockInSameClass(parent);
       if ((parent instanceof PsiNewExpression || parent instanceof PsiDeclarationStatement) && block != null) {
         final EnvironmentalInstructionVisitor envVisitor = new EnvironmentalInstructionVisitor(visitor, parent);
         final RunnerResult result = analyzeMethod(block, envVisitor);
@@ -151,6 +151,7 @@
         if (LOG.isDebugEnabled()) {
           LOG.debug(instructionState.toString());
         }
+        //System.out.println(instructionState.toString());
 
         DfaInstructionState[] after = instruction.accept(this, instructionState.getMemoryState(), visitor);
         if (after != null) {
@@ -256,7 +257,7 @@
     private void checkEnvironment(DataFlowRunner runner, DfaMemoryState memState, @Nullable PsiElement anchor) {
       if (myClassParent == anchor) {
         DfaMemoryStateImpl copy = (DfaMemoryStateImpl)memState.createCopy();
-        copy.flushFields(runner);
+        copy.flushFields(runner.getFields());
         Set<DfaVariableValue> vars = new HashSet<DfaVariableValue>(copy.getVariableStates().keySet());
         for (DfaVariableValue value : vars) {
           copy.flushDependencies(value);
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DelegatingInstructionVisitor.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaInstructionState.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
index 8117a7a..455aaf3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryState.java
@@ -47,7 +47,7 @@
 
   boolean applyNotNull(DfaValue value);
 
-  void flushFields(DataFlowRunner runner);
+  void flushFields(DfaVariableValue[] fields);
 
   void flushVariable(DfaVariableValue variable);
 
@@ -57,5 +57,4 @@
 
   boolean isNotNull(DfaVariableValue dfaVar);
 
-  void flushVariableOutOfScope(DfaVariableValue variable);
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
index bb30b78..b7a0b51 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaMemoryStateImpl.java
@@ -25,12 +25,9 @@
 package com.intellij.codeInspection.dataFlow;
 
 import com.intellij.codeInspection.dataFlow.value.*;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.JavaTokenType;
-import com.intellij.psi.PsiPrimitiveType;
-import com.intellij.psi.PsiType;
+import com.intellij.psi.*;
 import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.containers.ContainerUtil;
@@ -43,15 +40,15 @@
 
 
 public class DfaMemoryStateImpl implements DfaMemoryState {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DfaMemoryStateImpl");
   private final DfaValueFactory myFactory;
 
-  private final ArrayList<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
+  private final List<SortedIntSet> myEqClasses = new ArrayList<SortedIntSet>();
   private int myStateSize = 0;
   private final Stack<DfaValue> myStack = new Stack<DfaValue>();
   private TIntStack myOffsetStack = new TIntStack(1);
   private final TLongHashSet myDistinctClasses = new TLongHashSet();
   private final THashMap<DfaVariableValue,DfaVariableState> myVariableStates = new THashMap<DfaVariableValue, DfaVariableState>();
+  private final THashSet<DfaVariableValue> myUnknownVariables = new THashSet<DfaVariableValue>();
 
   public DfaMemoryStateImpl(final DfaValueFactory factory) {
     myFactory = factory;
@@ -69,9 +66,9 @@
   public DfaMemoryStateImpl createCopy() {
     DfaMemoryStateImpl newState = createNew();
 
-    //noinspection unchecked
     newState.myStack.addAll(myStack);
     newState.myDistinctClasses.addAll(myDistinctClasses.toArray());
+    newState.myUnknownVariables.addAll(myUnknownVariables);
     newState.myStateSize = myStateSize;
     newState.myOffsetStack = new TIntStack(myOffsetStack);
 
@@ -97,6 +94,7 @@
     if (!myStack.equals(that.myStack)) return false;
     if (!myOffsetStack.equals(that.myOffsetStack)) return false;
     if (!myVariableStates.equals(that.myVariableStates)) return false;
+    if (!myUnknownVariables.equals(that.myUnknownVariables)) return false;
 
     int[] permutation = getPermutationToSortedState();
     int[] thatPermutation = that.getPermutationToSortedState();
@@ -174,7 +172,7 @@
 
   public int hashCode() {
     return 0;
-    //return myEqClasses.hashCode() + myStack.hashCode() + myVariableStates.hashCode();
+    //return ((myEqClasses.hashCode() * 31 + myStack.hashCode()) * 31 + myVariableStates.hashCode()) * 31 + myUnknownVariables.hashCode();
   }
 
   private void appendClass(StringBuffer buf, int aClassIndex) {
@@ -201,25 +199,34 @@
       appendClass(result, i);
     }
 
-    result.append(" distincts: ");
-    List<String> distincs = new ArrayList<String>();
-    long[] dclasses = myDistinctClasses.toArray();
-    for (long pair : dclasses) {
-      StringBuffer one = new StringBuffer();
-      one.append("{");
-      appendClass(one, low(pair));
-      one.append(", ");
-      appendClass(one, high(pair));
-      one.append("}");
-      distincs.add(one.toString());
+    if (!myDistinctClasses.isEmpty()) {
+      result.append("\n  distincts: ");
+      List<String> distincs = new ArrayList<String>();
+      long[] dclasses = myDistinctClasses.toArray();
+      for (long pair : dclasses) {
+        StringBuffer one = new StringBuffer();
+        one.append("{");
+        appendClass(one, low(pair));
+        one.append(", ");
+        appendClass(one, high(pair));
+        one.append("}");
+        distincs.add(one.toString());
+      }
+      Collections.sort(distincs);
+      result.append(StringUtil.join(distincs, " "));
     }
-    Collections.sort(distincs);
-    result.append(StringUtil.join(distincs, " "));
 
-    result.append(" stack: ").append(StringUtil.join(myStack, ","));
-    result.append(" vars: ");
-    for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
-      result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+    if (!myStack.isEmpty()) {
+      result.append("\n  stack: ").append(StringUtil.join(myStack, ","));
+    }
+    if (!myVariableStates.isEmpty()) {
+      result.append("\n  vars: ");
+      for (Map.Entry<DfaVariableValue, DfaVariableState> entry : myVariableStates.entrySet()) {
+        result.append("[").append(entry.getKey()).append("->").append(entry.getValue()).append("]");
+      }
+    }
+    if (!myUnknownVariables.isEmpty()) {
+      result.append("\n  unknowns: ").append(new HashSet<DfaVariableValue>(myUnknownVariables));
     }
     result.append('>');
     return result.toString();
@@ -684,7 +691,7 @@
 
   private static boolean isMaybeBoxedConstant(DfaValue val) {
     return val instanceof DfaConstValue ||
-           (val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue);
+           val instanceof DfaBoxedValue && ((DfaBoxedValue)val).getWrappedValue() instanceof DfaConstValue;
   }
 
   private boolean checkCompareWithBooleanLiteral(DfaValue dfaLeft, DfaValue dfaRight, boolean negated) {
@@ -713,6 +720,10 @@
   }
 
   private boolean applyRelation(@NotNull final DfaValue dfaLeft, @NotNull final DfaValue dfaRight, boolean isNegated) {
+    if (isUnknownState(dfaLeft) || isUnknownState(dfaRight)) {
+      return true;
+    }
+
     // DfaConstValue || DfaVariableValue
     Integer c1Index = getOrCreateEqClassIndex(dfaLeft);
     Integer c2Index = getOrCreateEqClassIndex(dfaRight);
@@ -732,6 +743,10 @@
     return true;
   }
 
+  private boolean isUnknownState(DfaValue val) {
+    return val instanceof DfaVariableValue && (myUnknownVariables.contains(val) || myUnknownVariables.contains(val.createNegated()));
+  }
+
   @Override
   public boolean checkNotNullable(DfaValue value) {
     if (value == myFactory.getConstFactory().getNull()) return false;
@@ -765,11 +780,16 @@
 
     if (state == null) {
       state = createVariableState(dfaVar);
-      myVariableStates.put(dfaVar, state);
       PsiType type = dfaVar.getVariableType();
       if (type != null) {
         state.setInstanceofValue(myFactory.getTypeFactory().create(type));
       }
+      if (isUnknownState(dfaVar)) {
+        state.setNullable(false);
+        return state;
+      }
+
+      myVariableStates.put(dfaVar, state);
     }
 
     return state;
@@ -784,12 +804,21 @@
   }
 
   @Override
-  public void flushFields(DataFlowRunner runner) {
-    for (DfaVariableValue field : runner.getFields()) {
-      if (myVariableStates.containsKey(field) || getEqClassIndex(field) >= 0) {
-        if (!DfaUtil.isFinalField(field.getPsiVariable())) {
-          flushVariable(field);
-          getVariableState(field).setNullable(false);
+  public void flushFields(DfaVariableValue[] fields) {
+    Set<DfaVariableValue> allVars = new HashSet<DfaVariableValue>(myVariableStates.keySet());
+    Collections.addAll(allVars, fields);
+
+    Set<DfaVariableValue> dependencies  = new HashSet<DfaVariableValue>();
+    for (DfaVariableValue variableValue : allVars) {
+      dependencies.addAll(myFactory.getVarFactory().getAllQualifiedBy(variableValue));
+    }
+    allVars.addAll(dependencies);
+
+    for (DfaVariableValue value : allVars) {
+      if (myVariableStates.containsKey(value) || getEqClassIndex(value) >= 0) {
+        if (value.isFlushableByCalls()) {
+          doFlush(value);
+          myUnknownVariables.add(value);
         }
       }
     }
@@ -799,11 +828,8 @@
   public void flushVariable(@NotNull DfaVariableValue variable) {
     doFlush(variable);
     flushDependencies(variable);
-  }
-
-  @Override
-  public void flushVariableOutOfScope(DfaVariableValue variable) {
-    flushVariable(variable);
+    myUnknownVariables.remove(variable);
+    myUnknownVariables.removeAll(myFactory.getVarFactory().getAllQualifiedBy(variable));
   }
 
   public void flushDependencies(DfaVariableValue variable) {
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
new file mode 100644
index 0000000..da25f91
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaPsiUtil.java
@@ -0,0 +1,249 @@
+/*
+ * 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.codeInspection.dataFlow;
+
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.search.LocalSearchScope;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.NullableFunction;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.containers.Stack;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+public class DfaPsiUtil {
+  public static boolean isPlainMutableField(PsiVariable var) {
+    return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
+  }
+
+  public static boolean isFinalField(PsiVariable var) {
+    return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
+  }
+
+  static PsiElement getEnclosingCodeBlock(final PsiVariable variable, final PsiElement context) {
+    PsiElement codeBlock;
+    if (variable instanceof PsiParameter) {
+      codeBlock = ((PsiParameter)variable).getDeclarationScope();
+      if (codeBlock instanceof PsiMethod) {
+        codeBlock = ((PsiMethod)codeBlock).getBody();
+      }
+    }
+    else if (variable instanceof PsiLocalVariable) {
+      codeBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
+    }
+    else {
+      codeBlock = PsiTreeUtil.getParentOfType(context, PsiCodeBlock.class);
+    }
+    while (codeBlock != null) {
+      PsiAnonymousClass anon = PsiTreeUtil.getParentOfType(codeBlock, PsiAnonymousClass.class);
+      if (anon == null) break;
+      codeBlock = PsiTreeUtil.getParentOfType(anon, PsiCodeBlock.class);
+    }
+    return codeBlock;
+  }
+
+  @NotNull
+  public static Nullness getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) {
+    if (owner == null) {
+      return Nullness.UNKNOWN;
+    }
+
+    if (NullableNotNullManager.isNullable(owner)) {
+      return Nullness.NULLABLE;
+    }
+    if (NullableNotNullManager.isNotNull(owner)) {
+      return Nullness.NOT_NULL;
+    }
+
+    if (resultType != null) {
+      NullableNotNullManager nnn = NullableNotNullManager.getInstance(owner.getProject());
+      for (PsiAnnotation annotation : resultType.getAnnotations()) {
+        String qualifiedName = annotation.getQualifiedName();
+        if (nnn.getNullables().contains(qualifiedName)) {
+          return Nullness.NULLABLE;
+        }
+        if (nnn.getNotNulls().contains(qualifiedName)) {
+          return Nullness.NOT_NULL;
+        }
+      }
+    }
+
+    return Nullness.UNKNOWN;
+  }
+
+  public static List<PsiExpression> findAllConstructorInitializers(PsiField field) {
+    final List<PsiExpression> result = ContainerUtil.createLockFreeCopyOnWriteList();
+    ContainerUtil.addIfNotNull(result, field.getInitializer());
+
+    PsiClass containingClass = field.getContainingClass();
+    if (containingClass != null) {
+      LocalSearchScope scope = new LocalSearchScope(containingClass.getConstructors());
+      ReferencesSearch.search(field, scope, false).forEach(new Processor<PsiReference>() {
+        @Override
+        public boolean process(PsiReference reference) {
+          final PsiElement element = reference.getElement();
+          if (element instanceof PsiReferenceExpression) {
+            final PsiAssignmentExpression assignment = getAssignmentExpressionIfOnAssignmentLhs(element);
+            final PsiMethod method = PsiTreeUtil.getParentOfType(assignment, PsiMethod.class);
+            if (method != null && method.isConstructor() && assignment != null) {
+              ContainerUtil.addIfNotNull(result, assignment.getRExpression());
+            }
+          }
+          return true;
+        }
+      });
+    }
+    return result;
+  }
+
+  @Nullable
+  private static PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLhs(PsiElement expression) {
+    PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
+    if (!(parent instanceof PsiAssignmentExpression)) {
+      return null;
+    }
+    final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+    if (!PsiTreeUtil.isAncestor(assignmentExpression.getLExpression(), expression, false)) {
+      return null;
+    }
+    return assignmentExpression;
+  }
+
+  public static boolean isNullableInitialized(PsiVariable var, boolean nullable) {
+    if (!isFinalField(var)) {
+      return false;
+    }
+
+    List<PsiExpression> initializers = findAllConstructorInitializers((PsiField)var);
+    if (initializers.isEmpty()) {
+      return false;
+    }
+
+    for (PsiExpression expression : initializers) {
+      if (!(expression instanceof PsiReferenceExpression)) {
+        return false;
+      }
+      PsiElement target = ((PsiReferenceExpression)expression).resolve();
+      if (!(target instanceof PsiParameter)) {
+        return false;
+      }
+      if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) {
+        return true;
+      }
+      if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) {
+        return false;
+      }
+    }
+    return !nullable;
+  }
+
+  @Nullable
+  public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) {
+    PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class);
+    if (block == null) {
+      return null;
+    }
+
+    PsiCodeBlock lastBlock = block;
+    while (true) {
+      block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class, true, PsiMember.class, PsiFile.class);
+      if (block == null) {
+        return lastBlock;
+      }
+      lastBlock = block;
+    }
+  }
+
+  @NotNull
+  public static Collection<PsiExpression> getVariableAssignmentsInFile(@NotNull PsiVariable psiVariable,
+                                                                       final boolean literalsOnly,
+                                                                       final PsiElement place) {
+    final Ref<Boolean> modificationRef = Ref.create(Boolean.FALSE);
+    final PsiCodeBlock codeBlock = place == null? null : getTopmostBlockInSameClass(place);
+    final int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0;
+    List<PsiExpression> list = ContainerUtil.mapNotNull(
+      ReferencesSearch.search(psiVariable, new LocalSearchScope(new PsiElement[] {psiVariable.getContainingFile()}, null, true)).findAll(),
+      new NullableFunction<PsiReference, PsiExpression>() {
+        @Override
+        public PsiExpression fun(final PsiReference psiReference) {
+          if (modificationRef.get()) return null;
+          final PsiElement parent = psiReference.getElement().getParent();
+          if (parent instanceof PsiAssignmentExpression) {
+            final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
+            final IElementType operation = assignmentExpression.getOperationTokenType();
+            if (assignmentExpression.getLExpression() == psiReference) {
+              if (JavaTokenType.EQ.equals(operation)) {
+                final PsiExpression rValue = assignmentExpression.getRExpression();
+                if (!literalsOnly || allOperandsAreLiterals(rValue)) {
+                  // if there's a codeBlock omit the values assigned later
+                  if (codeBlock != null && PsiTreeUtil.isAncestor(codeBlock, parent, true)
+                      && placeOffset < parent.getTextRange().getStartOffset()) {
+                    return null;
+                  }
+                  return rValue;
+                }
+                else {
+                  modificationRef.set(Boolean.TRUE);
+                }
+              }
+              else if (JavaTokenType.PLUSEQ.equals(operation)) {
+                modificationRef.set(Boolean.TRUE);
+              }
+            }
+          }
+          return null;
+        }
+      });
+    if (modificationRef.get()) return Collections.emptyList();
+    PsiExpression initializer = psiVariable.getInitializer();
+    if (initializer != null && (!literalsOnly || allOperandsAreLiterals(initializer))) {
+      list = ContainerUtil.concat(list, Collections.singletonList(initializer));
+    }
+    return list;
+  }
+
+  public static boolean allOperandsAreLiterals(@Nullable final PsiExpression expression) {
+    if (expression == null) return false;
+    if (expression instanceof PsiLiteralExpression) return true;
+    if (expression instanceof PsiPolyadicExpression) {
+      Stack<PsiExpression> stack = new Stack<PsiExpression>();
+      stack.add(expression);
+      while (!stack.isEmpty()) {
+        PsiExpression psiExpression = stack.pop();
+        if (psiExpression instanceof PsiPolyadicExpression) {
+          PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)psiExpression;
+          for (PsiExpression op : binaryExpression.getOperands()) {
+            stack.push(op);
+          }
+        }
+        else if (!(psiExpression instanceof PsiLiteralExpression)) {
+          return false;
+        }
+      }
+      return true;
+    }
+    return false;
+  }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
new file mode 100644
index 0000000..808872f
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
@@ -0,0 +1,196 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.dataFlow;
+
+import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
+import com.intellij.codeInspection.dataFlow.instructions.Instruction;
+import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
+import com.intellij.codeInspection.dataFlow.value.DfaValue;
+import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
+import com.intellij.openapi.util.Key;
+import com.intellij.openapi.util.MultiValuesMap;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.psi.util.CachedValue;
+import com.intellij.psi.util.CachedValueProvider;
+import com.intellij.psi.util.CachedValuesManager;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author Gregory.Shrago
+ */
+public class DfaUtil {
+  private static final Key<CachedValue<MultiValuesMap<PsiVariable, PsiExpression>>> DFA_VARIABLE_INFO_KEY = Key.create("DFA_VARIABLE_INFO_KEY");
+
+  private DfaUtil() {
+  }
+
+  private static final MultiValuesMap<PsiVariable, PsiExpression> TOO_COMPLEX = new MultiValuesMap<PsiVariable, PsiExpression>();
+  @Nullable("null means DFA analysis has failed (too complex to analyze)")
+  public static Collection<PsiExpression> getCachedVariableValues(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
+    if (variable == null || context == null) return Collections.emptyList();
+
+    CachedValue<MultiValuesMap<PsiVariable, PsiExpression>> cachedValue = context.getUserData(DFA_VARIABLE_INFO_KEY);
+    if (cachedValue == null) {
+      final PsiElement codeBlock = DfaPsiUtil.getEnclosingCodeBlock(variable, context);
+      cachedValue = CachedValuesManager.getManager(context.getProject()).createCachedValue(new CachedValueProvider<MultiValuesMap<PsiVariable, PsiExpression>>() {
+        @Override
+        public Result<MultiValuesMap<PsiVariable, PsiExpression>> compute() {
+          final MultiValuesMap<PsiVariable, PsiExpression> result;
+          if (codeBlock == null) {
+            result = null;
+          }
+          else {
+            final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
+            RunnerResult runnerResult = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
+            if (runnerResult == RunnerResult.OK) {
+              result = visitor.myValues;
+            }
+            else {
+              result = TOO_COMPLEX;
+            }
+          }
+          return new Result<MultiValuesMap<PsiVariable, PsiExpression>>(result, codeBlock);
+        }
+      }, false);
+      context.putUserData(DFA_VARIABLE_INFO_KEY, cachedValue);
+    }
+    final MultiValuesMap<PsiVariable, PsiExpression> value = cachedValue.getValue();
+    if (value == TOO_COMPLEX) return null;
+    final Collection<PsiExpression> expressions = value == null ? null : value.get(variable);
+    return expressions == null ? Collections.<PsiExpression>emptyList() : expressions;
+  }
+
+  @NotNull
+  public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
+    if (variable == null || context == null) return Nullness.UNKNOWN;
+
+    final PsiElement codeBlock = DfaPsiUtil.getEnclosingCodeBlock(variable, context);
+    if (codeBlock == null) {
+      return Nullness.UNKNOWN;
+    }
+    final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
+    RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
+    if (result != RunnerResult.OK) {
+      return Nullness.UNKNOWN;
+    }
+    if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULLABLE;
+    if (visitor.myNotNulls.contains(variable) && !visitor.myNulls.contains(variable)) return Nullness.NOT_NULL;
+    return Nullness.UNKNOWN;
+  }
+
+  @NotNull
+  public static Collection<? extends PsiElement> getPossibleInitializationElements(final PsiElement qualifierExpression) {
+    if (qualifierExpression instanceof PsiMethodCallExpression) {
+      return Collections.singletonList(qualifierExpression);
+    }
+    if (qualifierExpression instanceof PsiReferenceExpression) {
+      final PsiElement targetElement = ((PsiReferenceExpression)qualifierExpression).resolve();
+      if (!(targetElement instanceof PsiVariable)) {
+        return Collections.emptyList();
+      }
+      final Collection<? extends PsiElement> variableValues = getCachedVariableValues((PsiVariable)targetElement, qualifierExpression);
+      if (variableValues == null || variableValues.isEmpty()) {
+        return DfaPsiUtil.getVariableAssignmentsInFile((PsiVariable)targetElement, false, qualifierExpression);
+      }
+      return variableValues;
+    }
+    if (qualifierExpression instanceof PsiLiteralExpression) {
+      return Collections.singletonList(qualifierExpression);
+    }
+    return Collections.emptyList();
+  }
+
+  private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
+    final MultiValuesMap<PsiVariable, PsiExpression> myValues = new MultiValuesMap<PsiVariable, PsiExpression>(true);
+    final Set<PsiVariable> myNulls = new THashSet<PsiVariable>();
+    final Set<PsiVariable> myNotNulls = new THashSet<PsiVariable>();
+    private final PsiElement myContext;
+
+    public ValuableInstructionVisitor(@NotNull PsiElement context) {
+      myContext = context;
+    }
+
+    @Override
+    public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+      if (myContext == instruction.getPlace()) {
+        final Map<DfaVariableValue,DfaVariableState> map = ((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableStates();
+        for (Map.Entry<DfaVariableValue, DfaVariableState> entry : map.entrySet()) {
+          ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)entry.getValue();
+          DfaVariableValue variableValue = entry.getKey();
+          final PsiExpression psiExpression = state.myExpression;
+          if (psiExpression != null && variableValue.getQualifier() == null) {
+            myValues.put(variableValue.getPsiVariable(), psiExpression);
+          }
+        }
+        DfaValue value = instruction.getValue();
+        if (value instanceof DfaVariableValue && ((DfaVariableValue)value).getQualifier() == null) {
+          if (memState.isNotNull((DfaVariableValue)value)) {
+            myNotNulls.add(((DfaVariableValue)value).getPsiVariable());
+          }
+          if (memState.isNull(value)) {
+            myNulls.add(((DfaVariableValue)value).getPsiVariable());
+          }
+        }
+      }
+      return super.visitPush(instruction, runner, memState);
+    }
+
+    @Override
+    public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
+      final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
+
+      final DfaValue dfaSource = memState.pop();
+      final DfaValue dfaDest = memState.pop();
+
+      if (dfaDest instanceof DfaVariableValue) {
+        DfaVariableValue var = (DfaVariableValue)dfaDest;
+        final PsiExpression rightValue = instruction.getRExpression();
+        final PsiElement parent = rightValue == null ? null : rightValue.getParent();
+        final IElementType type = parent instanceof PsiAssignmentExpression
+                                  ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
+        // store current value - to use in case of '+='
+        final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
+        memState.setVarValue(var, dfaSource);
+        // state may have been changed so re-retrieve it
+        final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
+        final PsiExpression curValue = curState.myExpression;
+        final PsiExpression nextValue;
+        if (type == JavaTokenType.PLUSEQ && prevValue != null) {
+          PsiExpression tmpExpression;
+          try {
+            tmpExpression = JavaPsiFacade.getElementFactory(myContext.getProject())
+              .createExpressionFromText(prevValue.getText() + "+" + rightValue.getText(), rightValue);
+          }
+          catch (Exception e) {
+            tmpExpression = curValue == null ? rightValue : curValue;
+          }
+          nextValue = tmpExpression;
+        }
+        else {
+          nextValue = curValue == null ? rightValue : curValue;
+        }
+        curState.myExpression = nextValue;
+      }
+      memState.push(dfaDest);
+      return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/DfaVariableState.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
index 6d8d8d6..b1d3203 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/InstructionVisitor.java
@@ -119,9 +119,9 @@
   public DfaInstructionState[] visitFlushVariable(FlushVariableInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
     final DfaVariableValue variable = instruction.getVariable();
     if (variable != null) {
-      memState.flushVariableOutOfScope(variable);
+      memState.flushVariable(variable);
     } else {
-      memState.flushFields(runner);
+      memState.flushFields(runner.getFields());
     }
     return nextInstruction(instruction, runner, memState);
   }
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/Nullness.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/RunnerResult.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/SortedIntSet.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
similarity index 97%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
index 54df852..fc10e2e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/StandardInstructionVisitor.java
@@ -55,7 +55,7 @@
         return Nullness.NOT_NULL;
       }
 
-      return callExpression != null ? DfaUtil.getElementNullability(key.getResultType(), callExpression.resolveMethod()) : null;
+      return callExpression != null ? DfaPsiUtil.getElementNullability(key.getResultType(), callExpression.resolveMethod()) : null;
     }
   };
 
@@ -74,7 +74,7 @@
 
         Map<PsiExpression, Nullness> map = ContainerUtil.newHashMap();
         for (int i = 0; i < checkedCount; i++) {
-          map.put(args[i], DfaUtil.getElementNullability(substitutor.substitute(parameters[i].getType()), parameters[i]));
+          map.put(args[i], DfaPsiUtil.getElementNullability(substitutor.substitute(parameters[i].getType()), parameters[i]));
         }
         return map;
       }
@@ -112,7 +112,7 @@
     if (dfaDest instanceof DfaVariableValue) {
       DfaVariableValue var = (DfaVariableValue) dfaDest;
       final PsiVariable psiVariable = var.getPsiVariable();
-      if (DfaUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
+      if (DfaPsiUtil.getElementNullability(var.getVariableType(), psiVariable) == Nullness.NOT_NULL) {
         if (!memState.applyNotNull(dfaSource)) {
           onAssigningToNotNullableVariable(instruction);
         }
@@ -215,7 +215,7 @@
     finally {
       memState.push(getMethodResultValue(instruction, qualifier, runner.getFactory()));
       if (instruction.shouldFlushFields()) {
-        memState.flushFields(runner);
+        memState.flushFields(runner.getFields());
       }
     }
   }
@@ -229,9 +229,6 @@
 
     final PsiType type = instruction.getResultType();
     final MethodCallInstruction.MethodType methodType = instruction.getMethodType();
-    if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
-      return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
-    }
 
     if (methodType == MethodCallInstruction.MethodType.UNBOXING) {
       return factory.getBoxedFactory().createUnboxed(qualifierValue);
@@ -239,7 +236,7 @@
 
     if (methodType == MethodCallInstruction.MethodType.BOXING) {
       DfaValue boxed = factory.getBoxedFactory().createBoxed(qualifierValue);
-      return boxed == null ? DfaUnknownValue.getInstance() : boxed;
+      return boxed == null ? factory.getNotNullFactory().create(type) : boxed;
     }
 
     if (methodType == MethodCallInstruction.MethodType.CAST) {
@@ -248,6 +245,10 @@
       }
       return qualifierValue;
     }
+
+    if (type != null && (type instanceof PsiClassType || type.getArrayDimensions() > 0)) {
+      return factory.createTypeValueWithNullability(type, myReturnTypeNullability.get(instruction));
+    }
     return DfaUnknownValue.getInstance();
   }
 
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/ValuableDataFlowRunner.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/WorkingTimeMeasurer.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/AssignInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BinopInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/BranchingInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/CheckReturnValueInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ConditionalGotoInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/DupInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/EmptyStackInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FieldReferenceInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/FlushVariableInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GosubInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/GotoInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/InstanceofInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
similarity index 94%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
index 505deaa..5514268 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/Instruction.java
@@ -19,7 +19,7 @@
  * User: max
  * Date: Jan 26, 2002
  * Time: 10:46:40 PM
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.codeInspection.dataFlow.instructions;
@@ -31,10 +31,11 @@
 import com.intellij.openapi.progress.ProgressManager;
 
 import java.util.ArrayList;
+import java.util.List;
 
 public abstract class Instruction {
   private int myIndex;
-  private final ArrayList<DfaMemoryState> myProcessedStates;
+  private final List<DfaMemoryState> myProcessedStates;
 
   protected Instruction() {
     myProcessedStates = new ArrayList<DfaMemoryState>();
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
similarity index 74%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
index 5f65a86..a46abb6 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/MethodCallInstruction.java
@@ -36,44 +36,35 @@
 
 public class MethodCallInstruction extends Instruction {
   @Nullable private final PsiCallExpression myCall;
-  @Nullable private PsiType myType;
+  @Nullable private final PsiType myType;
   @NotNull private final PsiExpression[] myArgs;
-  private boolean myShouldFlushFields;
+  private final boolean myShouldFlushFields;
   @NotNull private final PsiExpression myContext;
   private final MethodType myMethodType;
-  @Nullable private DfaValue myPrecalculatedReturnValue;
+  @Nullable private final DfaValue myPrecalculatedReturnValue;
   public enum MethodType {
     BOXING, UNBOXING, REGULAR_METHOD_CALL, CAST
   }
 
-  public MethodCallInstruction(@NotNull PsiCallExpression callExpression, @Nullable DfaValue precalculatedReturnValue) {
-    this(callExpression, MethodType.REGULAR_METHOD_CALL);
-    myPrecalculatedReturnValue = precalculatedReturnValue;
-  }
-
   public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType, @Nullable PsiType resultType) {
-    this(context, methodType);
-    myType = resultType;
-    myShouldFlushFields = false;
-  }
-
-  public MethodCallInstruction(@NotNull PsiExpression context, MethodType methodType) {
     myContext = context;
     myMethodType = methodType;
-    myCall = methodType == MethodType.REGULAR_METHOD_CALL && context instanceof PsiCallExpression ? (PsiCallExpression)context : null;
-    final PsiExpressionList argList = myCall == null ? null : myCall.getArgumentList();
-    myArgs = argList != null ? argList.getExpressions() : PsiExpression.EMPTY_ARRAY;
-
-    myType = myCall == null ? null : myCall.getType();
-
-    myShouldFlushFields = true;
-    if (myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0) {
-      myShouldFlushFields = false;
-    }
+    myCall = null;
+    myArgs = PsiExpression.EMPTY_ARRAY;
+    myType = resultType;
+    myShouldFlushFields = false;
+    myPrecalculatedReturnValue = null;
   }
 
-  public void setShouldFlushFields(boolean shouldFlushFields) {
-    myShouldFlushFields = shouldFlushFields;
+  public MethodCallInstruction(@NotNull PsiCallExpression context, @Nullable DfaValue precalculatedReturnValue) {
+    myContext = context;
+    myMethodType = MethodType.REGULAR_METHOD_CALL;
+    myCall = context;
+    final PsiExpressionList argList = context.getArgumentList();
+    myArgs = argList != null ? argList.getExpressions() : PsiExpression.EMPTY_ARRAY;
+    myType = myCall.getType();
+    myShouldFlushFields = !(myCall instanceof PsiNewExpression && myType != null && myType.getArrayDimensions() > 0);
+    myPrecalculatedReturnValue = precalculatedReturnValue;
   }
 
   @Nullable
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/NotInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PopInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/PushInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnFromSubInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/ReturnInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/SwapInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/instructions/TypeCastInstruction.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaBoxedValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaConstValue.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
similarity index 90%
rename from java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
index 574fa5e..833f503 100644
--- a/java/java-impl/src/com/intellij/codeInsight/guess/impl/DfaInstanceofValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaInstanceofValue.java
@@ -13,10 +13,8 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-package com.intellij.codeInsight.guess.impl;
+package com.intellij.codeInspection.dataFlow.value;
 
-import com.intellij.codeInspection.dataFlow.value.DfaValue;
-import com.intellij.codeInspection.dataFlow.value.DfaValueFactory;
 import com.intellij.psi.PsiExpression;
 import com.intellij.psi.PsiType;
 import org.jetbrains.annotations.NotNull;
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaNotNullValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaRelationValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaTypeValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnboxedValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaUnknownValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValue.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaValueFactory.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
index 758059b..39541bf 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/dataFlow/value/DfaVariableValue.java
@@ -24,10 +24,9 @@
  */
 package com.intellij.codeInspection.dataFlow.value;
 
-import com.intellij.codeInspection.dataFlow.DfaUtil;
+import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
 import com.intellij.codeInspection.dataFlow.Nullness;
-import com.intellij.psi.PsiType;
-import com.intellij.psi.PsiVariable;
+import com.intellij.psi.*;
 import com.intellij.util.containers.HashMap;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
@@ -160,11 +159,11 @@
     }
 
     PsiVariable var = getPsiVariable();
-    Nullness nullability = DfaUtil.getElementNullability(getVariableType(), var);
+    Nullness nullability = DfaPsiUtil.getElementNullability(getVariableType(), var);
     if (nullability == Nullness.UNKNOWN && var != null) {
-      if (DfaUtil.isNullableInitialized(var, true)) {
+      if (DfaPsiUtil.isNullableInitialized(var, true)) {
         nullability = Nullness.NULLABLE;
-      } else if (DfaUtil.isNullableInitialized(var, false)) {
+      } else if (DfaPsiUtil.isNullableInitialized(var, false)) {
         nullability = Nullness.NOT_NULL;
       }
     }
@@ -174,4 +173,14 @@
     return nullability;
   }
 
+  public boolean isLocalVariable() {
+    return myVariable instanceof PsiLocalVariable || myVariable instanceof PsiParameter;
+  }
+
+  public boolean isFlushableByCalls() {
+    if (isLocalVariable()) return false;
+    if (!myVariable.hasModifierProperty(PsiModifier.FINAL)) return true;
+    return myQualifier != null && myQualifier.isFlushableByCalls();
+  }
+
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java
new file mode 100644
index 0000000..b21e514
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/defUse/DefUseInspectionBase.java
@@ -0,0 +1,218 @@
+package com.intellij.codeInspection.defUse;
+
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInspection.*;
+import com.intellij.psi.*;
+import com.intellij.psi.controlFlow.DefUseUtil;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.event.ChangeEvent;
+import javax.swing.event.ChangeListener;
+import java.awt.*;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+import java.util.Set;
+
+public class DefUseInspectionBase extends BaseJavaBatchLocalInspectionTool {
+  public boolean REPORT_PREFIX_EXPRESSIONS = false;
+  public boolean REPORT_POSTFIX_EXPRESSIONS = true;
+  public boolean REPORT_REDUNDANT_INITIALIZER = true;
+
+  public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.unused.assignment.display.name");
+  @NonNls public static final String SHORT_NAME = "UnusedAssignment";
+
+  @Override
+  @NotNull
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+    return new JavaElementVisitor() {
+      @Override public void visitMethod(PsiMethod method) {
+        checkCodeBlock(method.getBody(), holder, isOnTheFly);
+      }
+
+      @Override public void visitClassInitializer(PsiClassInitializer initializer) {
+        checkCodeBlock(initializer.getBody(), holder, isOnTheFly);
+      }
+    };
+  }
+
+  private void checkCodeBlock(final PsiCodeBlock body,
+                              final ProblemsHolder holder,
+                              final boolean isOnTheFly) {
+    if (body == null) return;
+    final Set<PsiVariable> usedVariables = new THashSet<PsiVariable>();
+    List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(body, usedVariables);
+
+    if (unusedDefs != null && !unusedDefs.isEmpty()) {
+      Collections.sort(unusedDefs, new Comparator<DefUseUtil.Info>() {
+        @Override
+        public int compare(DefUseUtil.Info o1, DefUseUtil.Info o2) {
+          int offset1 = o1.getContext().getTextOffset();
+          int offset2 = o2.getContext().getTextOffset();
+
+          if (offset1 == offset2) return 0;
+          if (offset1 < offset2) return -1;
+
+          return 1;
+        }
+      });
+
+      for (DefUseUtil.Info info : unusedDefs) {
+        PsiElement context = info.getContext();
+        PsiVariable psiVariable = info.getVariable();
+
+        if (context instanceof PsiDeclarationStatement || context instanceof PsiResourceVariable) {
+          if (!info.isRead()) {
+            if (!isOnTheFly) {
+              holder.registerProblem(psiVariable.getNameIdentifier(),
+                                     InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "<code>#ref</code> #loc"),
+                                     ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+            }
+          }
+          else {
+            if (REPORT_REDUNDANT_INITIALIZER) {
+              holder.registerProblem(psiVariable.getInitializer(),
+                                     InspectionsBundle.message("inspection.unused.assignment.problem.descriptor2",
+                                                               "<code>" + psiVariable.getName() + "</code>", "<code>#ref</code> #loc"),
+                                     ProblemHighlightType.LIKE_UNUSED_SYMBOL,
+                                     createRemoveInitializerFix());
+            }
+          }
+        }
+        else if (context instanceof PsiAssignmentExpression &&
+                 ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ) {
+          final PsiAssignmentExpression assignment = (PsiAssignmentExpression)context;
+          holder.registerProblem(assignment.getLExpression(),
+                                 InspectionsBundle.message("inspection.unused.assignment.problem.descriptor3",
+                                                           assignment.getRExpression().getText(), "<code>#ref</code>" + " #loc"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+        }
+        else {
+          if (context instanceof PsiPrefixExpression && REPORT_PREFIX_EXPRESSIONS ||
+              context instanceof PsiPostfixExpression && REPORT_POSTFIX_EXPRESSIONS) {
+            holder.registerProblem(context,
+                                   InspectionsBundle.message("inspection.unused.assignment.problem.descriptor4", "<code>#ref</code> #loc"));
+          }
+        }
+      }
+    }
+
+    body.accept(new JavaRecursiveElementWalkingVisitor() {
+      @Override public void visitClass(PsiClass aClass) {
+      }
+
+      @Override public void visitLocalVariable(PsiLocalVariable variable) {
+        if (!usedVariables.contains(variable) && variable.getInitializer() == null && !isOnTheFly) {
+          holder.registerProblem(variable.getNameIdentifier(),
+                                 InspectionsBundle.message("inspection.unused.assignment.problem.descriptor5", "<code>#ref</code> #loc"),
+                                 ProblemHighlightType.LIKE_UNUSED_SYMBOL);
+        }
+      }
+
+      @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+        PsiExpression lExpression = expression.getLExpression();
+        PsiExpression rExpression = expression.getRExpression();
+
+        if (lExpression instanceof PsiReferenceExpression && rExpression instanceof PsiReferenceExpression) {
+          PsiReferenceExpression lRef = (PsiReferenceExpression)lExpression;
+          PsiReferenceExpression rRef = (PsiReferenceExpression)rExpression;
+
+          if (lRef.resolve() != rRef.resolve()) return;
+          PsiExpression lQualifier = lRef.getQualifierExpression();
+          PsiExpression rQualifier = rRef.getQualifierExpression();
+
+          if ((lQualifier == null && rQualifier == null ||
+               lQualifier instanceof PsiThisExpression && rQualifier instanceof PsiThisExpression ||
+               lQualifier instanceof PsiThisExpression && rQualifier == null ||
+               lQualifier == null && rQualifier instanceof PsiThisExpression) && !isOnTheFly) {
+            holder.registerProblem(expression,
+                                   InspectionsBundle.message("inspection.unused.assignment.problem.descriptor6", "<code>#ref</code>"));
+          }
+        }
+      }
+    });
+  }
+
+  protected LocalQuickFix createRemoveInitializerFix() {
+    return null;
+  }
+
+  @Override
+  public JComponent createOptionsPanel() {
+    return new OptionsPanel();
+  }
+
+  private class OptionsPanel extends JPanel {
+    private final JCheckBox myReportPrefix;
+    private final JCheckBox myReportPostfix;
+    private final JCheckBox myReportInitializer;
+
+    private OptionsPanel() {
+      super(new GridBagLayout());
+
+      GridBagConstraints gc = new GridBagConstraints();
+      gc.weighty = 0;
+      gc.weightx = 1;
+      gc.fill = GridBagConstraints.HORIZONTAL;
+      gc.anchor = GridBagConstraints.NORTHWEST;
+
+      myReportInitializer = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option2"));
+      myReportInitializer.setSelected(REPORT_REDUNDANT_INITIALIZER);
+      myReportInitializer.getModel().addChangeListener(new ChangeListener() {
+        @Override
+        public void stateChanged(ChangeEvent e) {
+          REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected();
+        }
+      });
+      gc.insets = new Insets(0, 0, 15, 0);
+      gc.gridy = 0;
+      add(myReportInitializer, gc);
+
+      myReportPrefix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option"));
+      myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS);
+      myReportPrefix.getModel().addChangeListener(new ChangeListener() {
+        @Override
+        public void stateChanged(ChangeEvent e) {
+          REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected();
+        }
+      });
+      gc.insets = new Insets(0, 0, 0, 0);
+      gc.gridy++;
+      add(myReportPrefix, gc);
+
+      myReportPostfix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option1"));
+      myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS);
+      myReportPostfix.getModel().addChangeListener(new ChangeListener() {
+        @Override
+        public void stateChanged(ChangeEvent e) {
+          REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected();
+        }
+      });
+
+      gc.weighty = 1;
+      gc.gridy++;
+      add(myReportPostfix, gc);
+    }
+  }
+
+
+  @Override
+  @NotNull
+  public String getDisplayName() {
+    return DISPLAY_NAME;
+  }
+
+  @Override
+  @NotNull
+  public String getGroupDisplayName() {
+    return GroupNames.BUGS_GROUP_NAME;
+  }
+
+  @Override
+  @NotNull
+  public String getShortName() {
+    return SHORT_NAME;
+  }
+}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
similarity index 93%
rename from java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
index b17f1f5..85b3674 100644
--- a/java/java-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/deprecation/DeprecationInspection.java
@@ -16,18 +16,15 @@
 package com.intellij.codeInspection.deprecation;
 
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
 import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
+import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.ui.MultipleCheckboxOptionsPanel;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
 import com.intellij.psi.infos.MethodCandidateInfo;
 import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.util.RefactoringUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -38,10 +35,10 @@
 /**
  * @author max
  */
-public class DeprecationInspection extends BaseJavaLocalInspectionTool {
-  @NonNls public static final String SHORT_NAME = HighlightInfoType.DEPRECATION_SHORT_NAME;
-  @NonNls public static final String ID = HighlightInfoType.DEPRECATION_ID;
-  public static final String DISPLAY_NAME = HighlightInfoType.DEPRECATION_DISPLAY_NAME;
+public class DeprecationInspection extends BaseJavaBatchLocalInspectionTool {
+  @NonNls public static final String SHORT_NAME = DeprecationUtil.DEPRECATION_SHORT_NAME;
+  @NonNls public static final String ID = DeprecationUtil.DEPRECATION_ID;
+  public static final String DISPLAY_NAME = DeprecationUtil.DEPRECATION_DISPLAY_NAME;
 
   public boolean IGNORE_INSIDE_DEPRECATED = false;
   public boolean IGNORE_ABSTRACT_DEPRECATED_OVERRIDES = true;
@@ -178,7 +175,7 @@
         final PsiCodeBlock body = method.getBody();
         if (body != null) {
           final PsiStatement[] statements = body.getStatements();
-          if (statements.length == 0 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true)) {
+          if (statements.length == 0 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
             registerDefaultConstructorProblem(superClass, method.getNameIdentifier(), false);
           }
         }
diff --git a/java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
index b01d105..b95c3c9 100644
--- a/java/java-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/duplicateThrows/DuplicateThrowsInspection.java
@@ -16,11 +16,7 @@
 package com.intellij.codeInspection.duplicateThrows;
 
 import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInspection.DeleteThrowsFix;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.ui.SingleCheckboxOptionsPanel;
 import com.intellij.psi.*;
 import org.jetbrains.annotations.NotNull;
@@ -28,8 +24,7 @@
 
 import javax.swing.*;
 
-public class DuplicateThrowsInspection extends BaseLocalInspectionTool {
-
+public class DuplicateThrowsInspection extends BaseJavaBatchLocalInspectionTool {
   @SuppressWarnings("PublicField")
   public boolean ignoreSubclassing = false;
 
@@ -94,4 +89,9 @@
       }
     };
   }
+
+  @Override
+  public boolean isEnabledByDefault() {
+    return true;
+  }
 }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
new file mode 100644
index 0000000..eaab7a3
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
@@ -0,0 +1,135 @@
+/*
+ * 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.codeInspection.inheritance;
+
+import com.intellij.codeInsight.FileModificationService;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.intention.LowPriorityAction;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.TestOnly;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+public class ChangeSuperClassFix implements LocalQuickFix {
+  @NotNull
+  private final PsiClass myNewSuperClass;
+  @NotNull
+  private final PsiClass myOldSuperClass;
+  private final int myPercent;
+
+  public ChangeSuperClassFix(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
+    myNewSuperClass = newSuperClass;
+    myOldSuperClass = oldSuperClass;
+    myPercent = percent;
+  }
+
+  @NotNull
+  @TestOnly
+  public PsiClass getNewSuperClass() {
+    return myNewSuperClass;
+  }
+
+  @TestOnly
+  public int getPercent() {
+    return myPercent;
+  }
+
+  @NotNull
+  @Override
+  public String getName() {
+    return String.format("Make extends '%s' - %s%%", myNewSuperClass.getQualifiedName(), myPercent);
+  }
+
+  @NotNull
+  @Override
+  public String getFamilyName() {
+    return GroupNames.INHERITANCE_GROUP_NAME;
+  }
+
+  @Override
+  public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor problemDescriptor) {
+    changeSuperClass((PsiClass)problemDescriptor.getPsiElement(), myOldSuperClass, myNewSuperClass);
+  }
+
+  /**
+   * myOldSuperClass and myNewSuperClass can be interfaces or classes in any combination
+   * <p/>
+   * 1. not checks that myOldSuperClass is really super of aClass
+   * 2. not checks that myNewSuperClass not exists in currently existed supers
+   */
+  private static void changeSuperClass(@NotNull final PsiClass aClass,
+                                       @NotNull final PsiClass oldSuperClass,
+                                       @NotNull final PsiClass newSuperClass) {
+    if (!FileModificationService.getInstance().preparePsiElementForWrite(aClass)) return;
+
+    if (!FileModificationService.getInstance().prepareFileForWrite(aClass.getContainingFile())) return;
+    CommandProcessor.getInstance().executeCommand(newSuperClass.getProject(), new Runnable() {
+      @Override
+      public void run() {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          @Override
+          public void run() {
+            PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
+            if (aClass instanceof PsiAnonymousClass) {
+              ((PsiAnonymousClass)aClass).getBaseClassReference().replace(factory.createClassReferenceElement(newSuperClass));
+            }
+            else if (oldSuperClass.isInterface()) {
+              final PsiReferenceList interfaceList = aClass.getImplementsList();
+              if (interfaceList != null) {
+                for (final PsiJavaCodeReferenceElement interfaceRef : interfaceList.getReferenceElements()) {
+                  final PsiElement aInterface = interfaceRef.resolve();
+                  if (aInterface != null && aInterface.isEquivalentTo(oldSuperClass)) {
+                    interfaceRef.delete();
+                  }
+                }
+              }
+
+              final PsiReferenceList extendsList = aClass.getExtendsList();
+              if (extendsList != null) {
+                final PsiJavaCodeReferenceElement newClassReference = factory.createClassReferenceElement(newSuperClass);
+                if (extendsList.getReferenceElements().length == 0) {
+                  extendsList.add(newClassReference);
+                }
+              }
+            }
+            else {
+              final PsiReferenceList extendsList = aClass.getExtendsList();
+              if (extendsList != null && extendsList.getReferenceElements().length == 1) {
+                extendsList.getReferenceElements()[0].delete();
+                PsiElement ref = extendsList.add(factory.createClassReferenceElement(newSuperClass));
+                JavaCodeStyleManager.getInstance(aClass.getProject()).shortenClassReferences(ref);
+              }
+            }
+          }
+        });
+      }
+    }, "Changing inheritance", null);
+  }
+
+  public static class LowPriority extends ChangeSuperClassFix implements LowPriorityAction {
+    public LowPriority(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
+      super(newSuperClass, percent, oldSuperClass);
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
index aa3dd1e..03f5c4d 100644
--- a/java/java-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/SuperClassHasFrequentlyUsedInheritorsInspection.java
@@ -16,9 +16,9 @@
 /**
  * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
  */
-public class SuperClassHasFrequentlyUsedInheritorsInspection extends BaseJavaLocalInspectionTool {
-  private final static int MIN_PERCENT_RATIO = 5;
-  public final static int MAX_QUICK_FIX_COUNTS = 4;
+public class SuperClassHasFrequentlyUsedInheritorsInspection extends BaseJavaBatchLocalInspectionTool {
+  private static final int MIN_PERCENT_RATIO = 5;
+  public static final int MAX_QUICK_FIX_COUNTS = 4;
 
   @Nls
   @NotNull
@@ -36,7 +36,7 @@
 
   @Override
   public boolean isEnabledByDefault() {
-    return true;
+    return false;
   }
 
   @Nullable
@@ -78,13 +78,13 @@
       }
     }
     return new ProblemDescriptor[]{manager
-      .createProblemDescriptor(aClass, "Class may extend a commonly used base class instead of implementing interface or extending abstract class", false,
+      .createProblemDescriptor(aClass, getDisplayName(), false,
                                topInheritorsQuickFix.toArray(new LocalQuickFix[topInheritorsQuickFix.size()]),
                                ProblemHighlightType.INFORMATION)};
   }
 
   @Nullable
-  private static PsiClass getSuperIfUnique(final @NotNull PsiClass aClass) {
+  private static PsiClass getSuperIfUnique(@NotNull final PsiClass aClass) {
     if (aClass instanceof PsiAnonymousClass) {
       return (PsiClass)((PsiAnonymousClass)aClass).getBaseClassReference().resolve();
     }
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsCountData.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticalDataSearch.java
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java b/java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/inheritance/search/InheritorsStatisticsSearchResult.java
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
index fabc58d..f63b2d8 100644
--- a/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/java15api/Java15APIUsageInspection.java
@@ -19,7 +19,9 @@
 import com.intellij.codeHighlighting.HighlightDisplayLevel;
 import com.intellij.codeInsight.daemon.GroupNames;
 import com.intellij.codeInspection.*;
+import com.intellij.ide.ui.ListCellRendererWrapper;
 import com.intellij.openapi.extensions.ExtensionPoint;
+import com.intellij.openapi.extensions.ExtensionPointName;
 import com.intellij.openapi.extensions.Extensions;
 import com.intellij.openapi.module.EffectiveLanguageLevelUtil;
 import com.intellij.openapi.module.Module;
@@ -34,7 +36,6 @@
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.reference.SoftReference;
-import com.intellij.ide.ui.ListCellRendererWrapper;
 import com.intellij.util.ui.UIUtil;
 import gnu.trove.THashSet;
 import org.jdom.Element;
@@ -232,10 +233,11 @@
     return ourPresentableShortMessage.get(languageLevel);
   }
 
+  public static final ExtensionPointName<FileCheckingInspection> EP_NAME = ExtensionPointName.create(ToolExtensionPoints.JAVA15_INSPECTION_TOOL);
   private class MyVisitor extends JavaElementVisitor {
     private final ProblemsHolder myHolder;
     private final boolean myOnTheFly;
-    private final ExtensionPoint<FileCheckingInspection> point = Extensions.getRootArea().getExtensionPoint(ToolExtensionPoints.JAVA15_INSPECTION_TOOL);
+    private final ExtensionPoint<FileCheckingInspection> point = Extensions.getRootArea().getExtensionPoint(EP_NAME);
 
     public MyVisitor(final ProblemsHolder holder, boolean onTheFly) {
       myHolder = holder;
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
similarity index 89%
rename from java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
index 56cd621..c1dbdbf 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/AnnotateOverriddenMethodParameterFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
 import com.intellij.codeInspection.InspectionsBundle;
 import com.intellij.codeInspection.LocalQuickFix;
 import com.intellij.codeInspection.ProblemDescriptor;
@@ -25,12 +25,13 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiNameValuePair;
 import com.intellij.psi.PsiParameter;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.searches.OverridingMethodsSearch;
 import com.intellij.psi.util.ClassUtil;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.ArrayUtil;
+import com.intellij.util.ArrayUtilRt;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
@@ -65,7 +66,7 @@
     PsiMethod method = PsiTreeUtil.getParentOfType(parameter, PsiMethod.class);
     if (method == null) return;
     PsiParameter[] parameters = method.getParameterList().getParameters();
-    int index = ArrayUtil.find(parameters, parameter);
+    int index = ArrayUtilRt.find(parameters, parameter);
 
     List<PsiParameter> toAnnotate = new ArrayList<PsiParameter>();
 
@@ -84,7 +85,8 @@
       try {
         assert psiParam != null : toAnnotate;
         if (AnnotationUtil.isAnnotatingApplicable(psiParam, myAnnotation)) {
-          new AddAnnotationFix(myAnnotation, psiParam, myAnnosToRemove).invoke(project, null, psiParam.getContainingFile());
+          AddAnnotationPsiFix fix = new AddAnnotationPsiFix(myAnnotation, psiParam, PsiNameValuePair.EMPTY_ARRAY, myAnnosToRemove);
+          fix.invoke(project, psiParam.getContainingFile(), psiParam, psiParam);
         }
       }
       catch (IncorrectOperationException e) {
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
similarity index 98%
rename from java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
index 53b439f..aa3f0d0 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/ChangeNullableDefaultsFix.java
@@ -59,7 +59,8 @@
   public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
     if (myNotNullName != null) {
       myManager.setDefaultNotNull(myNotNullName);
-    } else {
+    }
+    else {
       myManager.setDefaultNullable(myNullableName);
     }
   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
new file mode 100644
index 0000000..8014acd
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspectionBase.java
@@ -0,0 +1,469 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.nullable;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.GroupNames;
+import com.intellij.codeInsight.intention.AddAnnotationPsiFix;
+import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.dataFlow.DfaPsiUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.searches.OverridingMethodsSearch;
+import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.*;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import java.util.List;
+
+public class NullableStuffInspectionBase extends BaseJavaBatchLocalInspectionTool {
+  // deprecated fields remain to minimize changes to users inspection profiles (which are often located in version control).
+  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true;
+  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true;
+  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true;
+  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true;
+  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true;
+  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
+  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
+  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
+
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.nullable.NullableStuffInspectionBase");
+
+  @Override
+  @NotNull
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
+    return new JavaElementVisitor() {
+      @Override public void visitMethod(PsiMethod method) {
+        if (!PsiUtil.isLanguageLevel5OrHigher(method)) return;
+        checkNullableStuffForMethod(method, holder);
+      }
+
+      @Override public void visitField(PsiField field) {
+        if (!PsiUtil.isLanguageLevel5OrHigher(field)) return;
+        final PsiType type = field.getType();
+        final Annotated annotated = check(field, holder, type);
+        if (TypeConversionUtil.isPrimitiveAndNotNull(type)) {
+          return;
+        }
+        Project project = holder.getProject();
+        final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
+        if (annotated.isDeclaredNotNull ^ annotated.isDeclaredNullable) {
+          final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
+          final List<String> annoToRemove = annotated.isDeclaredNotNull ? manager.getNullables() : manager.getNotNulls();
+
+          if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) {
+            final PsiAnnotation notNull = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
+            final PsiAnnotation nullable = AnnotationUtil.findAnnotation(field, manager.getNullables());
+            holder.registerProblem(field.getNameIdentifier(), "Nullable/NotNull defaults are not accessible in current context",
+                                   new ChangeNullableDefaultsFix(notNull, nullable, manager));
+            return;
+          }
+
+          String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD);
+          final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+          final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
+          final String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable());
+          final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull());
+          final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
+          if (nameIdentifier != null && nameIdentifier.isPhysical()) {
+            if (PropertyUtil.isSimpleGetter(getter)) {
+              AnnotateMethodFix getterAnnoFix = new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)) {
+                @Override
+                public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+                  return 1;
+                }
+              };
+              if (REPORT_NOT_ANNOTATED_GETTER) {
+                if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations(), false, false) &&
+                    !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) {
+                  holder.registerProblem(nameIdentifier, InspectionsBundle
+                    .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)),
+                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+                }
+              }
+              if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) {
+                holder.registerProblem(nameIdentifier, InspectionsBundle.message(
+                  "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName),
+                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+              } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) {
+                holder.registerProblem(nameIdentifier, InspectionsBundle.message(
+                  "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
+                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, getterAnnoFix);
+              }
+            }
+          }
+
+          final PsiClass containingClass = field.getContainingClass();
+          final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
+          if (setter != null) {
+            final PsiParameter[] parameters = setter.getParameterList().getParameters();
+            assert parameters.length == 1 : setter.getText();
+            final PsiParameter parameter = parameters[0];
+            LOG.assertTrue(parameter != null, setter.getText());
+            AddAnnotationPsiFix addAnnoFix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove));
+            if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
+              final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+              assertValidElement(setter, parameter, nameIdentifier1);
+              holder.registerProblem(nameIdentifier1,
+                                     InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
+                                                               StringUtil.getShortName(anno)),
+                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                     addAnnoFix);
+            }
+            if (PropertyUtil.isSimpleSetter(setter)) {
+              if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
+                final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+                assertValidElement(setter, parameter, nameIdentifier1);
+                holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
+                                       "inspection.nullable.problems.annotated.field.setter.parameter.conflict",
+                                       StringUtil.getShortName(anno), nullableSimpleName),
+                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                       addAnnoFix);
+              }
+              else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
+                final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
+                assertValidElement(setter, parameter, nameIdentifier1);
+                holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
+                  "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
+                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                       addAnnoFix);
+              }
+            }
+          }
+
+          for (PsiExpression rhs : DfaPsiUtil.findAllConstructorInitializers(field)) {
+            if (rhs instanceof PsiReferenceExpression) {
+              PsiElement target = ((PsiReferenceExpression)rhs).resolve();
+              if (target instanceof PsiParameter) {
+                PsiParameter parameter = (PsiParameter)target;
+                AddAnnotationPsiFix fix = new AddAnnotationPsiFix(anno, parameter, PsiNameValuePair.EMPTY_ARRAY, ArrayUtil.toStringArray(annoToRemove));
+                if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
+                  final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+                  assert nameIdentifier2 != null : parameter;
+                  holder.registerProblem(nameIdentifier2, InspectionsBundle
+                    .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated",
+                             StringUtil.getShortName(anno)),
+                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING, fix);
+                  continue;
+                }
+                if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
+                  final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+                  assert nameIdentifier2 != null : parameter;
+                  holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
+                    "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
+                    nullableSimpleName),
+                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                         fix);
+                }
+                else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
+                  boolean usedAsQualifier = !ReferencesSearch.search(parameter).forEach(new Processor<PsiReference>() {
+                    @Override
+                    public boolean process(PsiReference reference) {
+                      final PsiElement element = reference.getElement();
+                      return !(element instanceof PsiReferenceExpression && element.getParent() instanceof PsiReferenceExpression);
+                    }
+                  });
+                  if (!usedAsQualifier) {
+                    final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
+                    assert nameIdentifier2 != null : parameter;
+                    holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
+                      "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
+                      notNullSimpleName),
+                                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                           fix);
+                  }
+                }
+
+              }
+            }
+          }
+        }
+      }
+
+      private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
+        LOG.assertTrue(nameIdentifier1 != null && nameIdentifier1.isPhysical(), setter.getText());
+        LOG.assertTrue(parameter.isPhysical(), setter.getText());
+      }
+
+      @Override public void visitParameter(PsiParameter parameter) {
+        if (!PsiUtil.isLanguageLevel5OrHigher(parameter)) return;
+        check(parameter, holder, parameter.getType());
+      }
+    };
+  }
+
+  private static class Annotated {
+    private final boolean isDeclaredNotNull;
+    private final boolean isDeclaredNullable;
+
+    private Annotated(final boolean isDeclaredNotNull, final boolean isDeclaredNullable) {
+      this.isDeclaredNotNull = isDeclaredNotNull;
+      this.isDeclaredNullable = isDeclaredNullable;
+    }
+  }
+  private static Annotated check(final PsiModifierListOwner parameter, final ProblemsHolder holder, PsiType type) {
+    final NullableNotNullManager manager = NullableNotNullManager.getInstance(holder.getProject());
+    PsiAnnotation isDeclaredNotNull = AnnotationUtil.findAnnotation(parameter, manager.getNotNulls());
+    PsiAnnotation isDeclaredNullable = AnnotationUtil.findAnnotation(parameter, manager.getNullables());
+    if (isDeclaredNullable != null && isDeclaredNotNull != null) {
+      reportNullableNotNullConflict(holder, parameter, isDeclaredNullable,  isDeclaredNotNull);
+    }
+    if ((isDeclaredNotNull != null || isDeclaredNullable != null) && type != null && TypeConversionUtil.isPrimitive(type.getCanonicalText())) {
+      PsiAnnotation annotation = isDeclaredNotNull == null ? isDeclaredNullable : isDeclaredNotNull;
+      reportPrimitiveType(holder, annotation, annotation, parameter);
+    }
+    return new Annotated(isDeclaredNotNull != null,isDeclaredNullable != null);
+  }
+
+  private static void reportPrimitiveType(final ProblemsHolder holder, final PsiElement psiElement, final PsiAnnotation annotation,
+                                          final PsiModifierListOwner listOwner) {
+    holder.registerProblem(psiElement.isPhysical() ? psiElement : listOwner.getNavigationElement(),
+                           InspectionsBundle.message("inspection.nullable.problems.primitive.type.annotation"),
+                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(annotation, listOwner));
+  }
+
+  @Override
+  @NotNull
+  public String getDisplayName() {
+    return InspectionsBundle.message("inspection.nullable.problems.display.name");
+  }
+
+  @Override
+  @NotNull
+  public String getGroupDisplayName() {
+    return GroupNames.BUGS_GROUP_NAME;
+  }
+
+  @Override
+  @NotNull
+  public String getShortName() {
+    return "NullableProblems";
+  }
+
+  private void checkNullableStuffForMethod(PsiMethod method, final ProblemsHolder holder) {
+    Annotated annotated = check(method, holder, method.getReturnType());
+
+    PsiParameter[] parameters = method.getParameterList().getParameters();
+
+    List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
+    boolean reported_not_annotated_method_overrides_notnull = false;
+    boolean reported_nullable_method_overrides_notnull = false;
+    boolean[] reported_notnull_parameter_overrides_nullable = new boolean[parameters.length];
+    boolean[] reported_not_annotated_parameter_overrides_notnull = new boolean[parameters.length];
+
+    final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(holder.getProject());
+    for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
+      PsiMethod superMethod = superMethodSignature.getMethod();
+      if (!reported_nullable_method_overrides_notnull
+          && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE
+          && annotated.isDeclaredNullable
+          && NullableNotNullManager.isNotNull(superMethod)) {
+        reported_nullable_method_overrides_notnull = true;
+        holder.registerProblem(method.getNameIdentifier(),
+                               InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull"),
+                               ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+      }
+      if (!reported_not_annotated_method_overrides_notnull
+          && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL
+          && !annotated.isDeclaredNullable
+          && !annotated.isDeclaredNotNull
+          && NullableNotNullManager.isNotNull(superMethod)) {
+        reported_not_annotated_method_overrides_notnull = true;
+        final String defaultNotNull = nullableManager.getDefaultNotNull();
+        final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
+        final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull)
+                                  ? createAnnotateMethodFix(defaultNotNull, annotationsToRemove)
+                                  : createChangeDefaultNotNullFix(nullableManager, superMethod);
+        holder.registerProblem(method.getNameIdentifier(),
+                               InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
+                               ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                               wrapFix(fix));
+      }
+      if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
+        PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
+        if (superParameters.length != parameters.length) {
+          continue;
+        }
+        for (int i = 0; i < parameters.length; i++) {
+          PsiParameter parameter = parameters[i];
+          PsiParameter superParameter = superParameters[i];
+          if (!reported_notnull_parameter_overrides_nullable[i] && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE &&
+              nullableManager.isNotNull(parameter, false) &&
+              nullableManager.isNullable(superParameter, false)) {
+            reported_notnull_parameter_overrides_nullable[i] = true;
+            holder.registerProblem(parameter.getNameIdentifier(),
+                                   InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.overrides.Nullable"),
+                                   ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+          }
+          if (!reported_not_annotated_parameter_overrides_notnull[i] && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
+            if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) &&
+                nullableManager.isNotNull(superParameter, false)) {
+              reported_not_annotated_parameter_overrides_notnull[i] = true;
+              final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull())
+                                        ? new AddNotNullAnnotationFix(parameter)
+                                        : createChangeDefaultNotNullFix(nullableManager, superParameter);
+              holder.registerProblem(parameter.getNameIdentifier(),
+                                     InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull"),
+                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                     wrapFix(fix));
+            }
+          }
+        }
+      }
+    }
+
+    if (REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS) {
+      boolean[] parameterAnnotated = new boolean[parameters.length];
+      boolean[] parameterQuickFixSuggested = new boolean[parameters.length];
+      boolean hasAnnotatedParameter = false;
+      for (int i = 0; i < parameters.length; i++) {
+        PsiParameter parameter = parameters[i];
+        parameterAnnotated[i] = nullableManager.isNotNull(parameter, false);
+        hasAnnotatedParameter |= parameterAnnotated[i];
+      }
+      if (hasAnnotatedParameter || annotated.isDeclaredNotNull) {
+        PsiManager manager = method.getManager();
+        final String defaultNotNull = nullableManager.getDefaultNotNull();
+        final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull);
+        PsiMethod[] overridings =
+          OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(manager.getProject()), true).toArray(PsiMethod.EMPTY_ARRAY);
+        boolean methodQuickFixSuggested = false;
+        for (PsiMethod overriding : overridings) {
+          if (!manager.isInProject(overriding)) continue;
+
+          final boolean applicable = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull);
+          if (!methodQuickFixSuggested
+              && annotated.isDeclaredNotNull
+              && !nullableManager.isNotNull(overriding, false)
+              && (nullableManager.isNullable(overriding, false) || !nullableManager.isNullable(overriding, true))) {
+            method.getNameIdentifier(); //load tree
+            PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
+            final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
+
+            final LocalQuickFix fix;
+            if (applicable) {
+              fix = new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove);
+            }
+            else {
+              fix = superMethodApplicable ? null : createChangeDefaultNotNullFix(nullableManager, method);
+            }
+
+            PsiElement psiElement = annotation;
+            if (!annotation.isPhysical()) {
+              psiElement = method.getNameIdentifier();
+              if (psiElement == null) continue;
+            }
+            holder.registerProblem(psiElement, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
+                                   ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                   wrapFix(fix));
+            methodQuickFixSuggested = true;
+          }
+          if (hasAnnotatedParameter) {
+            PsiParameter[] psiParameters = overriding.getParameterList().getParameters();
+            for (int i = 0; i < psiParameters.length; i++) {
+              if (parameterQuickFixSuggested[i]) continue;
+              PsiParameter parameter = psiParameters[i];
+              if (parameterAnnotated[i] && !nullableManager.isNotNull(parameter, false) && !nullableManager.isNullable(parameter, false)) {
+                parameters[i].getNameIdentifier(); //be sure that corresponding tree element available
+                PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameters[i], nullableManager.getNotNulls());
+                PsiElement psiElement = annotation;
+                if (!annotation.isPhysical()) {
+                  psiElement = parameters[i].getNameIdentifier();
+                  if (psiElement == null) continue;
+                }
+                holder.registerProblem(psiElement,
+                                       InspectionsBundle.message("nullable.stuff.problems.overridden.method.parameters.are.not.annotated"),
+                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
+                                       wrapFix(!applicable
+                                               ? createChangeDefaultNotNullFix(nullableManager, parameters[i])
+                                               : new AnnotateOverriddenMethodParameterFix(defaultNotNull,
+                                                                                          nullableManager.getDefaultNullable())));
+                parameterQuickFixSuggested[i] = true;
+              }
+            }
+          }
+        }
+      }
+    }
+  }
+
+  private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
+    if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
+    return new LocalQuickFix[]{fix};
+  }
+
+  private static LocalQuickFix createChangeDefaultNotNullFix(NullableNotNullManager nullableManager, PsiModifierListOwner modifierListOwner) {
+    final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, nullableManager.getNotNulls());
+    if (annotation != null) {
+      final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
+      if (referenceElement != null && referenceElement.resolve() != null) {
+        return new ChangeNullableDefaultsFix(annotation.getQualifiedName(), null, nullableManager);
+      }
+    }
+    return null;
+  }
+
+  protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
+    return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
+  }
+
+  private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable,
+                                                    final PsiAnnotation declaredNotNull) {
+    holder.registerProblem(declaredNotNull.isPhysical() ? declaredNotNull : listOwner.getNavigationElement(),
+                           InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
+                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNotNull, listOwner));
+    holder.registerProblem(declaredNullable.isPhysical() ? declaredNullable : listOwner.getNavigationElement(),
+                           InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
+                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNullable, listOwner));
+  }
+
+  @Override
+  public JComponent createOptionsPanel() {
+    throw new RuntimeException("No UI in headless mode");
+  }
+
+  private static class MyAnnotateMethodFix extends AnnotateMethodFix {
+    public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
+      super(defaultNotNull, annotationsToRemove);
+    }
+
+    @Override
+    protected boolean annotateOverriddenMethods() {
+      return true;
+    }
+
+    @Override
+    public int shouldAnnotateBaseMethod(PsiMethod method, PsiMethod superMethod, Project project) {
+      return 1;
+    }
+
+    @Override
+    @NotNull
+    public String getName() {
+      return InspectionsBundle.message("annotate.overridden.methods.as.notnull", ClassUtil.extractClassName(myAnnotation));
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
similarity index 95%
rename from java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
index bc9c679..3135f48 100644
--- a/java/java-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/sillyAssignment/SillyAssignmentInspection.java
@@ -15,10 +15,7 @@
  */
 package com.intellij.codeInspection.sillyAssignment;
 
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.*;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -31,7 +28,7 @@
  * User: anna
  * Date: 15-Nov-2005
  */
-public class SillyAssignmentInspection extends BaseJavaLocalInspectionTool {
+public class SillyAssignmentInspection extends BaseJavaBatchLocalInspectionTool {
   @Override
   @NotNull
   public String getGroupDisplayName() {
@@ -164,7 +161,8 @@
         }
       }
       return thisQualifier;
-    } else if (qualifier != null) {
+    }
+    if (qualifier != null) {
       return  ((PsiSuperExpression)qualifier).getQualifier();
     }
     return null;
diff --git a/java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java b/java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
similarity index 69%
rename from java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
index 20f1ea6..9f69dda 100644
--- a/java/java-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/testOnly/TestOnlyInspection.java
@@ -17,10 +17,7 @@
 
 import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.TestFrameworks;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemHighlightType;
-import com.intellij.codeInspection.ProblemsHolder;
+import com.intellij.codeInspection.*;
 import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
@@ -28,7 +25,7 @@
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-public class TestOnlyInspection extends BaseJavaLocalInspectionTool {
+public class TestOnlyInspection extends BaseJavaBatchLocalInspectionTool {
   @Override
   @NotNull
   public String getDisplayName() {
@@ -57,7 +54,7 @@
     };
   }
 
-  private void validate(PsiCallExpression e, ProblemsHolder h) {
+  private static void validate(PsiCallExpression e, ProblemsHolder h) {
     if (!isTestOnlyMethodCalled(e)) return;
     if (isInsideTestOnlyMethod(e)) return;
     if (isInsideTestClass(e)) return;
@@ -66,28 +63,27 @@
     reportProblem(e, h);
   }
 
-  private boolean isTestOnlyMethodCalled(PsiCallExpression e) {
+  private static boolean isTestOnlyMethodCalled(PsiCallExpression e) {
     return isAnnotatedAsTestOnly(e.resolveMethod());
   }
 
-  private boolean isInsideTestOnlyMethod(PsiCallExpression e) {
+  private static boolean isInsideTestOnlyMethod(PsiCallExpression e) {
     PsiMethod m = getTopLevelParentOfType(e, PsiMethod.class);
     return isAnnotatedAsTestOnly(m);
   }
 
   private static boolean isAnnotatedAsTestOnly(@Nullable PsiMethod m) {
-    if (m == null) return false;
-    return AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false, false) ||
-           AnnotationUtil.isAnnotated(m, "com.google.common.annotations.VisibleForTesting", false, false);
+    return m != null &&
+           (AnnotationUtil.isAnnotated(m, AnnotationUtil.TEST_ONLY, false, false) ||
+            AnnotationUtil.isAnnotated(m, "com.google.common.annotations.VisibleForTesting", false, false));
   }
 
-  private boolean isInsideTestClass(PsiCallExpression e) {
+  private static boolean isInsideTestClass(PsiCallExpression e) {
     PsiClass c = getTopLevelParentOfType(e, PsiClass.class);
-    if (c == null) return false;
-    return TestFrameworks.getInstance().isTestClass(c);
+    return c != null && TestFrameworks.getInstance().isTestClass(c);
   }
 
-  private <T extends PsiElement> T getTopLevelParentOfType(PsiElement e, Class<T> c) {
+  private static <T extends PsiElement> T getTopLevelParentOfType(PsiElement e, Class<T> c) {
     T parent = PsiTreeUtil.getParentOfType(e, c);
     if (parent == null) return null;
 
@@ -99,14 +95,13 @@
     while (true);
   }
 
-  private boolean isUnderTestSources(PsiCallExpression e) {
+  private static boolean isUnderTestSources(PsiCallExpression e) {
     ProjectRootManager rm = ProjectRootManager.getInstance(e.getProject());
     VirtualFile f = e.getContainingFile().getVirtualFile();
-    if (f == null) return false;
-    return rm.getFileIndex().isInTestSourceContent(f);
+    return f != null && rm.getFileIndex().isInTestSourceContent(f);
   }
 
-  private void reportProblem(PsiCallExpression e, ProblemsHolder h) {
+  private static void reportProblem(PsiCallExpression e, ProblemsHolder h) {
     String message = InspectionsBundle.message("inspection.test.only.problems.test.only.method.call");
     h.registerProblem(e, message, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
   }
diff --git a/java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
similarity index 92%
rename from java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
index 4c56961..61b501c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/unneededThrows/RedundantThrowsDeclaration.java
@@ -18,8 +18,7 @@
 import com.intellij.codeInsight.ExceptionUtil;
 import com.intellij.codeInsight.daemon.GroupNames;
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInspection.*;
 import com.intellij.psi.*;
 import org.jetbrains.annotations.NonNls;
@@ -34,7 +33,7 @@
  * @author anna
  * @since 15-Nov-2005
  */
-public class RedundantThrowsDeclaration extends BaseJavaLocalInspectionTool {
+public class RedundantThrowsDeclaration extends BaseJavaBatchLocalInspectionTool {
   @Override
   @NotNull
   public String getGroupDisplayName() {
@@ -118,9 +117,9 @@
       }
     }
 
-    if (HighlightMethodUtil.isSerializationRelatedMethod(method, containingClass)) return null;
+    if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return null;
 
-    String description = JavaErrorMessages.message("exception.is.never.thrown", HighlightUtil.formatType(exceptionType));
+    String description = JavaErrorMessages.message("exception.is.never.thrown", JavaHighlightUtil.formatType(exceptionType));
     LocalQuickFix quickFixes = new DeleteThrowsFix(method, exceptionType);
     return inspectionManager.createProblemDescriptor(referenceElement, description, quickFixes, ProblemHighlightType.LIKE_UNUSED_SYMBOL, onTheFly);
   }
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java b/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java
new file mode 100644
index 0000000..3b2f747
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/util/ChangeToAppendUtil.java
@@ -0,0 +1,97 @@
+/*
+ * 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.codeInspection.util;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class ChangeToAppendUtil {
+  @Nullable
+  public static PsiExpression buildAppendExpression(PsiExpression appendable, PsiExpression concatenation) {
+    if (concatenation == null) return null;
+    final PsiType type = appendable.getType();
+    if (type == null) return null;
+    final StringBuilder result =
+      buildAppendExpression(concatenation, type.equalsToText("java.lang.Appendable"), new StringBuilder(appendable.getText()));
+    if (result == null) return null;
+    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(appendable.getProject());
+    return factory.createExpressionFromText(result.toString(), appendable);
+  }
+
+  @Nullable
+  public static StringBuilder buildAppendExpression(PsiExpression concatenation, boolean useStringValueOf, @NonNls StringBuilder out)
+    throws IncorrectOperationException {
+    final PsiType type = concatenation.getType();
+    if (type == null) {
+      return null;
+    }
+    if (concatenation instanceof PsiPolyadicExpression && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+      PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)concatenation;
+      final PsiExpression[] operands = polyadicExpression.getOperands();
+      boolean isConstant = true;
+      boolean isString = false;
+      final StringBuilder builder = new StringBuilder();
+      for (PsiExpression operand : operands) {
+        if (isConstant && PsiUtil.isConstantExpression(operand)) {
+          if (builder.length() != 0) {
+            builder.append('+');
+          }
+          final PsiType operandType = operand.getType();
+          if (operandType != null && operandType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
+            isString = true;
+          }
+          builder.append(operand.getText());
+        }
+        else {
+          isConstant = false;
+          if (builder.length() != 0) {
+            append(builder, useStringValueOf && !isString, out);
+            builder.setLength(0);
+          }
+          buildAppendExpression(operand, useStringValueOf, out);
+        }
+      }
+      if (builder.length() != 0) {
+        append(builder, false, out);
+      }
+    }
+    else if (concatenation instanceof PsiParenthesizedExpression) {
+      final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)concatenation;
+      final PsiExpression expression = parenthesizedExpression.getExpression();
+      if (expression != null) {
+        return buildAppendExpression(expression, useStringValueOf, out);
+      }
+    }
+    else {
+      append(concatenation.getText(), useStringValueOf && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING), out);
+    }
+    return out;
+  }
+
+  private static void append(CharSequence text, boolean useStringValueOf, StringBuilder out) {
+    out.append(".append(");
+    if (useStringValueOf) {
+      out.append("String.valueOf(").append(text).append(')');
+    }
+    else {
+      out.append(text);
+    }
+    out.append(')');
+  }
+}
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java
new file mode 100644
index 0000000..ebe8490
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtilBase.java
@@ -0,0 +1,95 @@
+/*
+ * 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.codeInspection.util;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.codeInspection.InspectionProfile;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.profile.codeInspection.InspectionProfileManager;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collections;
+import java.util.List;
+
+public class SpecialAnnotationsUtilBase {
+  public static LocalQuickFix createAddToSpecialAnnotationsListQuickFix(@NotNull final String text,
+                                                                        @NotNull final String family,
+                                                                        @NotNull final List<String> targetList,
+                                                                        @NotNull final String qualifiedName,
+                                                                        final PsiElement context) {
+    return new LocalQuickFix() {
+      @Override
+      @NotNull
+      public String getName() {
+        return text;
+      }
+
+      @Override
+      @NotNull
+      public String getFamilyName() {
+        return family;
+      }
+
+      @Override
+      public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
+        doQuickFixInternal(project, targetList, qualifiedName);
+      }
+    };
+  }
+
+  static void doQuickFixInternal(@NotNull Project project, @NotNull List<String> targetList, @NotNull String qualifiedName) {
+    targetList.add(qualifiedName);
+    Collections.sort(targetList);
+    final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
+    //correct save settings
+
+    //TODO lesya
+    InspectionProfileManager.getInstance().fireProfileChanged(inspectionProfile);
+    /*
+    try {
+      inspectionProfile.save();
+    }
+    catch (IOException e) {
+      Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
+    }
+
+    */
+  }
+
+  public static void createAddToSpecialAnnotationFixes(@NotNull PsiModifierListOwner owner, @NotNull Processor<String> processor) {
+    final PsiModifierList modifierList = owner.getModifierList();
+    if (modifierList != null) {
+      final PsiAnnotation[] psiAnnotations = modifierList.getAnnotations();
+      for (PsiAnnotation psiAnnotation : psiAnnotations) {
+        @NonNls final String name = psiAnnotation.getQualifiedName();
+        if (name == null) continue;
+        if (name.startsWith("java.") || name.startsWith("javax.") ||
+            name.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(name))) continue;
+        if (!processor.process(name)) break;
+      }
+    }
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
rename to java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/AdjustPackageNameFix.java
diff --git a/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
new file mode 100644
index 0000000..8efcc45
--- /dev/null
+++ b/java/java-analysis-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspectionBase.java
@@ -0,0 +1,125 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.wrongPackageStatement;
+
+import com.intellij.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeInsight.daemon.JavaErrorMessages;
+import com.intellij.codeInspection.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiUtilCore;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 14-Nov-2005
+ */
+public class WrongPackageStatementInspectionBase extends BaseJavaBatchLocalInspectionTool {
+  @Override
+  @Nullable
+  public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+    // does not work in tests since CodeInsightTestCase copies file into temporary location
+    if (ApplicationManager.getApplication().isUnitTestMode()) return null;
+    if (file instanceof PsiJavaFile) {
+      if (isInJsp(file)) return null;
+      PsiJavaFile javaFile = (PsiJavaFile)file;
+
+      PsiDirectory directory = javaFile.getContainingDirectory();
+      if (directory == null) return null;
+      PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
+      if (dirPackage == null) return null;
+      PsiPackageStatement packageStatement = javaFile.getPackageStatement();
+
+      // highlight the first class in the file only
+      PsiClass[] classes = javaFile.getClasses();
+      if (classes.length == 0 && packageStatement == null) return null;
+
+      String packageName = dirPackage.getQualifiedName();
+      if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
+        String description = JavaErrorMessages.message("missing.package.statement", packageName);
+
+        return new ProblemDescriptor[]{manager.createProblemDescriptor(classes[0].getNameIdentifier(), description,
+                                                                       new AdjustPackageNameFix(packageName),
+                                                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)};
+      }
+      if (packageStatement != null) {
+        final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference();
+        PsiPackage classPackage = (PsiPackage)packageReference.resolve();
+        List<LocalQuickFix> availableFixes = new ArrayList<LocalQuickFix>();
+        if (classPackage == null || !Comparing.equal(dirPackage.getQualifiedName(), packageReference.getQualifiedName(), true)) {
+          availableFixes.add(new AdjustPackageNameFix(packageName));
+          String packName = classPackage != null ? classPackage.getQualifiedName() : packageReference.getQualifiedName();
+          addMoveToPackageFix(file, packName, availableFixes);
+        }
+        if (!availableFixes.isEmpty()){
+          String description = JavaErrorMessages.message("package.name.file.path.mismatch",
+                                                         packageReference.getQualifiedName(),
+                                                         dirPackage.getQualifiedName());
+          LocalQuickFix[] fixes = availableFixes.toArray(new LocalQuickFix[availableFixes.size()]);
+          ProblemDescriptor descriptor =
+            manager.createProblemDescriptor(packageStatement.getPackageReference(), description, isOnTheFly,
+                                            fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
+          return new ProblemDescriptor[]{descriptor};
+
+        }
+      }
+    }
+    return null;
+  }
+
+  private static boolean isInJsp(PsiFile file) {
+    return PsiUtilCore.getTemplateLanguageFile(file) instanceof ServerPageFile;
+  }
+
+  protected void addMoveToPackageFix(PsiFile file, String packName, List<LocalQuickFix> availableFixes) {
+  }
+
+  @Override
+  @NotNull
+  public String getGroupDisplayName() {
+    return "";
+  }
+
+  @Override
+  @NotNull
+  public HighlightDisplayLevel getDefaultLevel() {
+    return HighlightDisplayLevel.ERROR;
+  }
+
+  @Override
+  @NotNull
+  public String getDisplayName() {
+    return InspectionsBundle.message("wrong.package.statement");
+  }
+
+  @Override
+  @NotNull
+  @NonNls
+  public String getShortName() {
+    return "WrongPackageStatement";
+  }
+
+  @Override
+  public boolean isEnabledByDefault() {
+    return true;
+  }
+}
diff --git a/java/java-impl/java-impl.iml b/java/java-impl/java-impl.iml
index b305503..b7b5d03 100644
--- a/java/java-impl/java-impl.iml
+++ b/java/java-impl/java-impl.iml
@@ -33,6 +33,7 @@
     <orderEntry type="module" module-name="java-indexing-api" />
     <orderEntry type="module" module-name="jps-model-impl" />
     <orderEntry type="module" module-name="java-analysis-impl" exported="" />
+    <orderEntry type="module" module-name="external-system-api" />
   </component>
   <component name="copyright">
     <Base>
diff --git a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
index 50f48cb..0cb53dd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/CodeInsightUtil.java
@@ -30,7 +30,6 @@
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.psi.*;
-import com.intellij.psi.impl.source.PsiDiamondTypeElementImpl;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.searches.ClassInheritorsSearch;
 import com.intellij.psi.tree.IElementType;
@@ -81,7 +80,7 @@
   }
 
   public static <T extends PsiElement> T findElementInRange(PsiFile file, int startOffset, int endOffset, Class<T> klass) {
-    return CodeInsightUtilBase.findElementInRange(file, startOffset, endOffset, klass, StdLanguages.JAVA);
+    return CodeInsightUtilCore.findElementInRange(file, startOffset, endOffset, klass, StdLanguages.JAVA);
   }
 
   @NotNull
@@ -203,7 +202,7 @@
     PsiElement[] children = scope.getChildren();
     for (PsiElement child : children) {
       if (child instanceof PsiExpression) {
-        if (areExpressionsEquivalent(RefactoringUtil.unparenthesizeExpression((PsiExpression)child), expr)) {
+        if (JavaPsiEquivalenceUtil.areExpressionsEquivalent(RefactoringUtil.unparenthesizeExpression((PsiExpression)child), expr)) {
           array.add((PsiExpression)child);
           continue;
         }
@@ -233,30 +232,6 @@
     }
   }
 
-  public static boolean areExpressionsEquivalent(PsiExpression expr1, PsiExpression expr2) {
-    return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() {
-      @Override
-      public int compare(PsiElement o1, PsiElement o2) {
-        if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) {
-          return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName());
-        }
-        return 1;
-      }
-    }, new Comparator<PsiElement>() {
-        @Override
-        public int compare(PsiElement o1, PsiElement o2) {
-          if (!o1.textMatches(o2)) return 1;
-
-          if (o1 instanceof PsiDiamondTypeElementImpl && o2 instanceof PsiDiamondTypeElementImpl) {
-            final PsiDiamondType.DiamondInferenceResult thisInferenceResult = new PsiDiamondTypeImpl(o1.getManager(), (PsiTypeElement)o1).resolveInferredTypes();
-            final PsiDiamondType.DiamondInferenceResult otherInferenceResult = new PsiDiamondTypeImpl(o2.getManager(), (PsiTypeElement)o2).resolveInferredTypes();
-            return thisInferenceResult.equals(otherInferenceResult) ? 0 : 1;
-          }
-          return 0;
-        }
-      }, null, false);
-  }
-
   public static Editor positionCursor(final Project project, PsiFile targetFile, PsiElement element) {
     TextRange range = element.getTextRange();
     int textOffset = range.getStartOffset();
diff --git a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
index a4306bb..c4c156c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/ExternalAnnotationsManagerImpl.java
@@ -18,6 +18,7 @@
 import com.intellij.CommonBundle;
 import com.intellij.ProjectTopics;
 import com.intellij.codeInsight.highlighting.HighlightManager;
+import com.intellij.diagnostic.LogMessageEx;
 import com.intellij.icons.AllIcons;
 import com.intellij.ide.DataManager;
 import com.intellij.ide.highlighter.XmlFileType;
@@ -126,6 +127,7 @@
                                  @NotNull final String annotationFQName,
                                  @NotNull final PsiFile fromFile,
                                  @Nullable final PsiNameValuePair[] value) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
     final Project project = myPsiManager.getProject();
     final PsiFile containingFile = listOwner.getContainingFile();
     if (!(containingFile instanceof PsiJavaFile)) {
@@ -336,6 +338,7 @@
 
   @Override
   public boolean deannotate(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
     return processExistingExternalAnnotations(listOwner, annotationFQN, new Processor<XmlTag>() {
       @Override
       public boolean process(XmlTag annotationTag) {
@@ -355,6 +358,7 @@
   public boolean editExternalAnnotation(@NotNull PsiModifierListOwner listOwner,
                                         @NotNull final String annotationFQN,
                                         @Nullable final PsiNameValuePair[] value) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
     return processExistingExternalAnnotations(listOwner, annotationFQN, new Processor<XmlTag>() {
       @Override
       public boolean process(XmlTag annotationTag) {
@@ -365,7 +369,8 @@
     });
   }
 
-  private boolean processExistingExternalAnnotations(@NotNull final PsiModifierListOwner listOwner, @NotNull final String annotationFQN,
+  private boolean processExistingExternalAnnotations(@NotNull final PsiModifierListOwner listOwner,
+                                                     @NotNull final String annotationFQN,
                                                      @NotNull final Processor<XmlTag> annotationTagProcessor) {
     try {
       final List<XmlFile> files = findExternalAnnotationsXmlFiles(listOwner);
@@ -428,6 +433,7 @@
   @Override
   @NotNull
   public AnnotationPlace chooseAnnotationsPlace(@NotNull final PsiElement element) {
+    ApplicationManager.getApplication().assertIsDispatchThread();
     if (!element.isPhysical()) return AnnotationPlace.IN_CODE; //element just created
     if (!element.getManager().isInProject(element)) return AnnotationPlace.EXTERNAL;
     final Project project = myPsiManager.getProject();
@@ -634,6 +640,12 @@
     return null;
   }
 
+  @Override
+  protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) {
+    String message = text + "; for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl();
+    LogMessageEx.error(LOG, message, file.getText());
+  }
+
   private static class MyExternalPromptDialog extends OptionsMessageDialog {
     private final Project myProject;
     private static final String ADD_IN_CODE = ProjectBundle.message("external.annotations.in.code.option");
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
index 6343a29..ac8297d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/AllClassesGetter.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.completion;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
@@ -89,7 +89,7 @@
             context.setTailOffset(psiReference.getRangeInElement().getEndOffset() + psiReference.getElement().getTextRange().getStartOffset());
             final PsiElement newUnderlying = psiReference.bindToElement(psiClass);
             if (newUnderlying != null) {
-              final PsiElement psiElement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newUnderlying);
+              final PsiElement psiElement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newUnderlying);
               if (psiElement != null) {
                 for (final PsiReference reference : psiElement.getReferences()) {
                   if (psiManager.areElementsEquivalent(psiClass, JavaCompletionUtil.resolveReference(reference))) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java b/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java
deleted file mode 100644
index 5496bb1..0000000
--- a/java/java-impl/src/com/intellij/codeInsight/completion/ClassByNameMerger.java
+++ /dev/null
@@ -1,62 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInsight.completion;
-
-import com.intellij.codeInsight.CodeInsightSettings;
-import com.intellij.codeInsight.lookup.LookupElement;
-import com.intellij.codeInsight.lookup.LookupElementBuilder;
-import com.intellij.util.Consumer;
-
-/**
-* @author peter
-*/
-public class ClassByNameMerger implements Consumer<LookupElement> {
-  private int number = 0;
-  private LookupElement lastElement;
-  private final boolean myShouldMerge;
-  private final CompletionResultSet myResult;
-
-  public ClassByNameMerger(CompletionParameters parameters, CompletionResultSet result) {
-    myShouldMerge = parameters.getInvocationCount() == 0 && CodeInsightSettings.getInstance().SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS;
-    myResult = result;
-  }
-
-  @Override
-  public void consume(LookupElement element) {
-    if (!myShouldMerge) {
-      myResult.addElement(element);
-      return;
-    }
-
-    if (lastElement != null) {
-      if (lastElement.getLookupString().equals(element.getLookupString())) {
-        number++;
-        lastElement = LookupElementBuilder.create(element.getLookupString()).withTailText(" (" + number + " variants...)", true);
-        return;
-      }
-
-      myResult.addElement(lastElement);
-    }
-    lastElement = element;
-    number = 1;
-  }
-
-  public void finishedClassProcessing() {
-    if (lastElement != null) {
-      myResult.addElement(lastElement);
-    }
-  }
-}
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
index 4480f31..b98ad7a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionContributor.java
@@ -15,7 +15,6 @@
  */
 package com.intellij.codeInsight.completion;
 
-import com.intellij.codeInsight.CodeInsightSettings;
 import com.intellij.codeInsight.TailType;
 import com.intellij.codeInsight.completion.scope.JavaCompletionProcessor;
 import com.intellij.codeInsight.daemon.impl.quickfix.ImportClassFix;
@@ -415,13 +414,7 @@
   }
 
   public static boolean mayStartClassName(CompletionResultSet result) {
-    String prefix = result.getPrefixMatcher().getPrefix();
-    if (StringUtil.isEmpty(prefix)) {
-      return false;
-    }
-
-    return StringUtil.isCapitalized(prefix) ||
-           CodeInsightSettings.getInstance().COMPLETION_CASE_SENSITIVE == CodeInsightSettings.NONE;
+    return StringUtil.isNotEmpty(result.getPrefixMatcher().getPrefix());
   }
 
   private static void completeAnnotationAttributeName(CompletionResultSet result, PsiElement insertedElement,
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
index e2050a4..163b2c6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaCompletionUtil.java
@@ -677,7 +677,7 @@
           documentManager.doPostponedOperationsAndUnblockDocument(document);
           documentManager.commitDocument(document);
 
-          newElement = CodeInsightUtilBase.findElementInRange(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
+          newElement = CodeInsightUtilCore.findElementInRange(file, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(),
                                                               PsiJavaCodeReferenceElement.class,
                                                               JavaLanguage.INSTANCE);
           rangeMarker.dispose();
@@ -764,12 +764,14 @@
       context.setAddCompletionChar(false);
     }
 
-    final boolean needRightParenth = forceClosingParenthesis || !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET || hasTail);
     if (hasTail) {
       hasParams = false;
     }
+    final boolean needRightParenth = forceClosingParenthesis ||
+                                     !smart && (CodeInsightSettings.getInstance().AUTOINSERT_PAIR_BRACKET ||
+                                                !hasParams && completionChar != '(');
 
-    PsiDocumentManager.getInstance(context.getProject()).commitDocument(context.getDocument());
+    context.commitDocument();
 
     final CommonCodeStyleSettings styleSettings = context.getCodeStyleSettings();
     final PsiElement elementAt = file.findElementAt(context.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
index 6e95a4c..cbfde63 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/JavaNoVariantsDelegator.java
@@ -16,9 +16,11 @@
 package com.intellij.codeInsight.completion;
 
 import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.completion.impl.BetterPrefixMatcher;
 import com.intellij.codeInsight.completion.impl.CamelHumpMatcher;
 import com.intellij.codeInsight.lookup.AutoCompletionPolicy;
 import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.openapi.util.registry.Registry;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.filters.ElementFilter;
@@ -39,9 +41,9 @@
 public class JavaNoVariantsDelegator extends CompletionContributor {
 
   @Override
-  public void fillCompletionVariants(final CompletionParameters parameters, final CompletionResultSet result) {
-    final boolean empty = containsOnlyPackages(result.runRemainingContributors(parameters, true)) ||
-                          suggestMetaAnnotations(parameters);
+  public void fillCompletionVariants(final CompletionParameters parameters, CompletionResultSet result) {
+    LinkedHashSet<CompletionResult> plainResults = result.runRemainingContributors(parameters, true);
+    final boolean empty = containsOnlyPackages(plainResults) || suggestMetaAnnotations(parameters);
 
     if (!empty && parameters.getInvocationCount() == 0) {
       result.restartCompletionWhenNothingMatches();
@@ -49,6 +51,15 @@
 
     if (empty) {
       delegate(parameters, JavaCompletionSorting.addJavaSorting(parameters, result));
+    } else if (Registry.is("ide.completion.show.all.classes") || Registry.is("ide.completion.show.better.matching.classes")) {
+      if (parameters.getInvocationCount() <= 1 &&
+          JavaCompletionContributor.mayStartClassName(result) &&
+          JavaCompletionContributor.isClassNamePossible(parameters)) {
+        if (Registry.is("ide.completion.show.better.matching.classes")) {
+          result = result.withPrefixMatcher(new BetterPrefixMatcher(result.getPrefixMatcher(), BetterPrefixMatcher.getBestMatchingDegree(plainResults))); 
+        }
+        suggestNonImportedClasses(parameters, result);
+      }
     }
   }
 
@@ -158,9 +169,8 @@
     return allClasses;
   }
 
-  private static void suggestNonImportedClasses(CompletionParameters parameters, CompletionResultSet result) {
-    final ClassByNameMerger merger = new ClassByNameMerger(parameters, result);
-
+  private static void suggestNonImportedClasses(CompletionParameters parameters, final CompletionResultSet _result) {
+    final CompletionResultSet result = JavaCompletionSorting.addJavaSorting(parameters, _result);
     JavaClassNameCompletionContributor.addAllClasses(parameters,
                                                      true, result.getPrefixMatcher(), new Consumer<LookupElement>() {
       @Override
@@ -170,10 +180,8 @@
           classElement.setAutoCompletionPolicy(AutoCompletionPolicy.NEVER_AUTOCOMPLETE);
         }
 
-        merger.consume(classElement);
+        result.addElement(element);
       }
     });
-
-    merger.finishedClassProcessing();
   }
 }
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
index 79a8b04..6d03085 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/RecursionWeigher.java
@@ -15,8 +15,8 @@
  */
 package com.intellij.codeInsight.completion;
 
-import com.intellij.codeInsight.CodeInsightUtil;
 import com.intellij.codeInsight.ExpectedTypeInfo;
+import com.intellij.codeInsight.JavaPsiEquivalenceUtil;
 import com.intellij.codeInsight.lookup.LookupElement;
 import com.intellij.codeInsight.lookup.LookupElementWeigher;
 import com.intellij.openapi.util.Comparing;
@@ -79,7 +79,7 @@
     if (myCallQualifier != null &&
         myPositionQualifier != null &&
         myCallQualifier != myPositionQualifier &&
-        CodeInsightUtil.areExpressionsEquivalent(myCallQualifier, myPositionQualifier)) {
+        JavaPsiEquivalenceUtil.areExpressionsEquivalent(myCallQualifier, myPositionQualifier)) {
       return false;
     }
 
@@ -162,7 +162,7 @@
     return Result.normal;
   }
 
-  @Nullable 
+  @Nullable
   private String getSetterPropertyName(@Nullable PsiMethod calledMethod) {
     if (PropertyUtil.isSimplePropertySetter(calledMethod)) {
       assert calledMethod != null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
index 5e44202..ae1ae20 100644
--- a/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/completion/scope/JavaCompletionProcessor.java
@@ -226,10 +226,10 @@
     if (myOptions.showInstanceInStaticContext && !isQualifiedContext()) {
       return true;
     }
-    if (!(element instanceof PsiClass) && element instanceof PsiModifierListOwner) {
+    if (element instanceof PsiModifierListOwner) {
       PsiModifierListOwner modifierListOwner = (PsiModifierListOwner)element;
       if (myStatic) {
-        if (!modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
+        if (!(element instanceof PsiClass) && !modifierListOwner.hasModifierProperty(PsiModifier.STATIC)) {
           // we don't need non static method in static context.
           return false;
         }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
index 875d600..b647e7d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/JavaLineMarkerProvider.java
@@ -31,7 +31,6 @@
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.DumbService;
-import com.intellij.openapi.project.IndexNotReadyException;
 import com.intellij.openapi.util.Pair;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
@@ -68,15 +67,10 @@
   @Nullable
   public LineMarkerInfo getLineMarkerInfo(@NotNull final PsiElement element) {
     PsiElement parent;
-    if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod) {
+    if (element instanceof PsiIdentifier && (parent = element.getParent()) instanceof PsiMethod && 
+        !DumbService.getInstance(element.getProject()).isDumb()) {
       PsiMethod method = (PsiMethod)parent;
-      MethodSignatureBackedByPsiMethod superSignature = null;
-      try {
-        superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst();
-      }
-      catch (IndexNotReadyException e) {
-        //some searchers (EJB) require indices. What shall we do?
-      }
+      MethodSignatureBackedByPsiMethod superSignature = SuperMethodsSearch.search(method, null, true, false).findFirst();
       if (superSignature != null) {
         boolean overrides =
           method.hasModifierProperty(PsiModifier.ABSTRACT) == superSignature.getMethod().hasModifierProperty(PsiModifier.ABSTRACT);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
index 1c21876..a36521f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/PostHighlightingPass.java
@@ -22,10 +22,7 @@
 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
 import com.intellij.codeInsight.daemon.ImplicitUsageProvider;
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightLevelUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMethodUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.*;
 import com.intellij.codeInsight.daemon.impl.quickfix.*;
 import com.intellij.codeInsight.intention.EmptyIntentionAction;
 import com.intellij.codeInsight.intention.IntentionAction;
@@ -38,7 +35,7 @@
 import com.intellij.codeInspection.unusedImport.UnusedImportLocalInspection;
 import com.intellij.codeInspection.unusedParameters.UnusedParametersInspection;
 import com.intellij.codeInspection.unusedSymbol.UnusedSymbolLocalInspection;
-import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
+import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
 import com.intellij.diagnostic.LogMessageEx;
 import com.intellij.diagnostic.errordialog.Attachment;
 import com.intellij.find.FindManager;
@@ -442,7 +439,7 @@
 
         QuickFixAction.registerQuickFixAction(info, new CreateGetterOrSetterFix(false, true, field), myUnusedSymbolKey);
         QuickFixAction.registerQuickFixAction(info, HighlightMethodUtil.getFixRange(field), new CreateConstructorParameterFromFieldFix(field));
-        SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(field, new Processor<String>() {
+        SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(field, new Processor<String>() {
           @Override
           public boolean process(final String annoName) {
             QuickFixAction.registerQuickFixAction(info, UnusedSymbolLocalInspection.createQuickFix(annoName, "fields", field.getProject()));
@@ -497,7 +494,7 @@
            myUnusedSymbolInspection.REPORT_PARAMETER_FOR_PUBLIC_METHODS &&
            !isOverriddenOrOverrides(method)) &&
           !method.hasModifierProperty(PsiModifier.NATIVE) &&
-          !HighlightMethodUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
+          !JavaHighlightUtil.isSerializationRelatedMethod(method, method.getContainingClass()) &&
           !PsiClassImplUtil.isMainOrPremainMethod(method)) {
         if (UnusedSymbolLocalInspection.isInjected(method)) return null;
         HighlightInfo highlightInfo = checkUnusedParameter(parameter, identifier, progress);
@@ -559,10 +556,11 @@
     String message = JavaErrorMessages.message(key, symbolName);
     final HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, highlightInfoType);
     QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(method), highlightDisplayKey);
-    SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(method, new Processor<String>() {
+    SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(method, new Processor<String>() {
       @Override
       public boolean process(final String annoName) {
-        QuickFixAction.registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, "methods", method.getProject()));
+        QuickFixAction
+          .registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, "methods", method.getProject()));
         return true;
       }
     });
@@ -581,7 +579,7 @@
 
     boolean aPrivate = method.hasModifierProperty(PsiModifier.PRIVATE);
     PsiClass containingClass = method.getContainingClass();
-    if (HighlightMethodUtil.isSerializationRelatedMethod(method, containingClass)) return true;
+    if (JavaHighlightUtil.isSerializationRelatedMethod(method, containingClass)) return true;
     if (aPrivate) {
       if (isIntentionalPrivateConstructor(method, containingClass)) {
         return true;
@@ -727,10 +725,11 @@
     String message = JavaErrorMessages.message(pattern, symbolName);
     final HighlightInfo highlightInfo = createUnusedSymbolInfo(identifier, message, highlightInfoType);
     QuickFixAction.registerQuickFixAction(highlightInfo, new SafeDeleteFix(aClass), highlightDisplayKey);
-    SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes((PsiModifierListOwner)aClass, new Processor<String>() {
+    SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes((PsiModifierListOwner)aClass, new Processor<String>() {
       @Override
       public boolean process(final String annoName) {
-        QuickFixAction.registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, element, aClass.getProject()));
+        QuickFixAction
+          .registerQuickFixAction(highlightInfo, UnusedSymbolLocalInspection.createQuickFix(annoName, element, aClass.getProject()));
         return true;
       }
     });
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
index 8b66dce..0fd2685 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RecursiveCallLineMarkerProvider.java
@@ -21,7 +21,7 @@
 import com.intellij.icons.AllIcons;
 import com.intellij.openapi.actionSystem.AnAction;
 import com.intellij.openapi.editor.markup.GutterIconRenderer;
-import com.intellij.openapi.project.DumbAware;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -36,7 +36,7 @@
 /**
  * @author Danila Ponomarenko
  */
-public class RecursiveCallLineMarkerProvider implements LineMarkerProvider, DumbAware {
+public class RecursiveCallLineMarkerProvider implements LineMarkerProvider {
 
   @Override
   public LineMarkerInfo getLineMarkerInfo(@NotNull PsiElement element) {
@@ -49,6 +49,7 @@
     final Set<PsiStatement> statements = new HashSet<PsiStatement>();
 
     for (PsiElement element : elements) {
+      ProgressManager.checkCanceled();
       if (element instanceof PsiMethodCallExpression) {
         final PsiMethodCallExpression methodCall = (PsiMethodCallExpression)element;
         final PsiStatement statement = PsiTreeUtil.getParentOfType(methodCall, PsiStatement.class, true, PsiMethod.class);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
index f0ac84d..6fd6ba5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/RefCountHolder.java
@@ -38,6 +38,7 @@
 import java.util.Iterator;
 import java.util.List;
 import java.util.Map;
+import java.util.concurrent.atomic.AtomicInteger;
 import java.util.concurrent.atomic.AtomicReference;
 
 public class RefCountHolder {
@@ -56,19 +57,26 @@
   private static class HolderReference extends SoftReference<RefCountHolder> {
     @SuppressWarnings("UnusedDeclaration")
     private volatile RefCountHolder myHardRef; // to prevent gc
+    // number of live references to RefCountHolder. Once it reaches zero, hard ref is cleared
+    // the counter is used instead of a flag because multiple passes can be running simultaneously (one actual and several canceled winding down)
+    // and there is a chance they overlap the usage of RCH
+    private final AtomicInteger myRefCount = new AtomicInteger();
 
     public HolderReference(@NotNull RefCountHolder holder) {
       super(holder);
       myHardRef = holder;
     }
-    
-    private void makeHardReachable(boolean isHard) {
-      RefCountHolder holder = get();
-      assert !isHard || holder != null : "hard: "+isHard +"; holder="+holder;
-      myHardRef = isHard ? holder : null;
+
+    private void changeLivenessBy(int delta) {
+      if (myRefCount.addAndGet(delta) == 0) {
+        myHardRef = null;
+      }
+      else if (myHardRef == null) {
+        myHardRef = get();
+      }
     }
   }
-  
+
   private static final Key<HolderReference> REF_COUNT_HOLDER_IN_FILE_KEY = Key.create("REF_COUNT_HOLDER_IN_FILE_KEY");
   @NotNull
   private static Pair<RefCountHolder, HolderReference> getInstance(@NotNull PsiFile file, boolean create) {
@@ -98,7 +106,7 @@
   public static RefCountHolder startUsing(@NotNull PsiFile file) {
     Pair<RefCountHolder, HolderReference> pair = getInstance(file, true);
     HolderReference reference = pair.second;
-    reference.makeHardReachable(true); // make sure RefCountHolder won't be gced during highlighting
+    reference.changeLivenessBy(1); // make sure RefCountHolder won't be gced during highlighting
     log("startUsing: " + pair.first.myState+" for "+file);
     return pair.first;
   }
@@ -107,12 +115,12 @@
   public static RefCountHolder endUsing(@NotNull PsiFile file) {
     Pair<RefCountHolder, HolderReference> pair = getInstance(file, false);
     HolderReference reference = pair.second;
-    reference.makeHardReachable(false); // no longer needed, can be cleared
+    reference.changeLivenessBy(-1); // no longer needed, can be cleared
     RefCountHolder holder = pair.first;
     log("endUsing: " + (holder == null ? null : holder.myState)+" for "+file);
     return holder;
   }
-  
+
   private RefCountHolder(@NotNull PsiFile file) {
     myFile = file;
     log("c: created: " + myState.get()+" for "+file);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
index 8346db9..6849d74 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/AnnotationsHighlightUtil.java
@@ -133,12 +133,12 @@
       }
 
       String description = JavaErrorMessages.message("annotation.incompatible.types",
-                                                     formatReference(nameRef), HighlightUtil.formatType(expectedType));
+                                                     formatReference(nameRef), JavaHighlightUtil.formatType(expectedType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
     }
     if (value instanceof PsiArrayInitializerMemberValue) {
       if (expectedType instanceof PsiArrayType) return null;
-      String description = JavaErrorMessages.message("annotation.illegal.array.initializer", HighlightUtil.formatType(expectedType));
+      String description = JavaErrorMessages.message("annotation.illegal.array.initializer", JavaHighlightUtil.formatType(expectedType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
     }
     if (value instanceof PsiExpression) {
@@ -151,7 +151,7 @@
       }
 
       String description = JavaErrorMessages.message("annotation.incompatible.types",
-                                                     HighlightUtil.formatType(type), HighlightUtil.formatType(expectedType));
+                                                     JavaHighlightUtil.formatType(type), JavaHighlightUtil.formatType(expectedType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(value).descriptionAndTooltip(description).create();
     }
 
@@ -483,7 +483,7 @@
           final String qualifiedName = containingClass.getQualifiedName();
           if (CommonClassNames.JAVA_LANG_OBJECT.equals(qualifiedName) || CommonClassNames.JAVA_LANG_ANNOTATION_ANNOTATION.equals(qualifiedName)) {
             return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(nameIdentifier).descriptionAndTooltip(
-              "@interface member clashes with '" + HighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)).create();
+              "@interface member clashes with '" + JavaHighlightUtil.formatMethod(method) + "' in " + HighlightUtil.formatClass(containingClass)).create();
           }
         }
       }
@@ -599,7 +599,8 @@
     if (methods.length == 1) {
       PsiType expected = new PsiImmediateClassType((PsiClass)target, PsiSubstitutor.EMPTY).createArrayType();
       if (!expected.equals(methods[0].getReturnType())) {
-        return JavaErrorMessages.message("annotation.container.bad.type", container.getQualifiedName(), HighlightUtil.formatType(expected));
+        return JavaErrorMessages.message("annotation.container.bad.type", container.getQualifiedName(), JavaHighlightUtil
+          .formatType(expected));
       }
     }
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
index 000a035..5ee1703 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/GenericsHighlightUtil.java
@@ -15,7 +15,6 @@
  */
 package com.intellij.codeInsight.daemon.impl.analysis;
 
-import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
 import com.intellij.codeInsight.daemon.impl.HighlightInfoType;
@@ -41,7 +40,6 @@
 import com.intellij.util.containers.HashSet;
 import gnu.trove.THashMap;
 import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.*;
@@ -96,8 +94,8 @@
           String description = JavaErrorMessages.message(
             messageKey,
             HighlightUtil.formatClass(typeParameter),
-            HighlightUtil.formatType(extendsType),
-            HighlightUtil.formatType(substituted)
+            JavaHighlightUtil.formatType(extendsType),
+            JavaHighlightUtil.formatType(substituted)
           );
 
           return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(call).descriptionAndTooltip(description).create();
@@ -273,7 +271,7 @@
 
         String description = JavaErrorMessages.message(messageKey,
                                                        referenceClass != null ? HighlightUtil.formatClass(referenceClass) : type.getPresentableText(),
-                                                       HighlightUtil.formatType(bound));
+                                                       JavaHighlightUtil.formatType(bound));
 
         final HighlightInfo highlightInfo =
           HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement2Highlight).descriptionAndTooltip(description).create();
@@ -363,7 +361,7 @@
       return HighlightUtil.formatClass((PsiClass)typeParameterListOwner);
     }
     else if (typeParameterListOwner instanceof PsiMethod) {
-      return HighlightUtil.formatMethod((PsiMethod)typeParameterListOwner);
+      return JavaHighlightUtil.formatMethod((PsiMethod)typeParameterListOwner);
     }
     else {
       LOG.error("Unknown " + typeParameterListOwner);
@@ -447,8 +445,8 @@
           if (!Comparing.equal(type1, type2)) {
             String description = JavaErrorMessages.message("generics.cannot.be.inherited.with.different.type.arguments",
                                                            HighlightUtil.formatClass(superClass),
-                                                           HighlightUtil.formatType(type1),
-                                                           HighlightUtil.formatType(type2));
+                                                           JavaHighlightUtil.formatType(type1),
+                                                           JavaHighlightUtil.formatType(type2));
             return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
           }
         }
@@ -499,7 +497,7 @@
               .isInheritorOrSelf(containingClass, superContainingClass, true)) {
               if (superMethod.hasModifierProperty(PsiModifier.DEFAULT)) {
                 final String inheritUnrelatedDefaultsMessage = HighlightUtil.formatClass(aClass) + " inherits unrelated defaults for " +
-                                                               HighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) +
+                                                               JavaHighlightUtil.formatMethod(method) + " from types " + HighlightUtil.formatClass(containingClass) +
                                                                " and " + HighlightUtil.formatClass(superContainingClass);
                 return HighlightInfo
                   .newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(inheritUnrelatedDefaultsMessage).create();
@@ -508,7 +506,7 @@
                 final String message = JavaErrorMessages.message(
                   aClass instanceof PsiEnumConstantInitializer ? "enum.constant.should.implement.method" : "class.must.be.abstract",
                   HighlightUtil.formatClass(superContainingClass),
-                  HighlightUtil.formatMethod(superMethod),
+                  JavaHighlightUtil.formatMethod(superMethod),
                   HighlightUtil.formatClass(superContainingClass, false));
                 return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(classIdentifier).descriptionAndTooltip(message).create();
               }
@@ -532,9 +530,9 @@
     MethodSignatureBackedByPsiMethod sameErasure = sameErasureMethods.get(signatureToErase);
     HighlightInfo info;
     if (sameErasure != null) {
-      if (aClass instanceof PsiTypeParameter || 
+      if (aClass instanceof PsiTypeParameter ||
           MethodSignatureUtil.findMethodBySuperMethod(aClass, sameErasure.getMethod(), false) != null ||
-          !(InheritanceUtil.isInheritorOrSelf(sameErasure.getMethod().getContainingClass(), method.getContainingClass(), true) || 
+          !(InheritanceUtil.isInheritorOrSelf(sameErasure.getMethod().getContainingClass(), method.getContainingClass(), true) ||
             InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), sameErasure.getMethod().getContainingClass(), true))) {
         info = checkSameErasureNotSubSignatureOrSameClass(sameErasure, signature, aClass, method);
         if (info != null) return info;
@@ -659,7 +657,7 @@
         if (refParent instanceof PsiNewExpression) {
           PsiNewExpression newExpression = (PsiNewExpression)refParent;
           if (!(newExpression.getType() instanceof PsiArrayType)) {
-            String description = JavaErrorMessages.message("wildcard.type.cannot.be.instantiated", HighlightUtil.formatType(type));
+            String description = JavaErrorMessages.message("wildcard.type.cannot.be.instantiated", JavaHighlightUtil.formatType(type));
             return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
           }
         }
@@ -700,7 +698,7 @@
       if (toConvert instanceof PsiPrimitiveType) {
         final PsiClassType boxedType = ((PsiPrimitiveType)toConvert).getBoxedType(typeElement);
         if (boxedType != null) {
-          QuickFixAction.registerQuickFixAction(highlightInfo, 
+          QuickFixAction.registerQuickFixAction(highlightInfo,
                                                 new ReplacePrimitiveWithBoxedTypeAction(typeElement, toConvert.getPresentableText(), ((PsiPrimitiveType)toConvert).getBoxedTypeName()));
         }
       }
@@ -710,132 +708,15 @@
     return null;
   }
 
-  public static boolean isRawToGeneric(PsiType lType, PsiType rType) {
-    if (lType instanceof PsiPrimitiveType || rType instanceof PsiPrimitiveType) return false;
-    if (lType.equals(rType)) return false;
-    if (lType instanceof PsiArrayType && rType instanceof PsiArrayType) {
-      return isRawToGeneric(((PsiArrayType)lType).getComponentType(), ((PsiArrayType)rType).getComponentType());
-    }
-    if (lType instanceof PsiArrayType || rType instanceof PsiArrayType) return false;
-
-    if (rType instanceof PsiIntersectionType) {
-      for (PsiType type : ((PsiIntersectionType)rType).getConjuncts()) {
-        if (isRawToGeneric(lType, type)) return true;
-      }
-      return false;
-    }
-    if (lType instanceof PsiIntersectionType) {
-      for (PsiType type : ((PsiIntersectionType)lType).getConjuncts()) {
-        if (isRawToGeneric(type, rType)) return true;
-      }
-      return false;
-    }
-
-    if (!(lType instanceof PsiClassType) || !(rType instanceof PsiClassType)) return false;
-
-    PsiClassType.ClassResolveResult lResolveResult = ((PsiClassType)lType).resolveGenerics();
-    PsiClassType.ClassResolveResult rResolveResult = ((PsiClassType)rType).resolveGenerics();
-    PsiClass lClass = lResolveResult.getElement();
-    PsiClass rClass = rResolveResult.getElement();
-
-    if (rClass instanceof PsiAnonymousClass) {
-      return isRawToGeneric(lType, ((PsiAnonymousClass)rClass).getBaseClassType());
-    }
-
-    PsiSubstitutor lSubstitutor = lResolveResult.getSubstitutor();
-    PsiSubstitutor rSubstitutor = rResolveResult.getSubstitutor();
-    if (lClass == null || rClass == null) return false;
-    if (lClass instanceof PsiTypeParameter &&
-        !InheritanceUtil.isInheritorOrSelf(rClass, lClass, true)) {
-      return true;
-    }
-
-    if (!lClass.getManager().areElementsEquivalent(lClass, rClass)) {
-      if (lClass.isInheritor(rClass, true)) {
-        lSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(rClass, lClass, lSubstitutor);
-        lClass = rClass;
-      }
-      else if (rClass.isInheritor(lClass, true)) {
-        rSubstitutor = TypeConversionUtil.getSuperClassSubstitutor(lClass, rClass, rSubstitutor);
-        rClass = lClass;
-      }
-      else {
-        return false;
-      }
-    }
-
-    Iterator<PsiTypeParameter> lIterator = PsiUtil.typeParametersIterator(lClass);
-    Iterator<PsiTypeParameter> rIterator = PsiUtil.typeParametersIterator(rClass);
-    while (lIterator.hasNext()) {
-      if (!rIterator.hasNext()) return false;
-      PsiTypeParameter lParameter = lIterator.next();
-      PsiTypeParameter rParameter = rIterator.next();
-      PsiType lTypeArg = lSubstitutor.substitute(lParameter);
-      PsiType rTypeArg = rSubstitutor.substituteWithBoundsPromotion(rParameter);
-      if (lTypeArg == null) continue;
-      if (rTypeArg == null) {
-        if (lTypeArg instanceof PsiWildcardType && ((PsiWildcardType)lTypeArg).getBound() == null) {
-          continue;
-        }
-        else {
-          return true;
-        }
-      }
-      if (!TypeConversionUtil.typesAgree(lTypeArg, rTypeArg, true)) return true;
-    }
-    return false;
-  }
-
-  public static boolean isUncheckedCast(PsiType castType, PsiType operandType) {
-    if (TypeConversionUtil.isAssignable(castType, operandType, false)) return false;
-
-    castType = castType.getDeepComponentType();
-    if (castType instanceof PsiClassType) {
-      final PsiClassType castClassType = (PsiClassType)castType;
-      operandType = operandType.getDeepComponentType();
-
-      if (!(operandType instanceof PsiClassType)) return false;
-      final PsiClassType operandClassType = (PsiClassType)operandType;
-      final PsiClassType.ClassResolveResult castResult = castClassType.resolveGenerics();
-      final PsiClassType.ClassResolveResult operandResult = operandClassType.resolveGenerics();
-      final PsiClass operandClass = operandResult.getElement();
-      final PsiClass castClass = castResult.getElement();
-
-      if (operandClass == null || castClass == null) return false;
-      if (castClass instanceof PsiTypeParameter) return true;
-
-      if (castClassType.hasNonTrivialParameters()) {
-        if (operandClassType.isRaw()) return true;
-        if (castClass.isInheritor(operandClass, true)) {
-          PsiSubstitutor castSubstitutor = castResult.getSubstitutor();
-          PsiElementFactory factory = JavaPsiFacade.getInstance(castClass.getProject()).getElementFactory();
-          for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(castClass)) {
-            PsiSubstitutor modifiedSubstitutor = castSubstitutor.put(typeParameter, null);
-            PsiClassType otherType = factory.createType(castClass, modifiedSubstitutor);
-            if (TypeConversionUtil.isAssignable(operandType, otherType, false)) return true;
-          }
-          for (PsiTypeParameter typeParameter : PsiUtil.typeParametersIterable(operandClass)) {
-            final PsiType operand = operandResult.getSubstitutor().substitute(typeParameter);
-            if (operand instanceof PsiCapturedWildcardType) return true;
-          }
-          return false;
-        }
-        return true;
-      }
-    }
-
-    return false;
-  }
-
   @Nullable
   public static HighlightInfo checkForeachLoopParameterType(PsiForeachStatement statement) {
     final PsiParameter parameter = statement.getIterationParameter();
     final PsiExpression expression = statement.getIteratedValue();
     if (expression == null || expression.getType() == null) return null;
-    final PsiType itemType = getCollectionItemType(expression);
+    final PsiType itemType = JavaGenericsUtil.getCollectionItemType(expression);
     if (itemType == null) {
       String description = JavaErrorMessages.message("foreach.not.applicable",
-                                                     HighlightUtil.formatType(expression.getType()));
+                                                     JavaHighlightUtil.formatType(expression.getType()));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(description).create();
     }
     final int start = parameter.getTextRange().getStartOffset();
@@ -848,61 +729,6 @@
     return highlightInfo;
   }
 
-  @Nullable
-  public static PsiType getCollectionItemType(@NotNull PsiExpression expression) {
-    final PsiType type = expression.getType();
-    if (type == null) return null;
-    return getCollectionItemType(type, expression.getResolveScope());
-  }
-
-  @Nullable
-  public static PsiType getCollectionItemType(final PsiType type, final GlobalSearchScope scope) {
-    if (type instanceof PsiArrayType) {
-      return ((PsiArrayType)type).getComponentType();
-    }
-    if (type instanceof PsiClassType) {
-      final PsiClassType.ClassResolveResult resolveResult = ((PsiClassType)type).resolveGenerics();
-      PsiClass aClass = resolveResult.getElement();
-      if (aClass == null) return null;
-      final PsiManager manager = aClass.getManager();
-      final String qName = aClass.getQualifiedName();
-      PsiSubstitutor substitutor = resolveResult.getSubstitutor();
-      JavaPsiFacade facade = JavaPsiFacade.getInstance(manager.getProject());
-      if (qName != null) {
-        PsiClass myClass = facade.findClass(qName, scope);
-        if (myClass != null && myClass != aClass) {
-          //different JDKs
-          PsiTypeParameter thisTypeParameter = getIterableTypeParameter(facade, myClass);
-          if (thisTypeParameter == null) return null;
-          PsiTypeParameter thatTypeParameter = getIterableTypeParameter(facade, aClass);
-          if (thatTypeParameter != null) { //it can be null if we reference collection in JDK1.4 module from JDK5 source
-            substitutor = substitutor.put(thisTypeParameter, substitutor.substitute(thatTypeParameter));
-          }
-          aClass = myClass;
-        }
-      }
-      PsiTypeParameter typeParameter = getIterableTypeParameter(facade, aClass);
-      if (typeParameter == null) return null;
-      PsiClass owner = (PsiClass)typeParameter.getOwner();
-      if (owner == null) return null;
-      PsiSubstitutor superClassSubstitutor = TypeConversionUtil.getClassSubstitutor(owner, aClass, PsiSubstitutor.EMPTY);
-      if (superClassSubstitutor == null) return null;
-      PsiType itemType = superClassSubstitutor.substitute(typeParameter);
-      itemType = substitutor.substitute(itemType);
-      return itemType == null ? PsiType.getJavaLangObject(manager, aClass.getResolveScope()) : itemType;
-    }
-    return null;
-  }
-
-  @Nullable
-  private static PsiTypeParameter getIterableTypeParameter(final JavaPsiFacade facade, final PsiClass context) {
-    PsiClass iterable = facade.findClass("java.lang.Iterable", context.getResolveScope());
-    if (iterable == null) return null;
-    PsiTypeParameter[] typeParameters = iterable.getTypeParameters();
-    if (typeParameters.length != 1) return null;
-    return typeParameters[0];
-  }
-
   //http://docs.oracle.com/javase/specs/jls/se7/html/jls-8.html#jls-8.9.2
   @Nullable
   public static HighlightInfo checkAccessStaticFieldFromEnumConstructor(PsiReferenceExpression expr, JavaResolveResult result) {
@@ -952,7 +778,7 @@
   @Nullable
   public static HighlightInfo checkGenericArrayCreation(PsiElement element, PsiType type) {
     if (type instanceof PsiArrayType) {
-      if (!isReifiableType(((PsiArrayType)type).getComponentType())) {
+      if (!JavaGenericsUtil.isReifiableType(((PsiArrayType)type).getComponentType())) {
         String description = JavaErrorMessages.message("generic.array.creation");
         return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(element).descriptionAndTooltip(description).create();
       }
@@ -1058,10 +884,10 @@
 
     if (resolved instanceof PsiClass) {
       final PsiClass containingClass = ((PsiClass)resolved).getContainingClass();
-      if (containingClass != null && 
-          ref.getQualifier() == null && 
-          containingClass.getTypeParameters().length > 0 && 
-          !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC) && 
+      if (containingClass != null &&
+          ref.getQualifier() == null &&
+          containingClass.getTypeParameters().length > 0 &&
+          !((PsiClass)resolved).hasModifierProperty(PsiModifier.STATIC) &&
           ((PsiClass)resolved).getTypeParameters().length == 0) {
         String description = JavaErrorMessages.message("illegal.generic.type.for.instanceof");
         return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
@@ -1180,7 +1006,7 @@
       LOG.assertTrue(varParameter.isVarArgs());
       final PsiEllipsisType ellipsisType = (PsiEllipsisType)varParameter.getType();
       final PsiType componentType = ellipsisType.getComponentType();
-      if (isReifiableType(componentType)) {
+      if (JavaGenericsUtil.isReifiableType(componentType)) {
         PsiElement element = varParameter.getTypeElement();
         return HighlightInfo.newHighlightInfo(HighlightInfoType.WARNING).range(element).descriptionAndTooltip(
           "@SafeVarargs is not applicable for reifiable types").create();
@@ -1192,102 +1018,6 @@
     }
   }
 
-  public static boolean isUncheckedWarning(PsiJavaCodeReferenceElement expression, JavaResolveResult resolveResult) {
-    final PsiElement resolve = resolveResult.getElement();
-    if (resolve instanceof PsiMethod) {
-      final PsiMethod psiMethod = (PsiMethod)resolve;
-
-      final LanguageLevel languageLevel = PsiUtil.getLanguageLevel(expression);
-
-      if (psiMethod.isVarArgs()) {
-        if (!languageLevel.isAtLeast(LanguageLevel.JDK_1_7) || !AnnotationUtil.isAnnotated(psiMethod, "java.lang.SafeVarargs", false)) {
-          final int parametersCount = psiMethod.getParameterList().getParametersCount();
-          final PsiParameter varargParameter =
-            psiMethod.getParameterList().getParameters()[parametersCount - 1];
-          final PsiType componentType = ((PsiEllipsisType)varargParameter.getType()).getComponentType();
-          if (!isReifiableType(resolveResult.getSubstitutor().substitute(componentType))) {
-            final PsiElement parent = expression.getParent();
-            if (parent instanceof PsiCall) {
-              final PsiExpressionList argumentList = ((PsiCall)parent).getArgumentList();
-              if (argumentList != null) {
-                final PsiExpression[] args = argumentList.getExpressions();
-                if (args.length == parametersCount) {
-                  final PsiExpression lastArg = args[args.length - 1];
-                  if (lastArg instanceof PsiReferenceExpression) {
-                    final PsiElement lastArgsResolve = ((PsiReferenceExpression)lastArg).resolve();
-                    if (lastArgsResolve instanceof PsiParameter) {
-                      if (((PsiParameter)lastArgsResolve).getType() instanceof PsiArrayType) {
-                        return false;
-                      }
-                    }
-                  }
-                  else if (lastArg instanceof PsiMethodCallExpression) {
-                    if (lastArg.getType() instanceof PsiArrayType) {
-                      return false;
-                    }
-                  }
-                }
-                for (int i = parametersCount - 1; i < args.length; i++) {
-                  if (!isReifiableType(resolveResult.getSubstitutor().substitute(args[i].getType()))) {
-                    return true;
-                  }
-                }
-                return args.length < parametersCount;
-              }
-            }
-          }
-        }
-      }
-    }
-    return false;
-  }
-
-  public static boolean isReifiableType(PsiType type) {
-    if (type instanceof PsiArrayType) {
-      return isReifiableType(((PsiArrayType)type).getComponentType());
-    }
-
-    if (type instanceof PsiPrimitiveType) {
-      return true;
-    }
-
-    if (PsiUtil.resolveClassInType(type) instanceof PsiTypeParameter) {
-      return false;
-    }
-
-    if (type instanceof PsiClassType) {
-      final PsiClassType classType = (PsiClassType)PsiUtil.convertAnonymousToBaseType(type);
-      if (classType.isRaw()) {
-        return true;
-      }
-      PsiType[] parameters = classType.getParameters();
-
-      for (PsiType parameter : parameters) {
-        if (parameter instanceof PsiWildcardType && ((PsiWildcardType)parameter).getBound() == null) {
-          return true;
-        }
-      }
-      final PsiClass resolved = ((PsiClassType)PsiUtil.convertAnonymousToBaseType(classType)).resolve();
-      if (resolved instanceof PsiTypeParameter) {
-        return false;
-      }
-      if (parameters.length == 0) {
-        if (resolved != null && !resolved.hasModifierProperty(PsiModifier.STATIC)) {
-          final PsiClass containingClass = resolved.getContainingClass();
-          if (containingClass != null) {
-            final PsiTypeParameter[] containingClassTypeParameters = containingClass.getTypeParameters();
-            if (containingClassTypeParameters.length > 0) {
-              return false;
-            }
-          }
-        }
-        return true;
-      }
-    }
-
-    return false;
-  }
-
   static void checkEnumConstantForConstructorProblems(PsiEnumConstant enumConstant, final HighlightInfoHolder holder) {
     PsiClass containingClass = enumConstant.getContainingClass();
     if (enumConstant.getInitializingClass() == null) {
@@ -1407,7 +1137,7 @@
         if ((parent instanceof PsiCallExpression || parent instanceof PsiMethodReferenceExpression) && PsiUtil.isLanguageLevel7OrHigher(parent)) {
           return null;
         }
-        
+
         if (element instanceof PsiMethod) {
           if (((PsiMethod)element).findSuperMethods().length > 0) return null;
           if (qualifier instanceof PsiReferenceExpression){
@@ -1520,8 +1250,8 @@
       if (qualifier instanceof PsiJavaCodeReferenceElement) {
         if (((PsiJavaCodeReferenceElement)qualifier).getTypeParameters().length > 0) {
           final PsiElement resolve = ((PsiJavaCodeReferenceElement)parent).resolve();
-          if (resolve instanceof PsiTypeParameterListOwner 
-              && ((PsiTypeParameterListOwner)resolve).hasTypeParameters() 
+          if (resolve instanceof PsiTypeParameterListOwner
+              && ((PsiTypeParameterListOwner)resolve).hasTypeParameters()
               && !((PsiTypeParameterListOwner)resolve).hasModifierProperty(PsiModifier.STATIC)) {
             return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parent).descriptionAndTooltip(
               "Improper formed type; some type parameters are missing").create();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
index 62a59b0..40e1f57 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightClassUtil.java
@@ -98,7 +98,7 @@
       return null;
     }
     String baseClassName = HighlightUtil.formatClass(aClass, false);
-    String methodName = HighlightUtil.formatMethod(abstractMethod);
+    String methodName = JavaHighlightUtil.formatMethod(abstractMethod);
     String message = JavaErrorMessages.message(aClass instanceof PsiEnumConstantInitializer || implementsFixElement instanceof PsiEnumConstant ? "enum.constant.should.implement.method" : "class.must.be.abstract",
                                                baseClassName,
                                                methodName,
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
index 1f5e33a..80f4b17 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMethodUtil.java
@@ -23,6 +23,7 @@
 import com.intellij.codeInsight.daemon.impl.quickfix.*;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInsight.intention.QuickFixFactory;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.IndexNotReadyException;
 import com.intellij.openapi.util.Comparing;
@@ -60,8 +61,8 @@
   public static String createClashMethodMessage(PsiMethod method1, PsiMethod method2, boolean showContainingClasses) {
     @NonNls String pattern = showContainingClasses ? "clash.methods.message.show.classes" : "clash.methods.message";
     return JavaErrorMessages.message(pattern,
-                                     HighlightUtil.formatMethod(method1),
-                                     HighlightUtil.formatMethod(method2),
+                                     JavaHighlightUtil.formatMethod(method1),
+                                     JavaHighlightUtil.formatMethod(method2),
                                      HighlightUtil.formatClass(method1.getContainingClass()),
                                      HighlightUtil.formatClass(method2.getContainingClass()));
   }
@@ -212,8 +213,8 @@
     // strange things happen when super method is from Object and method from interface
     if (superMethod.hasModifierProperty(PsiModifier.FINAL)) {
       String description = JavaErrorMessages.message("final.method.override",
-                                                 HighlightUtil.formatMethod(method),
-                                                 HighlightUtil.formatMethod(superMethod),
+                                                 JavaHighlightUtil.formatMethod(method),
+                                                 JavaHighlightUtil.formatMethod(superMethod),
                                                  HighlightUtil.formatClass(superMethod.getContainingClass()));
       TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
       HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -265,7 +266,7 @@
         PsiClassType exception = checkedExceptions.get(index);
         String description = JavaErrorMessages.message("overridden.method.does.not.throw",
                                                    createClashMethodMessage(method, superMethod, true),
-                                                   HighlightUtil.formatType(exception));
+                                                   JavaHighlightUtil.formatType(exception));
         TextRange textRange;
         if (includeRealPositionInfo) {
           PsiElement exceptionContext = exceptionContexts.get(index);
@@ -275,8 +276,8 @@
           textRange = TextRange.EMPTY_RANGE;
         }
         HighlightInfo errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
-        QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, false, false));
-        QuickFixAction.registerQuickFixAction(errorResult, QUICK_FIX_FACTORY.createMethodThrowsFix(superMethod, exception, true, true));
+        QuickFixAction.registerQuickFixAction(errorResult, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, false, false)));
+        QuickFixAction.registerQuickFixAction(errorResult, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(superMethod, exception, true, true)));
         return errorResult;
       }
     }
@@ -325,6 +326,9 @@
     if (resolved instanceof PsiMethod && resolveResult.isValidResult()) {
       TextRange fixRange = getFixRange(methodCall);
       highlightInfo = HighlightUtil.checkUnhandledExceptions(methodCall, fixRange);
+      if (highlightInfo == null && !LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)resolved, methodCall.getMethodExpression())) {
+        highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).descriptionAndTooltip("Static method may be invoked on containing interface class only").range(fixRange).create();
+      }
     }
     else {
       PsiMethod resolvedMethod = null;
@@ -683,7 +687,7 @@
       if (parameter != null) {
         PsiType type = substitutor.substitute(parameter.getType());
         s +=  "<font " + (mismatchColor == null ? "" : "color=" + mismatchColor) + ">" +
-              esctrim(showShort ? type.getPresentableText() : HighlightUtil.formatType(type))
+              esctrim(showShort ? type.getPresentableText() : JavaHighlightUtil.formatType(type))
               + "</font>"
               ;
       }
@@ -694,7 +698,7 @@
         PsiType type = expression.getType();
         s += "<font " + (mismatchColor == null ? "" : "color='" + mismatchColor + "'") + ">" +
                esctrim(expression.getText()) + "&nbsp;&nbsp;"+
-              (mismatchColor == null || type == null || type == PsiType.NULL ? "" : "("+esctrim(HighlightUtil.formatType(type))+")")
+              (mismatchColor == null || type == null || type == PsiType.NULL ? "" : "("+esctrim(JavaHighlightUtil.formatType(type))+")")
               + "</font>"
               ;
 
@@ -722,7 +726,7 @@
       @NonNls String mismatchColor = showShort ? null : UIUtil.isUnderDarcula() ? "ff6464" : "red";
       ms += "<td> " + "<b><nobr>" + (i == 0 ? "(" : "")
             + "<font " + (showShort ? "" : "color=" + mismatchColor) + ">" +
-            XmlStringUtil.escapeString(showShort ? type.getPresentableText() : HighlightUtil.formatType(type))
+            XmlStringUtil.escapeString(showShort ? type.getPresentableText() : JavaHighlightUtil.formatType(type))
             + "</font>"
             + (i == expressions.length - 1 ? ")" : ",") + "</nobr></b></td>";
     }
@@ -744,7 +748,7 @@
       ms += "<td><b><nobr>" + (i == 0 ? "(" : "") +
             XmlStringUtil.escapeString(showShortType(i, parameters, expressions, substitutor)
                                  ? type.getPresentableText()
-                                 : HighlightUtil.formatType(type))
+                                 : JavaHighlightUtil.formatType(type))
             + (i == parameters.length - 1 ? ")" : ",") + "</nobr></b></td>";
     }
     return ms;
@@ -849,7 +853,7 @@
     }
     if (methodCount > 1) {
       String description = JavaErrorMessages.message("duplicate.method",
-                                                 HighlightUtil.formatMethod(method),
+                                                 JavaHighlightUtil.formatMethod(method),
                                                  HighlightUtil.formatClass(aClass));
       TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -939,7 +943,7 @@
       PsiMethodCallExpression methodCallExpression = (PsiMethodCallExpression)expr.getParent().getParent();
       PsiMethod method = methodCallExpression.resolveMethod();
       if (method != null && method.hasModifierProperty(PsiModifier.ABSTRACT)) {
-        String message = JavaErrorMessages.message("direct.abstract.method.access", HighlightUtil.formatMethod(method));
+        String message = JavaErrorMessages.message("direct.abstract.method.access", JavaHighlightUtil.formatMethod(method));
         return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(methodCallExpression).descriptionAndTooltip(message).create();
       }
     }
@@ -1028,9 +1032,9 @@
                                 : "instance.method.cannot.override.static.method";
 
       String description = JavaErrorMessages.message(messageKey,
-                                                 HighlightUtil.formatMethod(method),
+                                                 JavaHighlightUtil.formatMethod(method),
                                                  HighlightUtil.formatClass(aClass),
-                                                 HighlightUtil.formatMethod(superMethod),
+                                                 JavaHighlightUtil.formatMethod(superMethod),
                                                  HighlightUtil.formatClass(superClass));
 
       HighlightInfo info = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
@@ -1128,9 +1132,9 @@
           PsiMethod superMethod = superSignature.getMethod();
           if (!superMethod.hasModifierProperty(PsiModifier.STATIC)) {
             description = JavaErrorMessages.message("static.method.cannot.override.instance.method",
-                                                         HighlightUtil.formatMethod(method),
+                                                         JavaHighlightUtil.formatMethod(method),
                                                          HighlightUtil.formatClass(containingClass),
-                                                         HighlightUtil.formatMethod(superMethod),
+                                                         JavaHighlightUtil.formatMethod(superMethod),
                                                          HighlightUtil.formatClass(superMethod.getContainingClass()));
             break Ultimate;
           }
@@ -1177,7 +1181,7 @@
     TextRange textRange = HighlightNamesUtil.getMethodDeclarationTextRange(method);
     HighlightInfo highlightInfo = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).descriptionAndTooltip(description).create();
     for (PsiClassType exception : unhandled) {
-      QuickFixAction.registerQuickFixAction(highlightInfo, QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, true, false));
+      QuickFixAction.registerQuickFixAction(highlightInfo, new LocalQuickFixOnPsiElementAsIntentionAdapter(QUICK_FIX_FACTORY.createMethodThrowsFix(method, exception, true, false)));
     }
     return highlightInfo;
   }
@@ -1380,43 +1384,6 @@
     }
   }
 
-  public static boolean isSerializationRelatedMethod(PsiMethod method, PsiClass containingClass) {
-    if (containingClass == null || method.isConstructor()) return false;
-    if (method.hasModifierProperty(PsiModifier.STATIC)) return false;
-    @NonNls String name = method.getName();
-    PsiParameter[] parameters = method.getParameterList().getParameters();
-    PsiType returnType = method.getReturnType();
-    if ("readObjectNoData".equals(name)) {
-      return parameters.length == 0 && TypeConversionUtil.isVoidType(returnType) && HighlightUtil.isSerializable(containingClass);
-    }
-    if ("readObject".equals(name)) {
-      return parameters.length == 1
-             && parameters[0].getType().equalsToText("java.io.ObjectInputStream")
-             && TypeConversionUtil.isVoidType(returnType) && method.hasModifierProperty(PsiModifier.PRIVATE)
-             && HighlightUtil.isSerializable(containingClass);
-    }
-    if ("readResolve".equals(name)) {
-      return parameters.length == 0
-             && returnType != null
-             && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
-             && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || HighlightUtil.isSerializable(containingClass));
-    }
-    if ("writeReplace".equals(name)) {
-      return parameters.length == 0
-             && returnType != null
-             && returnType.equalsToText(CommonClassNames.JAVA_LANG_OBJECT)
-             && (containingClass.hasModifierProperty(PsiModifier.ABSTRACT) || HighlightUtil.isSerializable(containingClass));
-    }
-    if ("writeObject".equals(name)) {
-      return parameters.length == 1
-             && TypeConversionUtil.isVoidType(returnType)
-             && parameters[0].getType().equalsToText("java.io.ObjectOutputStream")
-             && method.hasModifierProperty(PsiModifier.PRIVATE)
-             && HighlightUtil.isSerializable(containingClass);
-    }
-    return false;
-  }
-
   private static String buildArgTypesList(PsiExpressionList list) {
     StringBuilder builder = new StringBuilder();
     builder.append("(");
@@ -1426,7 +1393,7 @@
         builder.append(", ");
       }
       PsiType argType = args[i].getType();
-      builder.append(argType != null ? HighlightUtil.formatType(argType) : "?");
+      builder.append(argType != null ? JavaHighlightUtil.formatType(argType) : "?");
     }
     builder.append(")");
     return builder.toString();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
index eb75a70..5354932 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightUtil.java
@@ -26,6 +26,7 @@
 import com.intellij.codeInsight.intention.QuickFixFactory;
 import com.intellij.codeInsight.quickfix.ChangeVariableTypeQuickFixProvider;
 import com.intellij.codeInsight.quickfix.UnresolvedReferenceQuickFixProvider;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElementAsIntentionAdapter;
 import com.intellij.lang.findUsages.LanguageFindUsages;
 import com.intellij.lang.java.JavaLanguage;
 import com.intellij.openapi.diagnostic.Logger;
@@ -280,7 +281,8 @@
     if (TypeConversionUtil.isPrimitiveAndNotNull(operandType)
         || TypeConversionUtil.isPrimitiveAndNotNull(checkType)
         || !TypeConversionUtil.areTypesConvertible(operandType, checkType)) {
-      String message = JavaErrorMessages.message("inconvertible.type.cast", formatType(operandType), formatType(checkType));
+      String message = JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+        .formatType(checkType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
     }
     return null;
@@ -300,7 +302,8 @@
     if (operandType != null &&
         !TypeConversionUtil.areTypesConvertible(operandType, castType) &&
         !RedundantCastUtil.isInPolymorphicCall(expression)) {
-      String message = JavaErrorMessages.message("inconvertible.type.cast", formatType(operandType), formatType(castType));
+      String message = JavaErrorMessages.message("inconvertible.type.cast", JavaHighlightUtil.formatType(operandType), JavaHighlightUtil
+        .formatType(castType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
     }
 
@@ -347,8 +350,8 @@
         PsiType.getJavaLangObject(assignment.getManager(), assignment.getResolveScope()).equals(lType)) {
       String operatorText = operationSign.getText().substring(0, operationSign.getText().length() - 1);
       String message = JavaErrorMessages.message("binary.operator.not.applicable", operatorText,
-                                                 formatType(lType),
-                                                 formatType(rType));
+                                                 JavaHighlightUtil.formatType(lType),
+                                                 JavaHighlightUtil.formatType(rType));
 
       errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(assignment).descriptionAndTooltip(message).create();
       QuickFixAction.registerQuickFixAction(errorResult, new ChangeToAppendFix(eqOpSign, lType, assignment));
@@ -547,7 +550,7 @@
       @NotNull
       @Override
       public String fun(PsiClassType type) {
-        return formatType(type);
+        return JavaHighlightUtil.formatType(type);
       }
     }, ", ");
   }
@@ -630,24 +633,10 @@
   }
 
   @NotNull
-  public static String formatMethod(@NotNull PsiMethod method) {
-    return PsiFormatUtil.formatMethod(method, PsiSubstitutor.EMPTY, PsiFormatUtilBase.SHOW_NAME | PsiFormatUtilBase.SHOW_PARAMETERS,
-                                      PsiFormatUtilBase.SHOW_TYPE);
-  }
-
-  @NotNull
   public static String formatField(@NotNull PsiField field) {
     return PsiFormatUtil.formatVariable(field, PsiFormatUtilBase.SHOW_CONTAINING_CLASS | PsiFormatUtilBase.SHOW_NAME, PsiSubstitutor.EMPTY);
   }
 
-  @NotNull
-  public static String formatType(@Nullable PsiType type) {
-    if (type == null) return PsiKeyword.NULL;
-    String text = type.getInternalCanonicalText();
-    return text == null ? PsiKeyword.NULL : text;
-  }
-
-
   @Nullable
   public static HighlightInfo checkUnhandledExceptions(@NotNull final PsiElement element, @Nullable TextRange textRange) {
     final List<PsiClassType> unhandledExceptions = ExceptionUtil.getUnhandledExceptions(element);
@@ -1148,7 +1137,7 @@
       if (exceptionType.isAssignableFrom(caughtType) || caughtType.isAssignableFrom(exceptionType)) return null;
     }
 
-    final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(caughtType));
+    final String description = JavaErrorMessages.message("exception.never.thrown.try", JavaHighlightUtil.formatType(caughtType));
     final HighlightInfo errorResult =
       HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(parameter).descriptionAndTooltip(description).create();
     QuickFixAction.registerQuickFixAction(errorResult, new DeleteCatchFix(parameter));
@@ -1173,7 +1162,7 @@
         }
       }
       if (!used) {
-        final String description = JavaErrorMessages.message("exception.never.thrown.try", formatType(catchType));
+        final String description = JavaErrorMessages.message("exception.never.thrown.try", JavaHighlightUtil.formatType(catchType));
         final HighlightInfo highlight =
           HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(typeElement).descriptionAndTooltip(description).create();
         QuickFixAction.registerQuickFixAction(highlight, new DeleteMultiCatchFix(typeElement));
@@ -1267,7 +1256,8 @@
     if (type != null) {
       if (!isValidTypeForSwitchSelector(type, PsiUtil.isLanguageLevel7OrHigher(expression))) {
         String message =
-          JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), formatType(type));
+          JavaErrorMessages.message("incompatible.types", JavaErrorMessages.message("valid.switch.selector.types"), JavaHighlightUtil
+            .formatType(type));
         errorResult = HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
         QuickFixAction.registerQuickFixAction(errorResult, new ConvertSwitchToIfIntention(statement));
         if (PsiType.LONG.equals(type) || PsiType.FLOAT.equals(type) || PsiType.DOUBLE.equals(type)) {
@@ -1312,8 +1302,8 @@
       if (!TypeConversionUtil.isBinaryOperatorApplicable(operationSign, lType, rType, false)) {
         PsiJavaToken token = expression.getTokenBeforeOperand(operand);
         String message = JavaErrorMessages.message("binary.operator.not.applicable", token.getText(),
-                                                   formatType(lType),
-                                                   formatType(rType));
+                                                   JavaHighlightUtil.formatType(lType),
+                                                   JavaHighlightUtil.formatType(rType));
         return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(expression).descriptionAndTooltip(message).create();
       }
       lType = TypeConversionUtil.calcTypeForBinaryExpression(lType, rType, operationSign, true);
@@ -1328,7 +1318,7 @@
     if (token != null && expression != null && !TypeConversionUtil.isUnaryOperatorApplicable(token, expression)) {
       PsiType type = expression.getType();
       if (type == null) return null;
-      String message = JavaErrorMessages.message("unary.operator.not.applicable", token.getText(), formatType(type));
+      String message = JavaErrorMessages.message("unary.operator.not.applicable", token.getText(), JavaHighlightUtil.formatType(type));
 
       PsiElement parentExpr = token.getParent();
       HighlightInfo highlightInfo =
@@ -1510,7 +1500,7 @@
     final PsiType arrayExpressionType = arrayExpression.getType();
 
     if (arrayExpressionType != null && !(arrayExpressionType instanceof PsiArrayType)) {
-      final String description = JavaErrorMessages.message("array.type.expected", formatType(arrayExpressionType));
+      final String description = JavaErrorMessages.message("array.type.expected", JavaHighlightUtil.formatType(arrayExpressionType));
       final HighlightInfo info =
         HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(arrayExpression).descriptionAndTooltip(description).create();
       QuickFixAction.registerQuickFixAction(info, new ReplaceWithListAccessFix(arrayAccessExpression));
@@ -1560,12 +1550,12 @@
         result.add(info);
 
         if (!arrayTypeFixChecked) {
-          final PsiType checkResult = sameType(initializers);
+          final PsiType checkResult = JavaHighlightUtil.sameType(initializers);
           fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null;
           arrayTypeFixChecked = true;
         }
         if (fix != null) {
-          QuickFixAction.registerQuickFixAction(info, fix);
+          QuickFixAction.registerQuickFixAction(info, new LocalQuickFixOnPsiElementAsIntentionAdapter(fix));
         }
       }
     }
@@ -1573,40 +1563,10 @@
   }
 
   @Nullable
-  private static PsiType getArrayInitializerType(@NotNull final PsiArrayInitializerExpression element) {
-    final PsiType typeCheckResult = sameType(element.getInitializers());
-    if (typeCheckResult != null) {
-      return typeCheckResult.createArrayType();
-    }
-    return null;
-  }
-
-  @Nullable
-  public static PsiType sameType(@NotNull PsiExpression[] expressions) {
-    PsiType type = null;
-    for (PsiExpression expression : expressions) {
-      final PsiType currentType;
-      if (expression instanceof PsiArrayInitializerExpression) {
-        currentType = getArrayInitializerType((PsiArrayInitializerExpression)expression);
-      }
-      else {
-        currentType = expression.getType();
-      }
-      if (type == null) {
-        type = currentType;
-      }
-      else if (!type.equals(currentType)) {
-        return null;
-      }
-    }
-    return type;
-  }
-
-  @Nullable
   private static HighlightInfo checkArrayInitializerCompatibleTypes(@NotNull PsiExpression initializer, final PsiType componentType) {
     PsiType initializerType = initializer.getType();
     if (initializerType == null) {
-      String description = JavaErrorMessages.message("illegal.initializer", formatType(componentType));
+      String description = JavaErrorMessages.message("illegal.initializer", JavaHighlightUtil.formatType(componentType));
       return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(initializer).descriptionAndTooltip(description).create();
     }
     PsiExpression expression = initializer instanceof PsiArrayInitializerExpression ? null : initializer;
@@ -2333,7 +2293,8 @@
                                                redIfNotMatch(lRawType, assignable), requiredRow,
                                                redIfNotMatch(rRawType, assignable), foundRow);
 
-    String description = JavaErrorMessages.message("incompatible.types", formatType(lType1), formatType(rType1));
+    String description = JavaErrorMessages.message("incompatible.types", JavaHighlightUtil.formatType(lType1), JavaHighlightUtil
+      .formatType(rType1));
 
     return HighlightInfo.newHighlightInfo(HighlightInfoType.ERROR).range(textRange).description(description).escapedToolTip(toolTip).navigationShift(navigationShift).create();
   }
@@ -2503,7 +2464,7 @@
   @NotNull
   private static String format(@NotNull PsiElement element) {
     if (element instanceof PsiClass) return formatClass((PsiClass)element);
-    if (element instanceof PsiMethod) return formatMethod((PsiMethod)element);
+    if (element instanceof PsiMethod) return JavaHighlightUtil.formatMethod((PsiMethod)element);
     if (element instanceof PsiField) return formatField((PsiField)element);
     return ElementDescriptionUtil.getElementDescription(element, HighlightUsagesDescriptionLocation.INSTANCE);
   }
@@ -2575,18 +2536,12 @@
   }
 
 
-  public static boolean isSerializable(@NotNull PsiClass aClass) {
-    PsiManager manager = aClass.getManager();
-    PsiClass serializableClass = JavaPsiFacade.getInstance(manager.getProject()).findClass("java.io.Serializable", aClass.getResolveScope());
-    return serializableClass != null && aClass.isInheritor(serializableClass, true);
-  }
-
   public static boolean isSerializationImplicitlyUsedField(@NotNull PsiField field) {
     final String name = field.getName();
     if (!SERIAL_VERSION_UID_FIELD_NAME.equals(name) && !SERIAL_PERSISTENT_FIELDS_FIELD_NAME.equals(name)) return false;
     if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
     PsiClass aClass = field.getContainingClass();
-    return aClass == null || isSerializable(aClass);
+    return aClass == null || JavaHighlightUtil.isSerializable(aClass);
   }
 
   @Nullable
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
index 952cb60..1f92c42 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightVisitorImpl.java
@@ -26,7 +26,6 @@
 import com.intellij.openapi.editor.colors.EditorColorsScheme;
 import com.intellij.openapi.progress.ProgressIndicator;
 import com.intellij.openapi.progress.ProgressManager;
-import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.IndexNotReadyException;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
@@ -54,7 +53,7 @@
 import java.util.Map;
 import java.util.Set;
 
-public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor, DumbAware {
+public class HighlightVisitorImpl extends JavaElementVisitor implements HighlightVisitor {
   private final PsiResolveHelper myResolveHelper;
 
   private HighlightInfoHolder myHolder;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
index d96e461..9841643 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AccessStaticViaInstanceFix.java
@@ -21,8 +21,6 @@
 import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
 import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
-import com.intellij.ide.DataManager;
-import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
@@ -96,7 +94,7 @@
       final PsiExpression qualifierExpression = myExpression.getQualifierExpression();
       PsiElementFactory factory = JavaPsiFacade.getInstance(project).getElementFactory();
       if (qualifierExpression != null) {
-        if (!checkSideEffects(project, containingClass, qualifierExpression, factory, myExpression)) return;
+        if (!checkSideEffects(project, containingClass, qualifierExpression, factory, myExpression,editor)) return;
         PsiElement newQualifier = qualifierExpression.replace(factory.createReferenceExpression(containingClass));
         PsiElement qualifiedWithClassName = myExpression.copy();
         newQualifier.delete();
@@ -110,68 +108,71 @@
     }
   }
 
-  private boolean checkSideEffects(final Project project, PsiClass containingClass, final PsiExpression qualifierExpression,
-                                   PsiElementFactory factory, final PsiElement myExpression) {
+  private boolean checkSideEffects(final Project project,
+                                   PsiClass containingClass,
+                                   final PsiExpression qualifierExpression,
+                                   PsiElementFactory factory,
+                                   final PsiElement myExpression,
+                                   Editor editor) {
     final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
-    boolean hasSideEffects = RemoveUnusedVariableFix.checkSideEffects(qualifierExpression, null, sideEffects);
+    boolean hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects(qualifierExpression, null, sideEffects);
     if (hasSideEffects && !myOnTheFly) return false;
-    if (hasSideEffects && !ApplicationManager.getApplication().isUnitTestMode()) {
-      final TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
-      final Editor editor = PlatformDataKeys.EDITOR.getData(DataManager.getInstance().getDataContext());
-      if (editor == null)
-        return false;
-      HighlightManager.getInstance(project).addOccurrenceHighlights(editor, PsiUtilCore.toPsiElementArray(sideEffects), attributes, true,
-                                                                    null);
-      try {
-        hasSideEffects = PsiUtil.isStatement(factory.createStatementFromText(qualifierExpression.getText(), qualifierExpression));
-      }
-      catch (IncorrectOperationException e) {
-        hasSideEffects = false;
-      }
-      final PsiReferenceExpression qualifiedWithClassName = (PsiReferenceExpression)myExpression.copy();
-      qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass));
-      final boolean canCopeWithSideEffects = hasSideEffects;
-      final SideEffectWarningDialog dialog =
-        new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression),
-                                    canCopeWithSideEffects){
-          @Override
-          protected String sideEffectsDescription() {
-            if (canCopeWithSideEffects) {
-              return "<html><body>" +
-                     "  There are possible side effects found in expression '" +
-                     qualifierExpression.getText() +
-                     "'<br>" +
-                     "  You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li>" +
-                     "  <li><b>Transform</b> qualified expression into the statement on its own.<br>" +
-                     "  That is,<br>" +
-                     "  <table border=1><tr><td><code>" +
-                     myExpression.getText() +
-                     "</code></td></tr></table><br> becomes: <br>" +
-                     "  <table border=1><tr><td><code>" +
-                     qualifierExpression.getText() +
-                     ";<br>" +
-                     qualifiedWithClassName.getText() +
-                     "       </code></td></tr></table></li>" +
-                     "  </body></html>";
-            } else {
-              return "<html><body>  There are possible side effects found in expression '" + qualifierExpression.getText() + "'<br>" +
-                     "You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li></body></html>";
-            }
+    if (!hasSideEffects || ApplicationManager.getApplication().isUnitTestMode()) {
+      return true;
+    }
+    if (editor == null) {
+      return false;
+    }
+    TextAttributes attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
+    HighlightManager.getInstance(project).addOccurrenceHighlights(editor, PsiUtilCore.toPsiElementArray(sideEffects), attributes, true, null);
+    try {
+      hasSideEffects = PsiUtil.isStatement(factory.createStatementFromText(qualifierExpression.getText(), qualifierExpression));
+    }
+    catch (IncorrectOperationException e) {
+      hasSideEffects = false;
+    }
+    final PsiReferenceExpression qualifiedWithClassName = (PsiReferenceExpression)myExpression.copy();
+    qualifiedWithClassName.setQualifierExpression(factory.createReferenceExpression(containingClass));
+    final boolean canCopeWithSideEffects = hasSideEffects;
+    final SideEffectWarningDialog dialog =
+      new SideEffectWarningDialog(project, false, null, sideEffects.get(0).getText(), PsiExpressionTrimRenderer.render(qualifierExpression),
+                                  canCopeWithSideEffects){
+        @Override
+        protected String sideEffectsDescription() {
+          if (canCopeWithSideEffects) {
+            return "<html><body>" +
+                   "  There are possible side effects found in expression '" +
+                   qualifierExpression.getText() +
+                   "'<br>" +
+                   "  You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li>" +
+                   "  <li><b>Transform</b> qualified expression into the statement on its own.<br>" +
+                   "  That is,<br>" +
+                   "  <table border=1><tr><td><code>" +
+                   myExpression.getText() +
+                   "</code></td></tr></table><br> becomes: <br>" +
+                   "  <table border=1><tr><td><code>" +
+                   qualifierExpression.getText() +
+                   ";<br>" +
+                   qualifiedWithClassName.getText() +
+                   "       </code></td></tr></table></li>" +
+                   "  </body></html>";
           }
-        };
-      dialog.show();
-      int res = dialog.getExitCode();
-      if (res == SideEffectWarningDialog.CANCEL) return false;
-      try {
-        if (res == SideEffectWarningDialog.MAKE_STATEMENT) {
-          final PsiStatement statementFromText = factory.createStatementFromText(qualifierExpression.getText() + ";", null);
-          final PsiStatement statement = PsiTreeUtil.getParentOfType(myExpression, PsiStatement.class);
-          statement.getParent().addBefore(statementFromText, statement);
+          return "<html><body>  There are possible side effects found in expression '" + qualifierExpression.getText() + "'<br>" +
+                 "You can:<ul><li><b>Remove</b> class reference along with whole expressions involved, or</li></body></html>";
         }
+      };
+    dialog.show();
+    int res = dialog.getExitCode();
+    if (res == RemoveUnusedVariableUtil.CANCEL) return false;
+    try {
+      if (res == RemoveUnusedVariableUtil.MAKE_STATEMENT) {
+        final PsiStatement statementFromText = factory.createStatementFromText(qualifierExpression.getText() + ";", null);
+        final PsiStatement statement = PsiTreeUtil.getParentOfType(myExpression, PsiStatement.class);
+        statement.getParent().addBefore(statementFromText, statement);
       }
-      catch (IncorrectOperationException e) {
-        LOG.error(e);
-      }
+    }
+    catch (IncorrectOperationException e) {
+      LOG.error(e);
     }
     return true;
   }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
index dff7b58..6bb1d53 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/AddVariableInitializerFix.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.diagnostic.Logger;
@@ -75,7 +75,7 @@
     else {
       LOG.error("Unknown variable type: "+myVariable);
     }
-    PsiVariable var = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myVariable);
+    PsiVariable var = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myVariable);
     TextRange range = var.getInitializer().getTextRange();
     int offset = range.getStartOffset();
     editor.getCaretModel().moveToOffset(offset);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
index 554c87c..04a7b58 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CastMethodArgumentFix.java
@@ -24,7 +24,7 @@
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.psi.*;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
@@ -38,10 +38,10 @@
   @NotNull
   public String getText() {
     if (myArgList.getExpressions().length == 1) {
-      return QuickFixBundle.message("cast.single.parameter.text", HighlightUtil.formatType(myToType));
+      return QuickFixBundle.message("cast.single.parameter.text", JavaHighlightUtil.formatType(myToType));
     }
 
-    return QuickFixBundle.message("cast.parameter.text", myIndex + 1, HighlightUtil.formatType(myToType));
+    return QuickFixBundle.message("cast.parameter.text", myIndex + 1, JavaHighlightUtil.formatType(myToType));
   }
 
   private static class MyFixerActionFactory extends ArgumentFixerActionFactory {
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
index ba7171b..1fecce1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeMethodSignatureFromUsageFix.java
@@ -19,7 +19,7 @@
 import com.intellij.codeInsight.TargetElementUtil;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.find.FindManager;
 import com.intellij.find.findUsages.FindUsagesHandler;
@@ -90,7 +90,7 @@
     final String shortText = getShortText();
     if (shortText != null) return shortText;
     return QuickFixBundle.message("change.method.signature.from.usage.text",
-                                  HighlightUtil.formatMethod(myTargetMethod),
+                                  JavaHighlightUtil.formatMethod(myTargetMethod),
                                   myTargetMethod.getName(),
                                   formatTypesList(myNewParametersInfo, myContext));
   }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
index 8c31230..0683af7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ChangeToAppendFix.java
@@ -19,15 +19,13 @@
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInspection.util.ChangeToAppendUtil;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
 import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.IncorrectOperationException;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 /**
  * @author Bas Leijdekkers
@@ -48,9 +46,10 @@
   @Override
   public String getText() {
     return QuickFixBundle.message("change.to.append.text",
-                                  buildAppendExpression(myAssignmentExpression.getRExpression(),
-                                                        myLhsType.equalsToText("java.lang.Appendable"),
-                                                        new StringBuilder(myAssignmentExpression.getLExpression().getText())));
+                                  ChangeToAppendUtil.buildAppendExpression(myAssignmentExpression.getRExpression(),
+                                                                           myLhsType.equalsToText("java.lang.Appendable"),
+                                                                           new StringBuilder(
+                                                                             myAssignmentExpression.getLExpression().getText())));
   }
 
   @NotNull
@@ -78,81 +77,8 @@
   public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
     if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
     final PsiExpression appendExpression =
-      buildAppendExpression(myAssignmentExpression.getLExpression(), myAssignmentExpression.getRExpression());
+      ChangeToAppendUtil.buildAppendExpression(myAssignmentExpression.getLExpression(), myAssignmentExpression.getRExpression());
     if (appendExpression == null) return;
     myAssignmentExpression.replace(appendExpression);
   }
-
-  @Nullable
-  public static PsiExpression buildAppendExpression(PsiExpression appendable, PsiExpression concatenation) {
-    if (concatenation == null) return null;
-    final PsiType type = appendable.getType();
-    if (type == null) return null;
-    final StringBuilder result =
-      buildAppendExpression(concatenation, type.equalsToText("java.lang.Appendable"), new StringBuilder(appendable.getText()));
-    if (result == null) return null;
-    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(appendable.getProject());
-    return factory.createExpressionFromText(result.toString(), appendable);
-  }
-
-  @Nullable
-  private static StringBuilder buildAppendExpression(PsiExpression concatenation, boolean useStringValueOf, @NonNls StringBuilder out)
-    throws IncorrectOperationException {
-    final PsiType type = concatenation.getType();
-    if (type == null) {
-      return null;
-    }
-    if (concatenation instanceof PsiPolyadicExpression && type.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
-      PsiPolyadicExpression polyadicExpression = (PsiPolyadicExpression)concatenation;
-      final PsiExpression[] operands = polyadicExpression.getOperands();
-      boolean isConstant = true;
-      boolean isString = false;
-      final StringBuilder builder = new StringBuilder();
-      for (PsiExpression operand : operands) {
-        if (isConstant && PsiUtil.isConstantExpression(operand)) {
-          if (builder.length() != 0) {
-            builder.append('+');
-          }
-          final PsiType operandType = operand.getType();
-          if (operandType != null && operandType.equalsToText(CommonClassNames.JAVA_LANG_STRING)) {
-            isString = true;
-          }
-          builder.append(operand.getText());
-        }
-        else {
-          isConstant = false;
-          if (builder.length() != 0) {
-            append(builder, useStringValueOf && !isString, out);
-            builder.setLength(0);
-          }
-          buildAppendExpression(operand, useStringValueOf, out);
-        }
-      }
-      if (builder.length() != 0) {
-        append(builder, false, out);
-      }
-    }
-    else if (concatenation instanceof PsiParenthesizedExpression) {
-      final PsiParenthesizedExpression parenthesizedExpression = (PsiParenthesizedExpression)concatenation;
-      final PsiExpression expression = parenthesizedExpression.getExpression();
-      if (expression != null) {
-        return buildAppendExpression(expression, useStringValueOf, out);
-      }
-    }
-    else {
-      append(concatenation.getText(), useStringValueOf && !type.equalsToText(CommonClassNames.JAVA_LANG_STRING), out);
-    }
-    return out;
-  }
-
-  private static void append(CharSequence text, boolean useStringValueOf, StringBuilder out) {
-    out.append(".append(");
-    if (useStringValueOf) {
-      out.append("String.valueOf(").append(text).append(')');
-    }
-    else {
-      out.append(text);
-    }
-    out.append(')');
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
index 9b20330..a996525 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ConvertSwitchToIfIntention.java
@@ -92,7 +92,7 @@
     final boolean hadSideEffects;
     final String expressionText;
     final Project project = switchStatement.getProject();
-    if (RemoveUnusedVariableFix.checkSideEffects(switchExpression, null, new ArrayList<PsiElement>())) {
+    if (RemoveUnusedVariableUtil.checkSideEffects(switchExpression, null, new ArrayList<PsiElement>())) {
       hadSideEffects = true;
 
       final JavaCodeStyleManager javaCodeStyleManager =
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
index 35be223..ed56ce5 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateCastExpressionFromInstanceofAction.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
@@ -52,7 +52,7 @@
     assert instanceOfExpression.getContainingFile() == file : instanceOfExpression.getContainingFile() + "; file="+file;
     PsiElement decl = createAndInsertCast(instanceOfExpression, editor, file);
     if (decl == null) return;
-    decl = CodeStyleManager.getInstance(project).reformat(CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl));
+    decl = CodeStyleManager.getInstance(project).reformat(CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl));
     editor.getCaretModel().moveToOffset(decl.getTextRange().getEndOffset());
   }
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
index 43bd4c0..ff1b786 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateClassFromNewFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.ExpectedTypesProvider;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
@@ -100,7 +100,7 @@
       setupSuperCall(aClass, constructor, templateBuilder);
 
       getReferenceElement(newExpression).bindToElement(aClass);
-      aClass = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(aClass);
+      aClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(aClass);
       final Template template = templateBuilder.buildTemplate();
       template.setToReformat(true);
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
index 7074f27..fa32f9f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromCallFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.generation.OverrideImplementUtil;
 import com.intellij.codeInsight.template.Template;
@@ -65,7 +65,7 @@
                                                  getTargetSubstitutor(myConstructorCall));
       final PsiMethod superConstructor = CreateClassFromNewFix.setupSuperCall(targetClass, constructor, templateBuilder);
 
-      constructor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(constructor);
+      constructor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(constructor);
       Template template = templateBuilder.buildTemplate();
       final Editor editor = positionCursor(project, targetClass.getContainingFile(), targetClass);
       if (editor == null) return;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
index 09fcdeb..f944fc7 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateConstructorFromThisOrSuperFix.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
 import com.intellij.codeInsight.CodeInsightUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.template.Template;
 import com.intellij.codeInsight.template.TemplateBuilderImpl;
@@ -95,7 +95,7 @@
       templateBuilder.setEndVariableAfter(constructor.getBody().getLBrace());
       final RangeMarker rangeMarker = psiFile.getViewProvider().getDocument().createRangeMarker(myMethodCall.getTextRange());
 
-      constructor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(constructor);
+      constructor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(constructor);
 
       targetClass = constructor.getContainingClass();
       myMethodCall = CodeInsightUtil.findElementInRange(psiFile, rangeMarker.getStartOffset(), rangeMarker.getEndOffset(), myMethodCall.getClass());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
index 97c8f89..4972ed1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateEnumConstantFromUsageFix.java
@@ -15,12 +15,11 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.ExpectedTypeUtil;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.intention.HighPriorityAction;
-import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInsight.template.Template;
 import com.intellij.codeInsight.template.TemplateBuilderImpl;
 import com.intellij.openapi.diagnostic.Logger;
@@ -29,7 +28,6 @@
 import com.intellij.openapi.util.TextRange;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.util.Function;
 import org.jetbrains.annotations.NotNull;
 
@@ -75,7 +73,7 @@
           builder.replaceElement(expression, new EmptyExpression());
         }
 
-        enumConstant = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(enumConstant);
+        enumConstant = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(enumConstant);
         final Template template = builder.buildTemplate();
 
         final Project project = targetClass.getProject();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
index 41ffc74..24ba71d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalFromUsageFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.intention.impl.TypeExpression;
 import com.intellij.codeInsight.template.Template;
@@ -110,7 +110,7 @@
       CodeStyleSettingsManager.getSettings(project).GENERATE_FINAL_LOCALS && !CreateFromUsageUtils.isAccessedForWriting(expressions);
     PsiUtil.setModifierProperty(var, PsiModifier.FINAL, isFinal);
 
-    var = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(var);
+    var = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(var);
     if (var == null) return;
     TemplateBuilderImpl builder = new TemplateBuilderImpl(var);
     builder.replaceElement(var.getTypeElement(), expression);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
index e34cbb0..9fc885e 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateLocalVarFromInstanceofAction.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.PsiEquivalenceUtil;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
@@ -206,7 +206,7 @@
       final PsiStatement statementInside = isNegated(instanceOfExpression) ? null : getExpressionStatementInside(file, editor, instanceOfExpression.getOperand());
       PsiDeclarationStatement decl = createLocalVariableDeclaration(instanceOfExpression, statementInside);
       if (decl == null) return;
-      decl = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(decl);
+      decl = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(decl);
 
       PsiLocalVariable localVariable = (PsiLocalVariable)decl.getDeclaredElements()[0];
       TemplateBuilderImpl builder = new TemplateBuilderImpl(localVariable);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
index a7cc465..d3fb2c1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreateMethodFromUsageFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
@@ -214,7 +214,7 @@
                                ExpectedTypeInfo[] expectedTypes,
                                @Nullable final PsiElement context) {
 
-    method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
+    method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
 
     if (method == null) {
       return;
@@ -231,7 +231,7 @@
       .setupTypeElement(method.getReturnTypeElement(), expectedTypes, substitutor, builder, context, targetClass);
     PsiCodeBlock body = method.getBody();
     builder.setEndVariableAfter(shouldBeAbstract || body == null ? method : body.getLBrace());
-    method = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(method);
+    method = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(method);
     if (method == null) return;
 
     RangeMarker rangeMarker = document.createRangeMarker(method.getTextRange());
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
index 2626335..c616859 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/CreatePropertyFromUsageFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.completion.JavaLookupElementBuilder;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.intention.HighPriorityAction;
@@ -100,7 +100,7 @@
     if (classes.isEmpty()) return false;
 
     if (!checkTargetClasses(classes, methodName)) return false;
-    
+
     for (PsiClass aClass : classes) {
       if (!aClass.isInterface()) {
         setText(getterOrSetter);
@@ -242,13 +242,17 @@
     }
     accessor.setName(callText);
     PsiUtil.setModifierProperty(accessor, PsiModifier.STATIC, isStatic);
+    final String modifier = PsiUtil.getMaximumModifierForMember(targetClass);
+    if (modifier != null) {
+      PsiUtil.setModifierProperty(accessor, modifier, true);
+    }
 
     TemplateBuilderImpl builder = new TemplateBuilderImpl(accessor);
     builder.replaceElement(typeReference, TYPE_VARIABLE, new TypeExpression(project, expectedTypes), true);
     builder.replaceElement(fieldReference, FIELD_VARIABLE, new FieldExpression(field, targetClass, expectedTypes), true);
     builder.setEndVariableAfter(body.getLBrace());
 
-    accessor = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(accessor);
+    accessor = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(accessor);
     LOG.assertTrue(accessor != null);
     targetClass = accessor.getContainingClass();
     LOG.assertTrue(targetClass != null);
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
index 8ddf826..35d25d8 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteCatchFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
@@ -34,7 +34,7 @@
   @Override
   @NotNull
   public String getText() {
-    return QuickFixBundle.message("delete.catch.text", HighlightUtil.formatType(myCatchParameter.getType()));
+    return QuickFixBundle.message("delete.catch.text", JavaHighlightUtil.formatType(myCatchParameter.getType()));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
index 69118b9..41e08d6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/DeleteMultiCatchFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
@@ -39,7 +39,7 @@
   @NotNull
   @Override
   public String getText() {
-    return QuickFixBundle.message("delete.catch.text", HighlightUtil.formatType(myTypeElement.getType()));
+    return QuickFixBundle.message("delete.catch.text", JavaHighlightUtil.formatType(myTypeElement.getType()));
   }
 
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
index 4252711..b0c9790 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/GeneralizeCatchFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
@@ -41,8 +41,8 @@
   @NotNull
   public String getText() {
     return QuickFixBundle.message("generalize.catch.text",
-                                  HighlightUtil.formatType(myCatchParameter == null ? null : myCatchParameter.getType()),
-                                  HighlightUtil.formatType(myUnhandledException));
+                                  JavaHighlightUtil.formatType(myCatchParameter == null ? null : myCatchParameter.getType()),
+                                  JavaHighlightUtil.formatType(myUnhandledException));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
index ca346d3..a2bebf6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFix.java
@@ -108,7 +108,7 @@
   }
 
   @Override
-  protected List<PsiClass> filterByContext(List<PsiClass> candidates, PsiJavaCodeReferenceElement ref) {
+  protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull PsiJavaCodeReferenceElement ref) {
     PsiElement typeElement = ref.getParent();
     if (typeElement instanceof PsiTypeElement) {
       PsiElement var = typeElement.getParent();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
index 1419aca..3e045a3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/ImportClassFixBase.java
@@ -58,6 +58,7 @@
  * @author peter
  */
 public abstract class ImportClassFixBase<T extends PsiElement, R extends PsiReference> implements HintAction, HighPriorityAction {
+  @NotNull
   private final T myElement;
   private final R myRef;
 
@@ -88,6 +89,13 @@
 
   @NotNull
   public List<PsiClass> getClassesToImport() {
+    if (myRef instanceof PsiJavaReference) {
+      JavaResolveResult result = ((PsiJavaReference)myRef).advancedResolve(true);
+      PsiElement element = result.getElement();
+      // already imported
+      // can happen when e.g. class name happened to be in a method position
+      if (element instanceof PsiClass && result.isValidResult()) return Collections.emptyList();
+    }
     PsiShortNamesCache cache = PsiShortNamesCache.getInstance(myElement.getProject());
     String name = getReferenceName(myRef);
     GlobalSearchScope scope = myElement.getResolveScope();
@@ -149,7 +157,7 @@
     return null;
   }
 
-  protected List<PsiClass> filterByContext(List<PsiClass> candidates, T ref) {
+  protected List<PsiClass> filterByContext(@NotNull List<PsiClass> candidates, @NotNull T ref) {
     return candidates;
   }
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
index 09053e5..ea5e364 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/InitializeFinalFieldInConstructorFix.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.generation.PsiMethodMember;
@@ -113,7 +113,7 @@
     T highest = null;
     int highestTextOffset = Integer.MAX_VALUE;
     for (T element : elements) {
-      final T forcedElem = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(element);
+      final T forcedElem = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(element);
       final int startOffset = forcedElem.getTextOffset();
       if (startOffset < highestTextOffset) {
         highest = forcedElem;
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
index 3fc0555..520f97f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/JavaCreateFieldFromUsageHelper.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.daemon.impl.quickfix;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.template.Template;
 import com.intellij.codeInsight.template.TemplateBuilderImpl;
@@ -40,7 +40,7 @@
                                     PsiSubstitutor substitutor) {
     PsiElementFactory factory = JavaPsiFacade.getElementFactory(field.getProject());
 
-    field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
+    field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field);
     TemplateBuilderImpl builder = new TemplateBuilderImpl(field);
     if (!(expectedTypes instanceof ExpectedTypeInfo[])) {
       expectedTypes = ExpectedTypeInfo.EMPTY_ARRAY;
@@ -53,7 +53,7 @@
       builder.replaceElement(field.getInitializer(), new EmptyExpression());
       PsiIdentifier identifier = field.getNameIdentifier();
       builder.setEndVariableAfter(identifier);
-      field = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(field);
+      field = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(field);
     }
     editor.getCaretModel().moveToOffset(field.getTextRange().getStartOffset());
     Template template = builder.buildInlineTemplate();
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
index bdd618c..48fae89 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/MoveCatchUpFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
@@ -44,8 +44,8 @@
   @NotNull
   public String getText() {
     return QuickFixBundle.message("move.catch.up.text",
-                                  HighlightUtil.formatType(myCatchSection.getCatchType()),
-                                  HighlightUtil.formatType(myMoveBeforeSection.getCatchType()));
+                                  JavaHighlightUtil.formatType(myCatchSection.getCatchType()),
+                                  JavaHighlightUtil.formatType(myMoveBeforeSection.getCatchType()));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
index 38f2c8a..8ca4195 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveRedundantArgumentsFix.java
@@ -18,7 +18,7 @@
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
 import com.intellij.codeInsight.daemon.impl.HighlightInfo;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
@@ -50,7 +50,7 @@
   @NotNull
   @Override
   public String getText() {
-    return QuickFixBundle.message("remove.redundant.arguments.text", HighlightUtil.formatMethod(myTargetMethod));
+    return QuickFixBundle.message("remove.redundant.arguments.text", JavaHighlightUtil.formatMethod(myTargetMethod));
   }
 
   @NotNull
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
index 3c67fa5..d779b1b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/RemoveUnusedVariableFix.java
@@ -27,13 +27,8 @@
 import com.intellij.openapi.editor.markup.TextAttributes;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PsiExpressionTrimRenderer;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilCore;
-import com.intellij.refactoring.psi.PropertyUtils;
+import com.intellij.psi.util.*;
 import com.intellij.util.IncorrectOperationException;
-import gnu.trove.THashSet;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
@@ -75,21 +70,6 @@
     removeVariableAndReferencingStatements(editor);
   }
 
-  private static void deleteReferences(PsiVariable variable, List<PsiElement> references, int mode) throws IncorrectOperationException {
-    for (PsiElement expression : references) {
-      processUsage(expression, variable, null, mode);
-    }
-  }
-
-  private static void collectReferences(@NotNull PsiElement context, final PsiVariable variable, final List<PsiElement> references) {
-    context.accept(new JavaRecursiveElementWalkingVisitor() {
-      @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
-        if (expression.resolve() == variable) references.add(expression);
-        super.visitReferenceExpression(expression);
-      }
-    });
-  }
-
   private void removeVariableAndReferencingStatements(Editor editor) {
     final List<PsiElement> references = new ArrayList<PsiElement>();
     final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
@@ -97,13 +77,13 @@
     try {
       PsiElement context = myVariable instanceof PsiField ? ((PsiField)myVariable).getContainingClass() : PsiUtil.getVariableCodeBlock(myVariable, null);
       if (context != null) {
-        collectReferences(context, myVariable, references);
+        RemoveUnusedVariableUtil.collectReferences(context, myVariable, references);
       }
       // do not forget to delete variable declaration
       references.add(myVariable);
       // check for side effects
       for (PsiElement element : references) {
-        Boolean result = processUsage(element, myVariable, sideEffects, SideEffectWarningDialog.CANCEL);
+        Boolean result = RemoveUnusedVariableUtil.processUsage(element, myVariable, sideEffects, RemoveUnusedVariableUtil.CANCEL);
         if (result == null) return;
         canCopeWithSideEffects[0] &= result;
       }
@@ -118,7 +98,7 @@
       @Override
       public void run() {
         try {
-          deleteReferences(myVariable, references, deleteMode);
+          RemoveUnusedVariableUtil.deleteReferences(myVariable, references, deleteMode);
         }
         catch (IncorrectOperationException e) {
           LOG.error(e);
@@ -133,11 +113,11 @@
                                            boolean canCopeWithSideEffects,
                                            @NonNls String beforeText,
                                            @NonNls String afterText) {
-    if (sideEffects.isEmpty()) return SideEffectWarningDialog.DELETE_ALL;
+    if (sideEffects.isEmpty()) return RemoveUnusedVariableUtil.DELETE_ALL;
     if (ApplicationManager.getApplication().isUnitTestMode()) {
       return canCopeWithSideEffects
-             ? SideEffectWarningDialog.MAKE_STATEMENT
-             : SideEffectWarningDialog.DELETE_ALL;
+             ? RemoveUnusedVariableUtil.MAKE_STATEMENT
+             : RemoveUnusedVariableUtil.DELETE_ALL;
     }
     Project project = editor.getProject();
     HighlightManager highlightManager = HighlightManager.getInstance(project);
@@ -163,235 +143,16 @@
       final PsiElement sideEffect = sideEffects.get(0);
       if (sideEffect instanceof PsiExpression) {
         text = PsiExpressionTrimRenderer.render((PsiExpression)sideEffect);
-      } else {
+      }
+      else {
         text = sideEffect.getText();
       }
     }
     return showSideEffectsWarning(sideEffects, variable, editor, canCopeWithSideEffects, text, text);
   }
 
-  /**
-   *
-   * @param element
-   * @param variable
-   * @param sideEffects if null, delete usages, otherwise collect side effects
-   * @return true if there are at least one unrecoverable side effect found, false if no side effects,
-   *         null if read usage found (may happen if interval between fix creation in invoke() call was long enough)
-   * @throws IncorrectOperationException
-   */
-  private static Boolean processUsage(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects, int deleteMode)
-    throws IncorrectOperationException {
-    if (!element.isValid()) return null;
-    PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
-    while (element != null) {
-      if (element instanceof PsiAssignmentExpression) {
-        PsiAssignmentExpression expression = (PsiAssignmentExpression)element;
-        PsiExpression lExpression = expression.getLExpression();
-        // there should not be read access to the variable, otherwise it is not unused
-        if (!(lExpression instanceof PsiReferenceExpression) || variable != ((PsiReferenceExpression)lExpression).resolve()) {
-          return null;
-        }
-        PsiExpression rExpression = expression.getRExpression();
-        rExpression = PsiUtil.deparenthesizeExpression(rExpression);
-        if (rExpression == null) return true;
-        // replace assignment with expression and resimplify
-        boolean sideEffectFound = checkSideEffects(rExpression, variable, sideEffects);
-        if (!(element.getParent() instanceof PsiExpressionStatement) || PsiUtil.isStatement(rExpression)) {
-          if (deleteMode == SideEffectWarningDialog.MAKE_STATEMENT ||
-              deleteMode == SideEffectWarningDialog.DELETE_ALL && !(element.getParent() instanceof PsiExpressionStatement)) {
-            element = replaceElementWithExpression(rExpression, factory, element);
-            while (element.getParent() instanceof PsiParenthesizedExpression) {
-              element = element.getParent().replace(element);
-            }
-            List<PsiElement> references = new ArrayList<PsiElement>();
-            collectReferences(element, variable, references);
-            deleteReferences(variable, references, deleteMode);
-          }
-          else if (deleteMode == SideEffectWarningDialog.DELETE_ALL) {
-            deleteWholeStatement(element, factory);
-          }
-          return true;
-        }
-        else {
-          if (deleteMode != SideEffectWarningDialog.CANCEL) {
-            deleteWholeStatement(element, factory);
-          }
-          return !sideEffectFound;
-        }
-      }
-      else if (element instanceof PsiExpressionStatement && deleteMode != SideEffectWarningDialog.CANCEL) {
-        element.delete();
-        break;
-      }
-      else if (element instanceof PsiVariable && element == variable) {
-        PsiExpression expression = variable.getInitializer();
-        if (expression != null) {
-          expression = PsiUtil.deparenthesizeExpression(expression);
-        }
-        boolean sideEffectsFound = checkSideEffects(expression, variable, sideEffects);
-        if (expression != null && PsiUtil.isStatement(expression) && variable instanceof PsiLocalVariable
-            &&
-            !(variable.getParent() instanceof PsiDeclarationStatement &&
-              ((PsiDeclarationStatement)variable.getParent()).getDeclaredElements().length > 1)) {
-          if (deleteMode == SideEffectWarningDialog.MAKE_STATEMENT) {
-            element = element.replace(createStatementIfNeeded(expression, factory, element));
-            List<PsiElement> references = new ArrayList<PsiElement>();
-            collectReferences(element, variable, references);
-            deleteReferences(variable, references, deleteMode);
-          }
-          else if (deleteMode == SideEffectWarningDialog.DELETE_ALL) {
-            element.delete();
-          }
-          return true;
-        }
-        else {
-          if (deleteMode != SideEffectWarningDialog.CANCEL) {
-            if (element instanceof PsiField) {
-              ((PsiField)element).normalizeDeclaration();
-            }
-            element.delete();
-          }
-          return !sideEffectsFound;
-        }
-      }
-      element = element.getParent();
-    }
-    return true;
-  }
-
-  private static void deleteWholeStatement(PsiElement element, PsiElementFactory factory)
-    throws IncorrectOperationException {
-    // just delete it altogether
-    if (element.getParent() instanceof PsiExpressionStatement) {
-      PsiExpressionStatement parent = (PsiExpressionStatement)element.getParent();
-      if (parent.getParent() instanceof PsiCodeBlock) {
-        parent.delete();
-      }
-      else {
-        // replace with empty statement (to handle with 'if (..) i=0;' )
-        parent.replace(createStatementIfNeeded(null, factory, element));
-      }
-    }
-    else {
-      element.delete();
-    }
-  }
-
-  private static PsiElement createStatementIfNeeded(PsiExpression expression,
-                                                    PsiElementFactory factory,
-                                                    PsiElement element) throws IncorrectOperationException {
-    // if element used in expression, subexpression will do
-    if (!(element.getParent() instanceof PsiExpressionStatement) &&
-        !(element.getParent() instanceof PsiDeclarationStatement)) {
-      return expression;
-    }
-    return factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
-  }
-
-  private static PsiElement replaceElementWithExpression(PsiExpression expression,
-                                                         PsiElementFactory factory,
-                                                         PsiElement element) throws IncorrectOperationException {
-    PsiElement elementToReplace = element;
-    PsiElement expressionToReplaceWith = expression;
-    if (element.getParent() instanceof PsiExpressionStatement) {
-      elementToReplace = element.getParent();
-      expressionToReplaceWith =
-      factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
-    }
-    else if (element.getParent() instanceof PsiDeclarationStatement) {
-      expressionToReplaceWith =
-      factory.createStatementFromText((expression == null ? "" : expression.getText()) + ";", null);
-    }
-    return elementToReplace.replace(expressionToReplaceWith);
-  }
-
-    public static boolean checkSideEffects(PsiElement element, PsiVariable variable, List<PsiElement> sideEffects) {
-    if (sideEffects == null || element == null) return false;
-    if (element instanceof PsiMethodCallExpression) {
-      final PsiMethod psiMethod = ((PsiMethodCallExpression)element).resolveMethod();
-      if (psiMethod == null || !PropertyUtils.isSimpleGetter(psiMethod) && !PropertyUtils.isSimpleSetter(psiMethod)) {
-        sideEffects.add(element);
-        return true;
-      }
-    }
-    if (element instanceof PsiNewExpression) {
-      PsiNewExpression newExpression = (PsiNewExpression)element;
-      if (newExpression.getArrayDimensions().length == 0
-          && newExpression.getArrayInitializer() == null
-          && !isSideEffectFreeConstructor(newExpression)) {
-        sideEffects.add(element);
-        return true;
-      }
-    }
-    if (element instanceof PsiAssignmentExpression
-        && !(((PsiAssignmentExpression)element).getLExpression() instanceof PsiReferenceExpression
-             && ((PsiReferenceExpression)((PsiAssignmentExpression)element).getLExpression()).resolve() == variable)) {
-      sideEffects.add(element);
-      return true;
-    }
-    PsiElement[] children = element.getChildren();
-
-      for (PsiElement child : children) {
-        checkSideEffects(child, variable, sideEffects);
-      }
-    return !sideEffects.isEmpty();
-  }
-
-  private static final Set<String> ourSideEffectFreeClasses = new THashSet<String>();
-  static {
-    ourSideEffectFreeClasses.add(Object.class.getName());
-    ourSideEffectFreeClasses.add(Short.class.getName());
-    ourSideEffectFreeClasses.add(Character.class.getName());
-    ourSideEffectFreeClasses.add(Byte.class.getName());
-    ourSideEffectFreeClasses.add(Integer.class.getName());
-    ourSideEffectFreeClasses.add(Long.class.getName());
-    ourSideEffectFreeClasses.add(Float.class.getName());
-    ourSideEffectFreeClasses.add(Double.class.getName());
-    ourSideEffectFreeClasses.add(String.class.getName());
-    ourSideEffectFreeClasses.add(StringBuffer.class.getName());
-    ourSideEffectFreeClasses.add(Boolean.class.getName());
-
-    ourSideEffectFreeClasses.add(ArrayList.class.getName());
-    ourSideEffectFreeClasses.add(Date.class.getName());
-    ourSideEffectFreeClasses.add(HashMap.class.getName());
-    ourSideEffectFreeClasses.add(HashSet.class.getName());
-    ourSideEffectFreeClasses.add(Hashtable.class.getName());
-    ourSideEffectFreeClasses.add(LinkedHashMap.class.getName());
-    ourSideEffectFreeClasses.add(LinkedHashSet.class.getName());
-    ourSideEffectFreeClasses.add(LinkedList.class.getName());
-    ourSideEffectFreeClasses.add(Stack.class.getName());
-    ourSideEffectFreeClasses.add(TreeMap.class.getName());
-    ourSideEffectFreeClasses.add(TreeSet.class.getName());
-    ourSideEffectFreeClasses.add(Vector.class.getName());
-    ourSideEffectFreeClasses.add(WeakHashMap.class.getName());
-  }
-
-  private static boolean isSideEffectFreeConstructor(PsiNewExpression newExpression) {
-    PsiJavaCodeReferenceElement classReference = newExpression.getClassReference();
-    PsiClass aClass = classReference == null ? null : (PsiClass)classReference.resolve();
-    String qualifiedName = aClass == null ? null : aClass.getQualifiedName();
-    if (qualifiedName == null) return false;
-    if (ourSideEffectFreeClasses.contains(qualifiedName)) return true;
-
-    PsiFile file = aClass.getContainingFile();
-    PsiDirectory directory = file.getContainingDirectory();
-    PsiPackage classPackage = JavaDirectoryService.getInstance().getPackage(directory);
-    String packageName = classPackage == null ? null : classPackage.getQualifiedName();
-
-    // all Throwable descendants from java.lang are side effects free
-    if ("java.lang".equals(packageName) || "java.io".equals(packageName)) {
-      PsiClass throwableClass = JavaPsiFacade.getInstance(aClass.getProject()).findClass("java.lang.Throwable", aClass.getResolveScope());
-      if (throwableClass != null && InheritanceUtil.isInheritorOrSelf(aClass, throwableClass, true)) {
-        return true;
-      }
-    }
-    return false;
-  }
-
   @Override
   public boolean startInWriteAction() {
     return false;
   }
-
-
 }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
index 5a15f0f..5f30a43 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SideEffectWarningDialog.java
@@ -39,9 +39,6 @@
   private final boolean myCanCopeWithSideEffects;
   private AbstractAction myRemoveAllAction;
   private AbstractAction myCancelAllAction;
-  public static final int MAKE_STATEMENT = 1;
-  public static final int DELETE_ALL = 2;
-  public static final int CANCEL = 0;
 
   public SideEffectWarningDialog(Project project, boolean canBeParent, PsiVariable variable, String beforeText, String afterText, boolean canCopeWithSideEffects) {
     super(project, canBeParent);
@@ -66,7 +63,7 @@
 
       @Override
       public void actionPerformed(ActionEvent e) {
-        close(DELETE_ALL);
+        close(RemoveUnusedVariableUtil.DELETE_ALL);
       }
 
     };
@@ -79,7 +76,7 @@
 
         @Override
         public void actionPerformed(ActionEvent e) {
-          close(MAKE_STATEMENT);
+          close(RemoveUnusedVariableUtil.MAKE_STATEMENT);
         }
       };
       actions.add(makeStmtAction);
@@ -113,7 +110,7 @@
 
   @Override
   public void doCancelAction() {
-    close(CANCEL);
+    close(RemoveUnusedVariableUtil.CANCEL);
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
index 8ff371f..6f48890 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/SuperMethodReturnFix.java
@@ -17,7 +17,7 @@
 
 import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.daemon.QuickFixBundle;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
@@ -52,7 +52,7 @@
     );
     return QuickFixBundle.message("fix.super.method.return.type.text",
                                   name,
-                                  HighlightUtil.formatType(mySuperMethodType));
+                                  JavaHighlightUtil.formatType(mySuperMethodType));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
index dad6f35..60e07b3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFix.java
@@ -24,6 +24,7 @@
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.util.TypeConversionUtil;
@@ -31,6 +32,8 @@
 import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
 import com.intellij.refactoring.changeSignature.JavaChangeSignatureDialog;
 import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import com.intellij.refactoring.util.RefactoringUIUtil;
+import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -53,6 +56,7 @@
   @Override
   public String getText() {
     return QuickFixBundle.message("fix.variable.type.text",
+                                  UsageViewUtil.getType(getStartElement()),
                                   myName,
                                   getReturnType().getCanonicalText());
   }
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
index 7fd7876..1b43c1b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
+++ b/java/java-impl/src/com/intellij/codeInsight/daemon/impl/quickfix/VariableTypeFromCallFix.java
@@ -33,6 +33,8 @@
 import com.intellij.refactoring.typeMigration.TypeMigrationLabeler;
 import com.intellij.refactoring.typeMigration.TypeMigrationProcessor;
 import com.intellij.refactoring.typeMigration.TypeMigrationRules;
+import com.intellij.usageView.UsageViewUtil;
+import com.intellij.usages.impl.UsageViewImpl;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
@@ -49,6 +51,7 @@
   @NotNull
   public String getText() {
     return QuickFixBundle.message("fix.variable.type.text",
+                                  UsageViewUtil.getType(myVar),
                                   myVar.getName(),
                                   myExpressionType.getCanonicalText());
   }
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
index 92b9c8a..85ea365 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/JavaCopyPasteReferenceProcessor.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * 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.
@@ -35,7 +35,7 @@
       if (!((PsiJavaCodeReferenceElement)element).isQualified()) {
         final JavaResolveResult resolveResult = ((PsiJavaCodeReferenceElement)element).advancedResolve(false);
         final PsiElement refElement = resolveResult.getElement();
-        if (refElement != null && refElement.getContainingFile() != file) {
+        if (refElement != null) {
 
           if (refElement instanceof PsiClass) {
             if (refElement.getContainingFile() != element.getContainingFile()) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
index 4983733..25a1c5c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/DeclarationMover.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.codeInsight.editorActions.moveUpDown;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
@@ -47,7 +47,7 @@
 
       try {
         PsiElement inserted = myEnumToInsertSemicolonAfter.getParent().addAfter(semicolon.getPsi(), myEnumToInsertSemicolonAfter);
-        inserted = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(inserted);
+        inserted = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(inserted);
         final LogicalPosition position = editor.offsetToLogicalPosition(inserted.getTextRange().getEndOffset());
 
         info.toMove2 = new LineRange(position.line + 1, position.line + 1);
diff --git a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
index 3d1983d..6b82868 100644
--- a/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
+++ b/java/java-impl/src/com/intellij/codeInsight/editorActions/moveUpDown/StatementMover.java
@@ -16,7 +16,7 @@
 package com.intellij.codeInsight.editorActions.moveUpDown;
 
 import com.intellij.codeInsight.CodeInsightUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.lang.StdLanguages;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
@@ -60,7 +60,7 @@
       final PsiBlockStatement blockStatement = (PsiBlockStatement)factory.createStatementFromText("{}", statementToSurroundWithCodeBlock);
       blockStatement.getCodeBlock().replace(codeBlock);
       PsiBlockStatement newStatement = (PsiBlockStatement)statementToSurroundWithCodeBlock.replace(blockStatement);
-      newStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(newStatement);
+      newStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(newStatement);
       info.toMove = new LineRange(document.getLineNumber(lineRangeMarker.getStartOffset()), document.getLineNumber(lineRangeMarker.getEndOffset())+1);
       PsiCodeBlock newCodeBlock = newStatement.getCodeBlock();
       if (down) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
index 2c91b12..25eec5f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/GenerateMembersUtil.java
@@ -28,7 +28,6 @@
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.*;
 import com.intellij.psi.impl.light.LightTypeElement;
-import com.intellij.psi.impl.source.tree.LeafElement;
 import com.intellij.psi.impl.source.tree.PsiWhiteSpaceImpl;
 import com.intellij.psi.javadoc.PsiDocComment;
 import com.intellij.psi.util.PsiTreeUtil;
@@ -263,10 +262,10 @@
       copyDocComment(sourceMethod, resultMethod);
       copyModifiers(sourceMethod.getModifierList(), resultMethod.getModifierList());
       final PsiSubstitutor collisionResolvedSubstitutor =
-        substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor);
+        substituteTypeParameters(factory, target, sourceMethod.getTypeParameterList(), resultMethod.getTypeParameterList(), substitutor, sourceMethod);
       substituteReturnType(PsiManager.getInstance(project), resultMethod, sourceMethod.getReturnType(), collisionResolvedSubstitutor);
       substituteParameters(factory, codeStyleManager, sourceMethod.getParameterList(), resultMethod.getParameterList(), collisionResolvedSubstitutor, target);
-      substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor);
+      substituteThrows(factory, sourceMethod.getThrowsList(), resultMethod.getThrowsList(), collisionResolvedSubstitutor, sourceMethod);
       return resultMethod;
     }
     catch (IncorrectOperationException e) {
@@ -285,14 +284,15 @@
                                                          @Nullable PsiElement target,
                                                          @Nullable PsiTypeParameterList sourceTypeParameterList,
                                                          @Nullable PsiTypeParameterList targetTypeParameterList,
-                                                         @NotNull PsiSubstitutor substitutor) {
+                                                         @NotNull PsiSubstitutor substitutor, 
+                                                         @NotNull PsiMethod sourceMethod) {
     if (sourceTypeParameterList == null || targetTypeParameterList == null) {
       return substitutor;
     }
 
     final Map<PsiTypeParameter, PsiType> substitutionMap = new HashMap<PsiTypeParameter, PsiType>(substitutor.getSubstitutionMap());
     for (PsiTypeParameter typeParam : sourceTypeParameterList.getTypeParameters()) {
-      final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor);
+      final PsiTypeParameter substitutedTypeParam = substituteTypeParameter(factory, typeParam, substitutor, sourceMethod);
 
       final PsiTypeParameter resolvedTypeParam = resolveTypeParametersCollision(factory, sourceTypeParameterList, target, substitutedTypeParam, substitutor);
       targetTypeParameterList.add(resolvedTypeParam);
@@ -347,7 +347,8 @@
   @NotNull
   private static PsiTypeParameter substituteTypeParameter(final @NotNull JVMElementFactory factory,
                                                           @NotNull PsiTypeParameter typeParameter,
-                                                          final @NotNull PsiSubstitutor substitutor) {
+                                                          final @NotNull PsiSubstitutor substitutor, 
+                                                          @NotNull final PsiMethod sourceMethod) {
     final PsiElement copy = typeParameter.copy();
     final Map<PsiElement, PsiElement> replacementMap = new HashMap<PsiElement, PsiElement>();
     copy.accept(new JavaRecursiveElementVisitor() {
@@ -357,7 +358,7 @@
         final PsiElement resolve = reference.resolve();
         if (resolve instanceof PsiTypeParameter) {
           final PsiType type = factory.createType((PsiTypeParameter)resolve);
-          replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type)));
+          replacementMap.put(reference, factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, type, sourceMethod)));
         }
       }
     });
@@ -374,7 +375,7 @@
     for (int i = 0; i < parameters.length; i++) {
       PsiParameter parameter = parameters[i];
       final PsiType parameterType = parameter.getType();
-      final PsiType substituted = substituteType(substitutor, parameterType);
+      final PsiType substituted = substituteType(substitutor, parameterType, (PsiMethod)parameter.getDeclarationScope());
       @NonNls String paramName = parameter.getName();
       boolean isBaseNameGenerated = true;
       final boolean isSubstituted = substituted.equals(parameterType);
@@ -400,17 +401,20 @@
   private static void substituteThrows(@NotNull JVMElementFactory factory,
                                        @NotNull PsiReferenceList sourceThrowsList,
                                        @NotNull PsiReferenceList targetThrowsList,
-                                       @NotNull PsiSubstitutor substitutor) {
+                                       @NotNull PsiSubstitutor substitutor, 
+                                       @NotNull PsiMethod sourceMethod) {
     for (PsiClassType thrownType : sourceThrowsList.getReferencedTypes()) {
-      targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType)));
+      targetThrowsList.add(factory.createReferenceElementByType((PsiClassType)substituteType(substitutor, thrownType, sourceMethod)));
     }
   }
 
   private static void copyDocComment(PsiMethod source, PsiMethod target) {
     final PsiElement navigationElement = source.getNavigationElement();
-    final PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment();
-    if (docComment != null) {
-      target.addAfter(docComment, null);
+    if (navigationElement instanceof PsiDocCommentOwner) {
+      final PsiDocComment docComment = ((PsiDocCommentOwner)navigationElement).getDocComment();
+      if (docComment != null) {
+        target.addAfter(docComment, null);
+      }
     }
   }
 
@@ -431,7 +435,7 @@
     if (returnTypeElement == null || returnType == null) {
       return;
     }
-    final PsiType substitutedReturnType = substituteType(substitutor, returnType);
+    final PsiType substitutedReturnType = substituteType(substitutor, returnType, method);
 
     returnTypeElement.replace(new LightTypeElement(manager, substitutedReturnType instanceof PsiWildcardType ? TypeConversionUtil.erasure(substitutedReturnType) : substitutedReturnType));
   }
@@ -449,7 +453,10 @@
     return Arrays.asList(csManager.suggestVariableName(VariableKind.PARAMETER, null, null, parameterType).names).contains(paramName);
   }
 
-  private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type) {
+  private static PsiType substituteType(final PsiSubstitutor substitutor, final PsiType type, @NotNull PsiTypeParameterListOwner owner) {
+    if (PsiUtil.isRawSubstitutor(owner, substitutor)) {
+      return TypeConversionUtil.erasure(type);
+    }
     final PsiType psiType = substitutor.substitute(type);
     if (psiType != null) {
       final PsiType deepComponentType = psiType.getDeepComponentType();
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java
new file mode 100644
index 0000000..3708b5e
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/JavaOverrideImplementMemberChooser.java
@@ -0,0 +1,224 @@
+package com.intellij.codeInsight.generation;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.MemberChooser;
+import com.intellij.ide.util.PropertiesComponent;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.keymap.KeymapManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.event.InputEvent;
+import java.awt.event.KeyEvent;
+import java.util.Arrays;
+import java.util.Collection;
+
+/**
+ * @author Dmitry Batkovich
+ */
+public class JavaOverrideImplementMemberChooser extends MemberChooser<PsiMethodMember> {
+  private static final String SORT_METHODS_BY_PERCENT_DESCRIPTION = "Sort by Percent of Classes which Overrides a Method";
+
+  @NonNls public static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
+  @NonNls public static final String PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT = "OverrideImplement.overriding.sorted";
+
+  private ToggleAction mySortByOverridingAction;
+  private ToggleAction myMergeAction;
+  private final PsiMethodMember[] myAllElements;
+  private final PsiMethodMember[] myOnlyPrimaryElements;
+  private final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> myLazyElementsWithPercent;
+  private final boolean myToImplement;
+  private Project myProject;
+  private boolean myMerge;
+  private boolean mySortedByOverriding;
+
+  @Nullable
+  public static JavaOverrideImplementMemberChooser create(final PsiElement aClass,
+                                                          final boolean toImplement,
+                                                          final Collection<CandidateInfo> candidates,
+                                                          final Collection<CandidateInfo> secondary) {
+    final Project project = aClass.getProject();
+    if (candidates.isEmpty() && secondary.isEmpty()) return null;
+
+    final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates);
+    final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary));
+    final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent =
+      new NotNullLazyValue<PsiMethodWithOverridingPercentMember[]>() {
+        @NotNull
+        @Override
+        protected PsiMethodWithOverridingPercentMember[] compute() {
+          final PsiMethodWithOverridingPercentMember[] elements =
+            PsiMethodWithOverridingPercentMember.calculateOverridingPercents(candidates);
+          Arrays.sort(elements, PsiMethodWithOverridingPercentMember.COMPARATOR);
+          return elements;
+        }
+      };
+    final boolean merge = PropertiesComponent.getInstance(project).getBoolean(PROP_COMBINED_OVERRIDE_IMPLEMENT, true);
+    final JavaOverrideImplementMemberChooser javaOverrideImplementMemberChooser =
+      new JavaOverrideImplementMemberChooser(all, onlyPrimary, lazyElementsWithPercent, project, PsiUtil.isLanguageLevel5OrHigher(aClass),
+                                             merge, toImplement, PropertiesComponent.getInstance(project)
+        .getBoolean(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, false));
+    javaOverrideImplementMemberChooser.setTitle(getChooserTitle(toImplement, merge));
+
+    javaOverrideImplementMemberChooser.setCopyJavadocVisible(true);
+
+    if (toImplement) {
+      javaOverrideImplementMemberChooser.selectElements(onlyPrimary);
+    }
+
+    if (ApplicationManager.getApplication().isUnitTestMode()) {
+      if (!toImplement || onlyPrimary.length == 0) {
+        javaOverrideImplementMemberChooser.selectElements(all);
+      }
+      javaOverrideImplementMemberChooser.close(DialogWrapper.OK_EXIT_CODE);
+      return javaOverrideImplementMemberChooser;
+    }
+    return javaOverrideImplementMemberChooser;
+  }
+
+  private JavaOverrideImplementMemberChooser(final PsiMethodMember[] allElements,
+                                             final PsiMethodMember[] onlyPrimaryElements,
+                                             final NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
+                                             final @NotNull Project project,
+                                             final boolean isInsertOverrideVisible,
+                                             final boolean merge,
+                                             final boolean toImplement,
+                                             final boolean sortedByOverriding) {
+    super(false, true, project, isInsertOverrideVisible, null, null);
+    myAllElements = allElements;
+    myOnlyPrimaryElements = onlyPrimaryElements;
+    myLazyElementsWithPercent = lazyElementsWithPercent;
+    myProject = project;
+    myMerge = merge;
+    myToImplement = toImplement;
+    mySortedByOverriding = sortedByOverriding;
+    resetElements(getInitialElements(allElements, onlyPrimaryElements, lazyElementsWithPercent, merge, toImplement, sortedByOverriding));
+    init();
+  }
+
+  private static PsiMethodMember[] getInitialElements(PsiMethodMember[] allElements,
+                                                      PsiMethodMember[] onlyPrimaryElements,
+                                                      NotNullLazyValue<PsiMethodWithOverridingPercentMember[]> lazyElementsWithPercent,
+                                                      boolean merge,
+                                                      boolean toImplement,
+                                                      boolean sortByOverriding) {
+    final boolean showElementsWithPercents = sortByOverriding && !toImplement;
+    final PsiMethodMember[] defaultElements = toImplement || merge ? allElements : onlyPrimaryElements;
+    return showElementsWithPercents ? lazyElementsWithPercent.getValue() : defaultElements;
+  }
+
+
+  @Override
+  protected void onAlphabeticalSortingEnabled(final AnActionEvent event) {
+    resetElements(myToImplement || myMerge ? myAllElements : myOnlyPrimaryElements, null, true);
+    if (mySortByOverridingAction != null) {
+      mySortByOverridingAction.setSelected(event, false);
+    }
+  }
+
+  @Override
+  protected void doOKAction() {
+    super.doOKAction();
+    PropertiesComponent.getInstance(myProject).setValue(PROP_COMBINED_OVERRIDE_IMPLEMENT, String.valueOf(myMerge));
+    PropertiesComponent.getInstance(myProject).setValue(PROP_OVERRIDING_SORTED_OVERRIDE_IMPLEMENT, String.valueOf(mySortedByOverriding));
+  }
+
+  @Override
+  protected void fillToolbarActions(DefaultActionGroup group) {
+    super.fillToolbarActions(group);
+    if (myToImplement) return;
+
+    mySortByOverridingAction = new MySortByOverridingAction();
+    if (mySortedByOverriding) {
+      changeSortComparator(PsiMethodWithOverridingPercentMember.COMPARATOR);
+    }
+    group.add(mySortByOverridingAction, Constraints.FIRST);
+
+    myMergeAction = new MyMergeAction();
+    group.add(myMergeAction);
+  }
+
+  private static String getChooserTitle(final boolean toImplement, final boolean merge) {
+    return toImplement
+           ? CodeInsightBundle.message("methods.to.implement.chooser.title")
+           : merge
+             ? CodeInsightBundle.message("methods.to.override.implement.chooser.title")
+             : CodeInsightBundle.message("methods.to.override.chooser.title");
+  }
+
+  private static PsiMethodMember[] convertToMethodMembers(Collection<CandidateInfo> candidates) {
+    return ContainerUtil.map2Array(candidates, PsiMethodMember.class, new Function<CandidateInfo, PsiMethodMember>() {
+      @Override
+      public PsiMethodMember fun(final CandidateInfo s) {
+        return new PsiMethodMember(s);
+      }
+    });
+  }
+
+  private class MySortByOverridingAction extends ToggleAction {
+    public MySortByOverridingAction() {
+      super(SORT_METHODS_BY_PERCENT_DESCRIPTION, SORT_METHODS_BY_PERCENT_DESCRIPTION, AllIcons.ObjectBrowser.SortedByUsage);
+      registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_U, InputEvent.ALT_MASK)), myTree);
+    }
+
+    @Override
+    public boolean isSelected(final AnActionEvent e) {
+      return mySortedByOverriding;
+    }
+
+    @Override
+    public void setSelected(final AnActionEvent e, final boolean state) {
+      mySortedByOverriding = state;
+      if (state) {
+        if (myMerge) {
+          myMergeAction.setSelected(e, false);
+        }
+        disableAlphabeticalSorting(e);
+        final PsiMethodWithOverridingPercentMember[] elementsWithPercent = myLazyElementsWithPercent.getValue();
+        resetElements(elementsWithPercent, PsiMethodWithOverridingPercentMember.COMPARATOR, false);
+      }
+      else {
+        final PsiMethodMember[] elementsToRender = myMerge ? myAllElements : myOnlyPrimaryElements;
+        resetElementsWithDefaultComparator(elementsToRender, true);
+      }
+    }
+  }
+
+  private class MyMergeAction extends ToggleAction {
+    private MyMergeAction() {
+      super("Show methods to implement", "Show methods to implement", AllIcons.General.Show_to_implement);
+      registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.ALT_MASK)), myTree);
+      final Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("OverrideMethods");
+      registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
+    }
+
+    @Override
+    public boolean isSelected(AnActionEvent e) {
+      return myMerge;
+    }
+
+    @Override
+    public void setSelected(AnActionEvent e, boolean state) {
+      myMerge = state;
+      if (state && mySortByOverridingAction.isSelected(e)) {
+        mySortByOverridingAction.setSelected(e, false);
+      }
+      resetElements(state ? myAllElements : myOnlyPrimaryElements, null, true);
+      setTitle(getChooserTitle(false, myMerge));
+    }
+  }
+
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
index 69205b4..68c3684 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/OverrideImplementUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * Copyright 0-2 JetBrains s.r.o.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
@@ -22,15 +22,14 @@
 import com.intellij.codeInsight.intention.AddAnnotationFix;
 import com.intellij.featureStatistics.FeatureUsageTracker;
 import com.intellij.featureStatistics.ProductivityFeatureNames;
-import com.intellij.icons.AllIcons;
 import com.intellij.ide.fileTemplates.FileTemplate;
 import com.intellij.ide.fileTemplates.FileTemplateManager;
 import com.intellij.ide.fileTemplates.FileTemplateUtil;
 import com.intellij.ide.fileTemplates.JavaTemplateUtil;
 import com.intellij.ide.util.MemberChooser;
-import com.intellij.ide.util.PropertiesComponent;
 import com.intellij.lang.java.JavaLanguage;
-import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.actionSystem.KeyboardShortcut;
+import com.intellij.openapi.actionSystem.Shortcut;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.Result;
 import com.intellij.openapi.command.WriteCommandAction;
@@ -49,8 +48,6 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.Ref;
-import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.CodeStyleSettingsManager;
@@ -61,7 +58,6 @@
 import com.intellij.psi.javadoc.PsiDocComment;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.*;
-import com.intellij.util.ArrayUtil;
 import com.intellij.util.Consumer;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
@@ -72,15 +68,11 @@
 
 import javax.swing.*;
 import java.awt.event.ActionEvent;
-import java.awt.event.InputEvent;
-import java.awt.event.KeyEvent;
 import java.util.*;
 
 public class OverrideImplementUtil extends OverrideImplementExploreUtil {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.OverrideImplementUtil");
 
-  @NonNls private static final String PROP_COMBINED_OVERRIDE_IMPLEMENT = "OverrideImplement.combined";
-
   private OverrideImplementUtil() { }
 
   protected static MethodImplementor[] getImplementors() {
@@ -223,7 +215,7 @@
     }
 
     annotateOnOverrideImplement(result, aClass, method, insertOverrideIfPossible);
-    
+
     if (CodeStyleSettingsManager.getSettings(aClass.getProject()).REPEAT_SYNCHRONIZED && method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
       result.getModifierList().setModifierProperty(PsiModifier.SYNCHRONIZED, true);
     }
@@ -379,7 +371,6 @@
       final PsiCodeBlock body = result.getBody();
       if (body != null) body.delete();
     }
-
     FileType fileType = FileTypeManager.getInstance().getFileTypeByExtension(template.getExtension());
     PsiType returnType = result.getReturnType();
     if (returnType == null) {
@@ -474,86 +465,29 @@
   public static MemberChooser<PsiMethodMember> showOverrideImplementChooser(Editor editor,
                                                                             final PsiElement aClass,
                                                                             final boolean toImplement,
-                                                                            Collection<CandidateInfo> candidates,
+                                                                            final Collection<CandidateInfo> candidates,
                                                                             Collection<CandidateInfo> secondary) {
+
+    final JavaOverrideImplementMemberChooser chooser =
+      JavaOverrideImplementMemberChooser.create(aClass, toImplement, candidates, secondary);
+    if (chooser == null) {
+      return null;
+    }
     Project project = aClass.getProject();
-    if (candidates.isEmpty() && secondary.isEmpty()) return null;
-
-    final PsiMethodMember[] onlyPrimary = convertToMethodMembers(candidates);
-    final PsiMethodMember[] all = ArrayUtil.mergeArrays(onlyPrimary, convertToMethodMembers(secondary));
-
-    final Ref<Boolean> merge = Ref.create(PropertiesComponent.getInstance(project).getBoolean(PROP_COMBINED_OVERRIDE_IMPLEMENT, true));
-    final MemberChooser<PsiMethodMember> chooser =
-      new MemberChooser<PsiMethodMember>(toImplement || merge.get() ? all : onlyPrimary, false, true, project, PsiUtil.isLanguageLevel5OrHigher(aClass)) {
-        @Override
-        protected void fillToolbarActions(DefaultActionGroup group) {
-          super.fillToolbarActions(group);
-          if (toImplement) return;
-
-          final ToggleAction mergeAction = new ToggleAction("Show methods to implement", "Show methods to implement",
-                                                            AllIcons.General.Show_to_implement) {
-            @Override
-            public boolean isSelected(AnActionEvent e) {
-              return merge.get().booleanValue();
-            }
-
-            @Override
-            public void setSelected(AnActionEvent e, boolean state) {
-              merge.set(state);
-              resetElements(state ? all : onlyPrimary);
-              setTitle(getChooserTitle(false, merge));
-            }
-          };
-          mergeAction.registerCustomShortcutSet(new CustomShortcutSet(KeyStroke.getKeyStroke(KeyEvent.VK_I, InputEvent.ALT_MASK)), myTree);
-
-          Shortcut[] shortcuts = KeymapManager.getInstance().getActiveKeymap().getShortcuts("OverrideMethods");
-          mergeAction.registerCustomShortcutSet(new CustomShortcutSet(shortcuts), myTree);
-
-          group.add(mergeAction);
-        }
-      };
-    chooser.setTitle(getChooserTitle(toImplement, merge));
     registerHandlerForComplementaryAction(project, editor, aClass, toImplement, chooser);
 
-    chooser.setCopyJavadocVisible(true);
-
-    if (toImplement) {
-      chooser.selectElements(onlyPrimary);
-    }
-
     if (ApplicationManager.getApplication().isUnitTestMode()) {
-      if (!toImplement || onlyPrimary.length == 0) {
-        chooser.selectElements(all);
-      }
-      chooser.close(DialogWrapper.OK_EXIT_CODE);
       return chooser;
     }
-
     chooser.show();
     if (chooser.getExitCode() != DialogWrapper.OK_EXIT_CODE) return null;
 
-    PropertiesComponent.getInstance(project).setValue(PROP_COMBINED_OVERRIDE_IMPLEMENT, merge.get().toString());
     return chooser;
   }
 
-  private static String getChooserTitle(boolean toImplement, Ref<Boolean> merge) {
-    return toImplement
-                     ? CodeInsightBundle.message("methods.to.implement.chooser.title")
-                     : merge.get().booleanValue()
-                       ? CodeInsightBundle.message("methods.to.override.implement.chooser.title")
-                       : CodeInsightBundle.message("methods.to.override.chooser.title");
-  }
-
-  private static PsiMethodMember[] convertToMethodMembers(Collection<CandidateInfo> candidates) {
-    return ContainerUtil.map2Array(candidates, PsiMethodMember.class, new Function<CandidateInfo, PsiMethodMember>() {
-        @Override
-        public PsiMethodMember fun(final CandidateInfo s) {
-          return new PsiMethodMember(s);
-        }
-      });
-  }
-
-  private static void registerHandlerForComplementaryAction(final Project project, final Editor editor, final PsiElement aClass,
+  private static void registerHandlerForComplementaryAction(final Project project,
+                                                            final Editor editor,
+                                                            final PsiElement aClass,
                                                             final boolean toImplement,
                                                             final MemberChooser<PsiMethodMember> chooser) {
     final JComponent preferredFocusedComponent = chooser.getPreferredFocusedComponent();
@@ -712,4 +646,4 @@
     boolean insert = CodeStyleSettingsManager.getSettings(aClass.getProject()).INSERT_OVERRIDE_ANNOTATION;
     return overrideOrImplementMethodCandidates(aClass, candidatesToImplement, copyJavadoc, insert);
   }
-}
+}
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java b/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java
new file mode 100644
index 0000000..1d57d32
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/PsiMethodWithOverridingPercentMember.java
@@ -0,0 +1,157 @@
+package com.intellij.codeInsight.generation;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PsiExtensibleClass;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.psi.search.searches.ClassInheritorsSearch;
+import com.intellij.ui.SimpleColoredComponent;
+import com.intellij.ui.SimpleTextAttributes;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.TestOnly;
+
+import javax.swing.*;
+import java.util.*;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+public class PsiMethodWithOverridingPercentMember extends PsiMethodMember {
+
+  private final int myOverridingPercent;
+
+  public PsiMethodWithOverridingPercentMember(final CandidateInfo info, final int overridingPercent) {
+    super(info);
+    myOverridingPercent = overridingPercent;
+  }
+
+  @Override
+  public void renderTreeNode(final SimpleColoredComponent component, final JTree tree) {
+    component.append(myOverridingPercent + "% ", SimpleTextAttributes.GRAY_ATTRIBUTES);
+    super.renderTreeNode(component, tree);
+  }
+
+  @TestOnly
+  public int getOverridingPercent() {
+    return myOverridingPercent;
+  }
+
+  public static final Comparator<PsiMethodMember> COMPARATOR = new Comparator<PsiMethodMember>() {
+    @Override
+    public int compare(PsiMethodMember e1, PsiMethodMember e2) {
+      if (!(e1 instanceof PsiMethodWithOverridingPercentMember)) {
+        if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
+          return e1.equals(e2) ? 0 : -1;
+        } else {
+          return -1;
+        }
+      }
+
+
+      if (!(e2 instanceof PsiMethodWithOverridingPercentMember)) {
+        return 1;
+      }
+      int sub =
+        ((PsiMethodWithOverridingPercentMember)e2).myOverridingPercent - ((PsiMethodWithOverridingPercentMember)e1).myOverridingPercent;
+      if (sub != 0) return sub;
+      return String.CASE_INSENSITIVE_ORDER.compare(e1.getText(), e2.getText());
+    }
+  };
+
+  @NotNull
+  public static PsiMethodWithOverridingPercentMember[] calculateOverridingPercents(@NotNull final Collection<CandidateInfo> candidateInfos) {
+    final List<PsiMethodWithOverridingPercentMember> result = new ArrayList<PsiMethodWithOverridingPercentMember>(candidateInfos.size());
+    final Map<String, Collection<PsiClass>> classShortNames2Inheritors = new HashMap<String, Collection<PsiClass>>();
+    for (final CandidateInfo candidateInfo : candidateInfos) {
+      final PsiMethod method = (PsiMethod)candidateInfo.getElement();
+      if (!method.hasModifierProperty(PsiModifier.FINAL) &&
+          !method.isConstructor() &&
+          !method.isDeprecated() &&
+          !EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES.contains(method.getName())) {
+        final PsiClass containingClass = method.getContainingClass();
+        if (containingClass == null) {
+          continue;
+        }
+
+        final String classShortName = containingClass.getName();
+
+        Collection<PsiClass> allInheritors = classShortNames2Inheritors.get(classShortName);
+        if (allInheritors == null) {
+          allInheritors = ClassInheritorsSearch.search(containingClass, true).findAll();
+          classShortNames2Inheritors.put(classShortName, allInheritors);
+        }
+
+        final int allInheritorsCount = allInheritors.size() - 1;
+        if (allInheritorsCount > 0) {
+          final int percent = searchForOverridingCount(method, allInheritors) * 100 / allInheritorsCount;
+          if (percent > 1) {
+            result.add(new PsiMethodWithOverridingPercentMember(candidateInfo, percent));
+          }
+        }
+      }
+    }
+    return result.toArray(new PsiMethodWithOverridingPercentMember[result.size()]);
+  }
+
+  private static int searchForOverridingCount(final PsiMethod method, final Collection<PsiClass> containingClassInheritors) {
+    int counter = 0;
+    for (final PsiClass inheritor : containingClassInheritors) {
+      if (inheritor instanceof PsiExtensibleClass) {
+        final List<PsiMethod> ownMethods = ((PsiExtensibleClass)inheritor).getOwnMethods();
+        for (PsiMethod ownMethod : ownMethods) {
+          if (maybeSuper(method, ownMethod)) {
+            counter++;
+            break;
+          }
+        }
+
+      }
+    }
+    return counter;
+  }
+
+  private static boolean maybeSuper(@NotNull final PsiMethod superMethod, @NotNull final PsiMethod method) {
+    if (!superMethod.getName().equals(method.getName())) {
+      return false;
+    }
+    final PsiParameterList superMethodParameterList = superMethod.getParameterList();
+    final PsiParameterList methodParameterList = method.getParameterList();
+    if (superMethodParameterList.getParametersCount() != methodParameterList.getParametersCount()) {
+      return false;
+    }
+    final PsiParameter[] superMethodParameters = superMethodParameterList.getParameters();
+    final PsiParameter[] methodParameters = methodParameterList.getParameters();
+    for (int i = 0; i < methodParameters.length; i++) {
+      if (!StringUtil.equals(getTypeShortName(superMethodParameters[i].getType()), getTypeShortName(methodParameters[i].getType()))) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+  @Nullable
+  private static String getTypeShortName(@NotNull final PsiType type) {
+    if (type instanceof PsiPrimitiveType) {
+      return ((PsiPrimitiveType)type).getBoxedTypeName();
+    }
+    if (type instanceof PsiClassType) {
+      return ((PsiClassType)type).getClassName();
+    }
+    if (type instanceof PsiArrayType) {
+      return getTypeShortName(((PsiArrayType)type).getComponentType()) + "[]";
+    }
+    return null;
+  }
+
+  private static final Set<String> EXCLUDED_JAVA_LANG_OBJECT_METHOD_NAMES =
+    ContainerUtil.newHashSet("hashCode", "finalize", "clone", "equals", "toString");
+
+  @Override
+  public String toString() {
+    return "PsiMethodWithOverridingPercentMember{" +
+           "myOverridingPercent=" + myOverridingPercent + ", myElement=" + getElement() +
+           '}';
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
index baa5638..81a98e9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/actions/GenerateSuperMethodCallHandler.java
@@ -21,6 +21,7 @@
 
 import com.intellij.codeInsight.CodeInsightActionHandler;
 import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.generation.OverrideImplementUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.editor.Editor;
@@ -53,7 +54,7 @@
       else {
         toGo = body.addAfter(superCall, body.getLBrace());
       }
-      toGo = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(toGo);
+      toGo = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(toGo);
       editor.getCaretModel().moveToOffset(toGo.getTextOffset());
       editor.getScrollingModel().scrollToCaret(ScrollType.RELATIVE);
     }
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
index 1055c46..e03e6c3 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithForSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -58,13 +58,13 @@
     bodyBlock.addRange(statements[0], statements[statements.length - 1]);
     container.deleteChildRange(statements[0], statements[statements.length - 1]);
 
-    forStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(forStatement);
+    forStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(forStatement);
     PsiStatement initialization = forStatement.getInitialization();
     if (initialization == null) {
       return null;
     }
     TextRange range1 = initialization.getTextRange();
-    
+
     PsiStatement update = forStatement.getUpdate();
     if (update == null) {
       return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
index f789f8ef..a753fc6 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseExpressionSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -45,8 +45,8 @@
 
     PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
 
-    PsiStatement afterStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block.getStatements()[0]);
-    
+    PsiStatement afterStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block.getStatements()[0]);
+
     TextRange range = afterStatement.getTextRange();
     editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
     return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
index 7c977e4..4ce38c1 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfElseSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
     SurroundWithUtil.indentCommentIfNecessary(thenBlock, statements);
     thenBlock.addRange(statements[0], statements[statements.length - 1]);
     container.deleteChildRange(statements[0], statements[statements.length - 1]);
-    ifStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifStatement);
+    ifStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(ifStatement);
     PsiExpression condition = ifStatement.getCondition();
     if (condition == null) {
       return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
index a52d0bb..0c492c9 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfExpressionSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -55,7 +55,7 @@
     ifStatement = (PsiIfStatement)statement.replace(ifStatement);
 
     PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
-    block = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block);
+    block = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block);
     TextRange range = block.getStatements()[0].getTextRange();
     editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
     return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
index 8e8454e..01d9840 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithIfSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
       container.deleteChildRange(statements[0], statements[statements.length - 1]);
     }
 
-    ifStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(ifStatement);
+    ifStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(ifStatement);
     if (ifStatement == null) {
       return null;
     }
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
index 8ea3c4d..cec501f 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNotInstanceofSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -48,7 +48,7 @@
     prefixExpr = (PsiPrefixExpression)expr.replace(prefixExpr);
     parenthExpr = (PsiParenthesizedExpression)prefixExpr.getOperand();
     instanceofExpr = (PsiInstanceOfExpression)parenthExpr.getExpression();
-    instanceofExpr = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(instanceofExpr);
+    instanceofExpr = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(instanceofExpr);
     TextRange range = instanceofExpr.getCheckType().getTextRange();
     editor.getDocument().deleteString(range.getStartOffset(), range.getEndOffset());
     return new TextRange(range.getStartOffset(), range.getStartOffset());
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
index 612c655..aa258ab 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithNullCheckSurrounder.java
@@ -16,7 +16,7 @@
  */
 package com.intellij.codeInsight.generation.surroundWith;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -56,7 +56,7 @@
     String oldText = statement.getText();
     ifStatement = (PsiIfStatement)statement.replace(ifStatement);
     PsiCodeBlock block = ((PsiBlockStatement)ifStatement.getThenBranch()).getCodeBlock();
-    block = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(block);
+    block = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(block);
     PsiElement replace = block.getStatements()[0].replace(factory.createStatementFromText(oldText, block));
     int offset = replace.getTextRange().getEndOffset();
     return new TextRange(offset, offset);
diff --git a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
index 1e2754c..a19980d 100644
--- a/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
+++ b/java/java-impl/src/com/intellij/codeInsight/generation/surroundWith/JavaWithSynchronizedSurrounder.java
@@ -17,7 +17,7 @@
 package com.intellij.codeInsight.generation.surroundWith;
 
 import com.intellij.codeInsight.CodeInsightBundle;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.TextRange;
@@ -57,7 +57,7 @@
     synchronizedBlock.addRange(statements[0], statements[statements.length - 1]);
     container.deleteChildRange(statements[0], statements[statements.length - 1]);
 
-    synchronizedStatement = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(synchronizedStatement);
+    synchronizedStatement = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(synchronizedStatement);
     PsiExpression lockExpression = synchronizedStatement.getLockExpression();
     if (lockExpression == null) {
       return null;
diff --git a/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
new file mode 100644
index 0000000..8a8bc91
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/hint/actions/ShowSiblingsAction.java
@@ -0,0 +1,114 @@
+/*
+ * 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.codeInsight.hint.actions;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.codeInsight.daemon.impl.PsiElementListNavigator;
+import com.intellij.codeInsight.documentation.DocumentationManager;
+import com.intellij.ide.util.MethodCellRenderer;
+import com.intellij.ide.util.PsiClassListCellRenderer;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.fileEditor.FileEditor;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.popup.JBPopup;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.FindSuperElementsHelper;
+import com.intellij.psi.presentation.java.SymbolPresentationUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.Consumer;
+import org.jetbrains.annotations.Nullable;
+
+public class ShowSiblingsAction extends ShowImplementationsAction {
+  private static final Logger LOG = Logger.getInstance("#" + ShowSiblingsAction.class.getName());
+
+  public ShowSiblingsAction() {
+    super();
+  }
+
+  @Override
+  public void performForContext(DataContext dataContext, final boolean invokedByShortcut) {
+    final Project project = PlatformDataKeys.PROJECT.getData(dataContext);
+    final PsiFile file = LangDataKeys.PSI_FILE.getData(dataContext);
+
+    if (project == null) return;
+
+    PsiDocumentManager.getInstance(project).commitAllDocuments();
+    final Editor editor = getEditor(dataContext);
+
+    PsiElement element = getElement(project, file, editor, LangDataKeys.PSI_ELEMENT.getData(dataContext));
+
+    if (element == null && file == null) return;
+    PsiFile containingFile = element != null ? element.getContainingFile() : file;
+    if (containingFile == null || !containingFile.getViewProvider().isPhysical()) return;
+
+
+    if (editor != null) {
+      PsiReference ref = TargetElementUtilBase.findReference(editor, editor.getCaretModel().getOffset());
+      if (element == null && ref != null) {
+        element = TargetElementUtilBase.getInstance().adjustReference(ref);
+      }
+    }
+
+    final NavigatablePsiElement[] superElements = (NavigatablePsiElement[])findSuperElements(element);
+    if (superElements == null || superElements.length == 0) return;
+
+    final boolean isMethod = superElements[0] instanceof PsiMethod;
+    final JBPopup popup = PsiElementListNavigator.navigateOrCreatePopup(superElements, "Choose super " + (isMethod ? "method" : "class or interface"), "Super " + (isMethod ? "methods" : "classes/interfaces"),
+                                                                       isMethod ? new MethodCellRenderer(false) : new PsiClassListCellRenderer(), null, new Consumer<Object[]>() {
+      @Override
+      public void consume(Object[] objects) {
+        showSiblings(invokedByShortcut, project, editor, file, editor != null, (PsiElement)objects[0]);
+      }
+    });
+    if (popup != null) {
+      if (editor != null) {
+        popup.showInBestPositionFor(editor);
+      } else {
+        popup.showCenteredInCurrentWindow(project);
+      }
+    }
+  }
+
+  private void showSiblings(boolean invokedByShortcut,
+                            Project project,
+                            Editor editor,
+                            PsiFile file,
+                            boolean invokedFromEditor,
+                            PsiElement element) {
+    final PsiElement[] impls = getSelfAndImplementations(editor, element, createImplementationsSearcher(), false);
+    final String text = SymbolPresentationUtil.getSymbolPresentableText(element);
+    showImplementations(impls, project, text, editor, file, element, invokedFromEditor, invokedByShortcut);
+  }
+
+  @Override
+  protected boolean isIncludeAlwaysSelf() {
+    return false;
+  }
+
+  @Nullable
+  private static PsiElement[] findSuperElements(final PsiElement element) {
+    PsiNameIdentifierOwner parent = PsiTreeUtil.getParentOfType(element, PsiMethod.class, PsiClass.class);
+    if (parent == null) {
+      return null;
+    }
+
+    return FindSuperElementsHelper.findSuperElements(parent);
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
index 3cb7547..63df5bf 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/ConvertAbsolutePathToRelativeIntentionAction.java
@@ -24,6 +24,7 @@
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceOwner;
 import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
+import com.intellij.psi.impl.source.resolve.reference.impl.providers.PsiFileReference;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -64,9 +65,9 @@
       }
     }
     else if (original instanceof FileReferenceOwner) {
-      final FileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
-      if (fileReference != null) {
-        return fileReference;
+      final PsiFileReference fileReference = ((FileReferenceOwner)original).getLastFileReference();
+      if (fileReference instanceof FileReference) {
+        return (FileReference)fileReference;
       }
     }
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
index 8b98816..3ae3ddc 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/SimplifyBooleanExpressionAction.java
@@ -39,7 +39,7 @@
   @Override
   @NotNull
   public String getFamilyName() {
-    return new SimplifyBooleanExpressionFix(null,null).getFamilyName();
+    return SimplifyBooleanExpressionFix.FAMILY_NAME;
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
index 124636c..c55a21b 100644
--- a/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
+++ b/java/java-impl/src/com/intellij/codeInsight/intention/impl/config/QuickFixFactoryImpl.java
@@ -21,6 +21,7 @@
 import com.intellij.codeInsight.intention.IntentionAction;
 import com.intellij.codeInsight.intention.QuickFixFactory;
 import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PropertyMemberType;
 import com.intellij.psi.util.ClassKind;
@@ -77,10 +78,10 @@
   }
 
   @Override
-  public LocalQuickFixAndIntentionActionOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method,
-                                                                           @NotNull PsiClassType exceptionClass,
-                                                                           boolean shouldThrow,
-                                                                           boolean showContainingClass) {
+  public LocalQuickFixOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method,
+                                                         @NotNull PsiClassType exceptionClass,
+                                                         boolean shouldThrow,
+                                                         boolean showContainingClass) {
     return new MethodThrowsFix(method, exceptionClass, shouldThrow, showContainingClass);
   }
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
index e93cd0d..9e89d7a 100644
--- a/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
+++ b/java/java-impl/src/com/intellij/codeInsight/lookup/PsiTypeLookupItem.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -225,7 +225,7 @@
           if (!psiClass.getManager().areElementsEquivalent(resolved, psiClass) && !PsiUtil.isInnerClass(psiClass)) {
             // inner class name should be shown qualified if its not accessible by single name
             PsiClass aClass = psiClass.getContainingClass();
-            while (aClass != null && !PsiUtil.isInnerClass(aClass)) {
+            while (aClass != null && !PsiUtil.isInnerClass(aClass) && aClass.getName() != null) {
               name = aClass.getName() + '.' + name;
               allStrings.add(name);
               aClass = aClass.getContainingClass();
@@ -275,6 +275,9 @@
 
       presentation.setItemText(((PsiType)object).getCanonicalText());
       presentation.setItemTextBold(getAttribute(LookupItem.HIGHLIGHTED_ATTR) != null || object instanceof PsiPrimitiveType);
+      if (isAddArrayInitializer()) {
+        presentation.setTailText("{...}");
+      }
 
     }
     if (myBracketsCount > 0) {
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.java
new file mode 100644
index 0000000..59dec48
--- /dev/null
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaArrayInitializerUnwrapper.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.intellij.codeInsight.unwrap;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.psi.PsiArrayInitializerExpression;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiNewExpression;
+import com.intellij.psi.PsiVariable;
+import com.intellij.util.IncorrectOperationException;
+
+public class JavaArrayInitializerUnwrapper extends JavaUnwrapper {
+
+  public JavaArrayInitializerUnwrapper() {
+    super(CodeInsightBundle.message("unwrap.array.initializer"));
+  }
+
+  @Override
+  public boolean isApplicableTo(PsiElement e) {
+    if (e instanceof PsiArrayInitializerExpression) {
+      final PsiElement gParent = e.getParent();
+      if (gParent instanceof PsiNewExpression && gParent.getParent() instanceof PsiVariable) {
+        return true;
+      }
+    }
+
+    return false;
+  }
+
+  @Override
+  protected void doUnwrap(PsiElement element, Context context) throws IncorrectOperationException {
+    final PsiArrayInitializerExpression arrayInitializerExpression = (PsiArrayInitializerExpression)element;
+    final PsiElement newExpression = arrayInitializerExpression.getParent();
+    context.extractElement(arrayInitializerExpression, newExpression);
+    context.deleteExactly(newExpression);
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
index e69505e..deda060 100644
--- a/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
+++ b/java/java-impl/src/com/intellij/codeInsight/unwrap/JavaUnwrapDescriptor.java
@@ -22,6 +22,7 @@
   @Override
   protected Unwrapper[] createUnwrappers() {
     return new Unwrapper[]{
+      new JavaArrayInitializerUnwrapper(),
       new JavaMethodParameterUnwrapper(),
       new JavaElseUnwrapper(),
       new JavaElseRemover(),
diff --git a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
index 983c4fa..3fd32c3 100644
--- a/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/MoveToPackageFix.java
@@ -99,10 +99,4 @@
       LOG.error(e);
     }
   }
-
-  public boolean startInWriteAction() {
-    return false;
-  }
-
-
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java b/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
index 72aaf61..3bdbc7c 100644
--- a/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/SurroundWithIfFix.java
@@ -60,7 +60,7 @@
     if (!FileModificationService.getInstance().prepareFileForWrite(file)) return;
     PsiElement[] elements = {anchorStatement};
     PsiElement prev = PsiTreeUtil.skipSiblingsBackward(anchorStatement, PsiWhiteSpace.class);
-    if (prev instanceof PsiComment && SuppressManager.getInstance().getSuppressedInspectionIdsIn(prev) != null) {
+    if (prev instanceof PsiComment && JavaSuppressionUtil.getSuppressedInspectionIdsIn(prev) != null) {
       elements = new PsiElement[]{prev, anchorStatement};
     }
     try {
diff --git a/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java b/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
index 26afc96..46994c9 100644
--- a/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
+++ b/java/java-impl/src/com/intellij/codeInspection/accessStaticViaInstance/AccessStaticViaInstance.java
@@ -15,92 +15,19 @@
  */
 package com.intellij.codeInspection.accessStaticViaInstance;
 
-import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightMessageUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
 import com.intellij.codeInsight.daemon.impl.quickfix.AccessStaticViaInstanceFix;
-import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
-import com.intellij.codeInspection.BaseJavaLocalInspectionTool;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.ProblemsHolder;
-import com.intellij.psi.*;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-
-import java.util.ArrayList;
+import com.intellij.psi.JavaResolveResult;
+import com.intellij.psi.PsiReferenceExpression;
 
 /**
  * User: anna
  * Date: 15-Nov-2005
  */
-public class AccessStaticViaInstance extends BaseJavaLocalInspectionTool {
-
-  public static final String ACCESS_STATIC_VIA_INSTANCE = "AccessStaticViaInstance";
-
+public class AccessStaticViaInstance extends AccessStaticViaInstanceBase {
   @Override
-  @NotNull
-  public String getGroupDisplayName() {
-    return "";
-  }
-
-  @Override
-  @NotNull
-  public String getDisplayName() {
-    return InspectionsBundle.message("access.static.via.instance");
-  }
-
-  @Override
-  @NotNull
-  @NonNls
-  public String getShortName() {
-    return ACCESS_STATIC_VIA_INSTANCE;
-  }
-
-  @Override
-  public String getAlternativeID() {
-    return "static-access";
-  }
-
-  @Override
-  public boolean isEnabledByDefault() {
-    return true;
-  }
-
-  @Override
-  @NotNull
-  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
-    return new JavaElementVisitor() {
-      @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
-        checkAccessStaticMemberViaInstanceReference(expression, holder, isOnTheFly);
-      }
-    };
-  }
-
-  private static void checkAccessStaticMemberViaInstanceReference(PsiReferenceExpression expr, ProblemsHolder holder, boolean onTheFly) {
-    JavaResolveResult result = expr.advancedResolve(false);
-    PsiElement resolved = result.getElement();
-
-    if (!(resolved instanceof PsiMember)) return;
-    PsiExpression qualifierExpression = expr.getQualifierExpression();
-    if (qualifierExpression == null) return;
-
-    if (qualifierExpression instanceof PsiReferenceExpression) {
-      final PsiElement qualifierResolved = ((PsiReferenceExpression)qualifierExpression).resolve();
-      if (qualifierResolved instanceof PsiClass || qualifierResolved instanceof PsiPackage) {
-        return;
-      }
-    }
-    if (!((PsiMember)resolved).hasModifierProperty(PsiModifier.STATIC)) return;
-
-    String description = JavaErrorMessages.message("static.member.accessed.via.instance.reference",
-                                                   HighlightUtil.formatType(qualifierExpression.getType()),
-                                                   HighlightMessageUtil.getSymbolName(resolved, result.getSubstitutor()));
-    if (!onTheFly) {
-      if (RemoveUnusedVariableFix.checkSideEffects(qualifierExpression, null, new ArrayList<PsiElement>())) {
-        holder.registerProblem(expr, description);
-        return;
-      }
-    }
-    holder.registerProblem(expr, description, new AccessStaticViaInstanceFix(expr, result, onTheFly));
+  protected AccessStaticViaInstanceFix createAccessStaticViaInstanceFix(PsiReferenceExpression expr,
+                                                                        boolean onTheFly,
+                                                                        JavaResolveResult result) {
+    return new AccessStaticViaInstanceFix(expr, result, onTheFly);
   }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
index 4e05e24..3363d94 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/ConditionCheckDialog.java
@@ -46,13 +46,13 @@
  */
 public class ConditionCheckDialog extends DialogWrapper {
   private final Project myProject;
-  private final @NotNull Splitter mainSplitter;
-  private final @NotNull MethodsPanel myIsNullCheckMethodPanel;
-  private final @NotNull MethodsPanel myIsNotNullCheckMethodPanel;
-  private final @NotNull MethodsPanel myAssertIsNullMethodPanel;
-  private final @NotNull MethodsPanel myAssertIsNotNullMethodPanel;
-  private final @NotNull MethodsPanel myAssertTrueMethodPanel;
-  private final @NotNull MethodsPanel myAssertFalseMethodPanel;
+  @NotNull private final Splitter mainSplitter;
+  @NotNull private final MethodsPanel myIsNullCheckMethodPanel;
+  @NotNull private final MethodsPanel myIsNotNullCheckMethodPanel;
+  @NotNull private final MethodsPanel myAssertIsNullMethodPanel;
+  @NotNull private final MethodsPanel myAssertIsNotNullMethodPanel;
+  @NotNull private final MethodsPanel myAssertTrueMethodPanel;
+  @NotNull private final MethodsPanel myAssertFalseMethodPanel;
 
   public ConditionCheckDialog(Project project, String mainDialogTitle) {
     super(project, true);
@@ -140,12 +140,12 @@
    * Is Null, Is Not Null, Assert True and Assert False Method Panel at the top of the main Dialog.
    */
   class MethodsPanel {
-    private final @NotNull JBList myList;
-    private final @NotNull JPanel myPanel;
-    private final @NotNull Project myProject;
+    @NotNull private final JBList myList;
+    @NotNull private final JPanel myPanel;
+    @NotNull private final Project myProject;
     private Set<MethodsPanel> otherPanels;
 
-    public MethodsPanel(final List<ConditionChecker> checkers, final ConditionChecker.Type type, final @NotNull Project myProject) {
+    public MethodsPanel(final List<ConditionChecker> checkers, final ConditionChecker.Type type, @NotNull final Project myProject) {
       this.myProject = myProject;
       myList = new JBList(new CollectionListModel<ConditionChecker>(checkers));
       myPanel = new JPanel(new BorderLayout());
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
index c4b90e7..348d3df 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DataFlowInspection.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -13,43 +13,17 @@
  * See the License for the specific language governing permissions and
  * limitations under the License.
  */
-
-/*
- * Created by IntelliJ IDEA.
- * User: max
- * Date: Dec 24, 2001
- * Time: 2:46:32 PM
- * To change template for new class use
- * Code Style | Class Templates options (Tools | IDE Options).
- */
 package com.intellij.codeInspection.dataFlow;
 
-import com.intellij.codeInsight.AnnotationUtil;
-import com.intellij.codeInsight.FileModificationService;
 import com.intellij.codeInsight.NullableNotNullDialog;
-import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.daemon.impl.quickfix.SimplifyBooleanExpressionFix;
-import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.dataFlow.instructions.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.SurroundWithIfFix;
 import com.intellij.ide.DataManager;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.util.Pair;
-import com.intellij.pom.java.LanguageLevel;
-import com.intellij.psi.*;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.SmartList;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import com.intellij.psi.PsiExpression;
 
 import javax.swing.*;
 import javax.swing.event.ChangeEvent;
@@ -57,497 +31,20 @@
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.*;
 import java.util.List;
 
-public class DataFlowInspection extends BaseLocalInspectionTool {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.dataFlow.DataFlowInspection");
-  @NonNls private static final String SHORT_NAME = "ConstantConditions";
-  public boolean SUGGEST_NULLABLE_ANNOTATIONS = false;
-  public boolean DONT_REPORT_TRUE_ASSERT_STATEMENTS = false;
-
+public class DataFlowInspection extends DataFlowInspectionBase {
+  @Override
+  protected void addSurroundWithIfFix(PsiExpression qualifier, List<LocalQuickFix> fixes) {
+    if (SurroundWithIfFix.isAvailable(qualifier)) {
+      fixes.add(new SurroundWithIfFix(qualifier));
+    }
+  }
   @Override
   public JComponent createOptionsPanel() {
     return new OptionsPanel();
   }
 
-  @Override
-  @NotNull
-  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
-    return new JavaElementVisitor() {
-      @Override
-      public void visitField(PsiField field) {
-        analyzeCodeBlock(field, holder);
-      }
-
-      @Override
-      public void visitMethod(PsiMethod method) {
-        analyzeCodeBlock(method.getBody(), holder);
-      }
-
-      @Override
-      public void visitClassInitializer(PsiClassInitializer initializer) {
-        analyzeCodeBlock(initializer.getBody(), holder);
-      }
-    };
-  }
-
-  private void analyzeCodeBlock(@Nullable final PsiElement scope, ProblemsHolder holder) {
-    if (scope == null) return;
-    final StandardDataFlowRunner dfaRunner = new StandardDataFlowRunner(SUGGEST_NULLABLE_ANNOTATIONS);
-    final StandardInstructionVisitor visitor = new DataFlowInstructionVisitor(dfaRunner);
-    final RunnerResult rc = dfaRunner.analyzeMethod(scope, visitor);
-    if (rc == RunnerResult.OK) {
-      if (dfaRunner.problemsDetected(visitor)) {
-        createDescription(dfaRunner, holder, visitor);
-      }
-    }
-    else if (rc == RunnerResult.TOO_COMPLEX) {
-      if (scope.getParent() instanceof PsiMethod) {
-        PsiMethod method = (PsiMethod)scope.getParent();
-        final PsiIdentifier name = method.getNameIdentifier();
-        if (name != null) { // Might be null for synthetic methods like JSP page.
-          holder.registerProblem(name, InspectionsBundle.message("dataflow.too.complex"), ProblemHighlightType.WEAK_WARNING);
-        }
-      }
-    }
-  }
-
-  @Nullable
-  private static LocalQuickFix[] createNPEFixes(PsiExpression qualifier, PsiExpression expression) {
-    if (qualifier == null || expression == null) return null;
-    if (qualifier instanceof PsiMethodCallExpression) return null;
-    if (qualifier instanceof PsiLiteralExpression && ((PsiLiteralExpression)qualifier).getValue() == null) return null;
-
-    try {
-      final List<LocalQuickFix> fixes = new SmartList<LocalQuickFix>();
-
-      if (PsiUtil.getLanguageLevel(qualifier).isAtLeast(LanguageLevel.JDK_1_4)) {
-        final Project project = qualifier.getProject();
-        final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(project).getElementFactory();
-        final PsiBinaryExpression binary = (PsiBinaryExpression)elementFactory.createExpressionFromText("a != null", null);
-        binary.getLOperand().replace(qualifier);
-        fixes.add(new AddAssertStatementFix(binary));
-      }
-
-      if (SurroundWithIfFix.isAvailable(qualifier)) {
-        fixes.add(new SurroundWithIfFix(qualifier));
-      }
-      if (ReplaceWithTernaryOperatorFix.isAvailable(qualifier, expression)) {
-        fixes.add(new ReplaceWithTernaryOperatorFix(qualifier));
-      }
-      return fixes.toArray(new LocalQuickFix[fixes.size()]);
-    }
-    catch (IncorrectOperationException e) {
-      LOG.error(e);
-      return null;
-    }
-  }
-
-  private void createDescription(StandardDataFlowRunner runner, ProblemsHolder holder, StandardInstructionVisitor visitor) {
-    Pair<Set<Instruction>, Set<Instruction>> constConditions = runner.getConstConditionalExpressions();
-    Set<Instruction> trueSet = constConditions.getFirst();
-    Set<Instruction> falseSet = constConditions.getSecond();
-
-    ArrayList<Instruction> allProblems = new ArrayList<Instruction>();
-    allProblems.addAll(trueSet);
-    allProblems.addAll(falseSet);
-    allProblems.addAll(runner.getNPEInstructions());
-    allProblems.addAll(runner.getCCEInstructions());
-    allProblems.addAll(StandardDataFlowRunner.getRedundantInstanceofs(runner, visitor));
-
-    Collections.sort(allProblems, new Comparator<Instruction>() {
-      @Override
-      public int compare(Instruction i1, Instruction i2) {
-        return i1.getIndex() - i2.getIndex();
-      }
-    });
-
-    HashSet<PsiElement> reportedAnchors = new HashSet<PsiElement>();
-
-    for (Instruction instruction : allProblems) {
-      if (instruction instanceof MethodCallInstruction) {
-        reportCallMayProduceNpe(holder, (MethodCallInstruction)instruction);
-      }
-      else if (instruction instanceof FieldReferenceInstruction) {
-        reportFieldAccessMayProduceNpe(holder, (FieldReferenceInstruction)instruction);
-      }
-      else if (instruction instanceof TypeCastInstruction) {
-        reportCastMayFail(holder, (TypeCastInstruction)instruction);
-      }
-      else if (instruction instanceof BranchingInstruction) {
-        handleBranchingInstruction(holder, visitor, trueSet, falseSet, reportedAnchors, (BranchingInstruction)instruction);
-      }
-    }
-
-    reportNullableArguments(runner, holder);
-    reportNullableAssignments(runner, holder);
-    reportUnboxedNullables(runner, holder);
-    reportNullableReturns(runner, holder);
-    reportNullableArgumentsPassedToNonAnnotated(runner, holder);
-  }
-
-  private static void reportNullableArgumentsPassedToNonAnnotated(StandardDataFlowRunner runner, ProblemsHolder holder) {
-    Set<PsiExpression> exprs = runner.getNullableArgumentsPassedToNonAnnotatedParam();
-    for (PsiExpression expr : exprs) {
-      final String text = isNullLiteralExpression(expr)
-                          ? "Passing <code>null</code> argument to non annotated parameter"
-                          : "Argument <code>#ref</code> #loc might be null but passed to non annotated parameter";
-      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
-      final PsiElement parent = expr.getParent();
-      if (parent instanceof PsiExpressionList) {
-        final int idx = ArrayUtil.find(((PsiExpressionList)parent).getExpressions(), expr);
-        if (idx > -1) {
-          final PsiElement gParent = parent.getParent();
-          if (gParent instanceof PsiCallExpression) {
-            final PsiMethod psiMethod = ((PsiCallExpression)gParent).resolveMethod();
-            if (psiMethod != null && psiMethod.getManager().isInProject(psiMethod) && AnnotationUtil.isAnnotatingApplicable(psiMethod)) {
-              final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
-              if (idx < parameters.length) {
-                final AddNullableAnnotationFix addNullableAnnotationFix = new AddNullableAnnotationFix(parameters[idx]);
-                fixes = fixes == null ? new LocalQuickFix[]{addNullableAnnotationFix} : ArrayUtil.append(fixes, addNullableAnnotationFix);
-                holder.registerProblem(expr, text, fixes);
-              }
-            }
-          }
-        }
-      }
-
-    }
-  }
-
-  private static void reportCallMayProduceNpe(ProblemsHolder holder, MethodCallInstruction mcInstruction) {
-    if (mcInstruction.getCallExpression() instanceof PsiMethodCallExpression) {
-      PsiMethodCallExpression callExpression = (PsiMethodCallExpression)mcInstruction.getCallExpression();
-      LocalQuickFix[] fix = createNPEFixes(callExpression.getMethodExpression().getQualifierExpression(), callExpression);
-
-      holder.registerProblem(callExpression,
-                             InspectionsBundle.message("dataflow.message.npe.method.invocation"),
-                             fix);
-    }
-  }
-
-  private static void reportFieldAccessMayProduceNpe(ProblemsHolder holder, FieldReferenceInstruction frInstruction) {
-    PsiElement elementToAssert = frInstruction.getElementToAssert();
-    PsiExpression expression = frInstruction.getExpression();
-    if (expression instanceof PsiArrayAccessExpression) {
-      LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
-      holder.registerProblem(expression,
-                             InspectionsBundle.message("dataflow.message.npe.array.access"),
-                             fix);
-    }
-    else {
-      LocalQuickFix[] fix = createNPEFixes((PsiExpression)elementToAssert, expression);
-      holder.registerProblem(elementToAssert,
-                             InspectionsBundle.message("dataflow.message.npe.field.access"),
-                             fix);
-    }
-  }
-
-  private static void reportCastMayFail(ProblemsHolder holder, TypeCastInstruction instruction) {
-    PsiTypeCastExpression typeCast = instruction.getCastExpression();
-    holder.registerProblem(typeCast.getCastType(),
-                           InspectionsBundle.message("dataflow.message.cce", typeCast.getOperand().getText()));
-  }
-
-  private void handleBranchingInstruction(ProblemsHolder holder,
-                                          StandardInstructionVisitor visitor,
-                                          Set<Instruction> trueSet,
-                                          Set<Instruction> falseSet, HashSet<PsiElement> reportedAnchors, BranchingInstruction instruction) {
-    PsiElement psiAnchor = instruction.getPsiAnchor();
-    boolean underBinary = isAtRHSOfBooleanAnd(psiAnchor);
-    if (instruction instanceof InstanceofInstruction && visitor.isInstanceofRedundant((InstanceofInstruction)instruction)) {
-      if (visitor.canBeNull((BinopInstruction)instruction)) {
-        holder.registerProblem(psiAnchor,
-                               InspectionsBundle.message("dataflow.message.redundant.instanceof"),
-                               new RedundantInstanceofFix());
-      }
-      else {
-        final LocalQuickFix localQuickFix = createSimplifyBooleanExpressionFix(psiAnchor, true);
-        holder.registerProblem(psiAnchor,
-                               InspectionsBundle.message(underBinary ? "dataflow.message.constant.condition.when.reached" : "dataflow.message.constant.condition", Boolean.toString(true)),
-                               localQuickFix == null ? null : new LocalQuickFix[]{localQuickFix});
-      }
-    }
-    else if (psiAnchor instanceof PsiSwitchLabelStatement) {
-      if (falseSet.contains(instruction)) {
-        holder.registerProblem(psiAnchor,
-                               InspectionsBundle.message("dataflow.message.unreachable.switch.label"));
-      }
-    }
-    else if (psiAnchor != null && !reportedAnchors.contains(psiAnchor) && !isCompileConstantInIfCondition(psiAnchor)) {
-      boolean evaluatesToTrue = trueSet.contains(instruction);
-      if (onTheLeftSideOfConditionalAssignemnt(psiAnchor)) {
-        holder.registerProblem(
-          psiAnchor,
-          InspectionsBundle.message("dataflow.message.pointless.assignment.expression", Boolean.toString(evaluatesToTrue)),
-          createSimplifyToAssignmentFix()
-        );
-      }
-      else if (!skipReportingConstantCondition(visitor, psiAnchor, evaluatesToTrue)) {
-        final LocalQuickFix fix = createSimplifyBooleanExpressionFix(psiAnchor, evaluatesToTrue);
-        String message = InspectionsBundle.message(underBinary ?
-                                                   "dataflow.message.constant.condition.when.reached" :
-                                                   "dataflow.message.constant.condition", Boolean.toString(evaluatesToTrue));
-        holder.registerProblem(psiAnchor, message, fix == null ? null : new LocalQuickFix[]{fix});
-      }
-      reportedAnchors.add(psiAnchor);
-    }
-  }
-
-  private boolean skipReportingConstantCondition(StandardInstructionVisitor visitor, PsiElement psiAnchor, boolean evaluatesToTrue) {
-    return DONT_REPORT_TRUE_ASSERT_STATEMENTS && isAssertionEffectively(psiAnchor, evaluatesToTrue) ||
-           visitor.silenceConstantCondition(psiAnchor);
-  }
-
-  private static void reportNullableArguments(StandardDataFlowRunner runner, ProblemsHolder holder) {
-    Set<PsiExpression> exprs = runner.getNullableArguments();
-    for (PsiExpression expr : exprs) {
-      final String text = isNullLiteralExpression(expr)
-                          ? InspectionsBundle.message("dataflow.message.passing.null.argument")
-                          : InspectionsBundle.message("dataflow.message.passing.nullable.argument");
-      LocalQuickFix[] fixes = createNPEFixes(expr, expr);
-      holder.registerProblem(expr, text, fixes);
-    }
-  }
-
-  private static void reportNullableAssignments(StandardDataFlowRunner runner, ProblemsHolder holder) {
-    for (PsiExpression expr : runner.getNullableAssignments()) {
-      final String text = isNullLiteralExpression(expr)
-                          ? InspectionsBundle.message("dataflow.message.assigning.null")
-                          : InspectionsBundle.message("dataflow.message.assigning.nullable");
-      holder.registerProblem(expr, text);
-    }
-  }
-
-  private static void reportUnboxedNullables(StandardDataFlowRunner runner, ProblemsHolder holder) {
-    for (PsiExpression expr : runner.getUnboxedNullables()) {
-      holder.registerProblem(expr, InspectionsBundle.message("dataflow.message.unboxing"));
-    }
-  }
-
-  private static void reportNullableReturns(StandardDataFlowRunner runner, ProblemsHolder holder) {
-    for (PsiReturnStatement statement : runner.getNullableReturns()) {
-      final PsiExpression expr = statement.getReturnValue();
-      if (runner.isInNotNullMethod()) {
-        final String text = isNullLiteralExpression(expr)
-                            ? InspectionsBundle.message("dataflow.message.return.null.from.notnull")
-                            : InspectionsBundle.message("dataflow.message.return.nullable.from.notnull");
-        holder.registerProblem(expr, text);
-      }
-      else if (AnnotationUtil.isAnnotatingApplicable(statement)) {
-        final String text = isNullLiteralExpression(expr)
-                            ? InspectionsBundle.message("dataflow.message.return.null.from.notnullable")
-                            : InspectionsBundle.message("dataflow.message.return.nullable.from.notnullable");
-        final NullableNotNullManager manager = NullableNotNullManager.getInstance(expr.getProject());
-        holder.registerProblem(expr, text, new AnnotateMethodFix(manager.getDefaultNullable(), ArrayUtil.toStringArray(manager.getNotNulls())));
-      }
-    }
-  }
-
-  private static boolean isAssertionEffectively(PsiElement psiAnchor, boolean evaluatesToTrue) {
-    PsiElement parent = psiAnchor.getParent();
-    if (parent instanceof PsiAssertStatement) {
-      return evaluatesToTrue;
-    }
-    if (parent instanceof PsiIfStatement && psiAnchor == ((PsiIfStatement)parent).getCondition()) {
-      PsiStatement thenBranch = ((PsiIfStatement)parent).getThenBranch();
-      if (thenBranch instanceof PsiThrowStatement) {
-        return !evaluatesToTrue;
-      }
-      if (thenBranch instanceof PsiBlockStatement) {
-        PsiStatement[] statements = ((PsiBlockStatement)thenBranch).getCodeBlock().getStatements();
-        if (statements.length == 1 && statements[0] instanceof PsiThrowStatement) {
-          return !evaluatesToTrue;
-        }
-      }
-    }
-    return false;
-  }
-
-  private static boolean isAtRHSOfBooleanAnd(PsiElement expr) {
-    PsiElement cur = expr;
-
-    while (cur != null && !(cur instanceof PsiMember)) {
-      PsiElement parent = cur.getParent();
-
-      if (parent instanceof PsiBinaryExpression && cur == ((PsiBinaryExpression)parent).getROperand()) {
-        return true;
-      }
-
-      cur = parent;
-    }
-
-    return false;
-  }
-
-  private static boolean isCompileConstantInIfCondition(PsiElement element) {
-    if (!(element instanceof PsiReferenceExpression)) return false;
-    PsiElement resolved = ((PsiReferenceExpression)element).resolve();
-    if (!(resolved instanceof PsiField)) return false;
-    PsiField field = (PsiField)resolved;
-
-    if (!field.hasModifierProperty(PsiModifier.FINAL)) return false;
-    if (!field.hasModifierProperty(PsiModifier.STATIC)) return false;
-
-    PsiElement parent = element.getParent();
-    if (parent instanceof PsiPrefixExpression && ((PsiPrefixExpression)parent).getOperationTokenType() == JavaTokenType.EXCL) {
-      element = parent;
-      parent = parent.getParent();
-    }
-    return parent instanceof PsiIfStatement && ((PsiIfStatement)parent).getCondition() == element;
-  }
-
-  private static boolean isNullLiteralExpression(PsiExpression expr) {
-    if (expr instanceof PsiLiteralExpression) {
-      final PsiLiteralExpression literalExpression = (PsiLiteralExpression)expr;
-      return PsiType.NULL.equals(literalExpression.getType());
-    }
-    return false;
-  }
-
-  private static boolean onTheLeftSideOfConditionalAssignemnt(final PsiElement psiAnchor) {
-    final PsiElement parent = psiAnchor.getParent();
-    if (parent instanceof PsiAssignmentExpression) {
-      final PsiAssignmentExpression expression = (PsiAssignmentExpression)parent;
-      if (expression.getLExpression() == psiAnchor) return true;
-    }
-    return false;
-  }
-
-  @Nullable
-  private static LocalQuickFix createSimplifyBooleanExpressionFix(PsiElement element, final boolean value) {
-    SimplifyBooleanExpressionFix fix = createIntention(element, value);
-    if (fix == null) return null;
-    final String text = fix.getText();
-    return new LocalQuickFix() {
-      @Override
-      @NotNull
-      public String getName() {
-        return text;
-      }
-
-      @Override
-      public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-        final PsiElement psiElement = descriptor.getPsiElement();
-        if (psiElement == null) return;
-        final SimplifyBooleanExpressionFix fix = createIntention(psiElement, value);
-        if (fix == null) return;
-        try {
-          LOG.assertTrue(psiElement.isValid());
-          fix.invoke(project, null, psiElement.getContainingFile());
-        }
-        catch (IncorrectOperationException e) {
-          LOG.error(e);
-        }
-      }
-
-      @Override
-      @NotNull
-      public String getFamilyName() {
-        return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
-      }
-    };
-  }
-
-  @NotNull
-  private static LocalQuickFix createSimplifyToAssignmentFix() {
-    return new LocalQuickFix() {
-      @NotNull
-      @Override
-      public String getName() {
-        return InspectionsBundle.message("inspection.data.flow.simplify.to.assignment.quickfix.name");
-      }
-
-      @NotNull
-      @Override
-      public String getFamilyName() {
-        return InspectionsBundle.message("inspection.data.flow.simplify.boolean.expression.quickfix");
-      }
-
-      @Override
-      public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-        final PsiElement psiElement = descriptor.getPsiElement();
-        if (psiElement == null) return;
-
-        final PsiAssignmentExpression assignmentExpression = PsiTreeUtil.getParentOfType(psiElement, PsiAssignmentExpression.class);
-        if (assignmentExpression == null) {
-          return;
-        }
-
-        final PsiElementFactory factory = JavaPsiFacade.getElementFactory(project);
-        final String lExpressionText = assignmentExpression.getLExpression().getText();
-        final PsiExpression rExpression = assignmentExpression.getRExpression();
-        final String rExpressionText = rExpression != null ? rExpression.getText() : "";
-        assignmentExpression.replace(factory.createExpressionFromText(lExpressionText + " = " + rExpressionText, psiElement));
-      }
-    };
-  }
-
-  private static SimplifyBooleanExpressionFix createIntention(PsiElement element, boolean value) {
-    if (!(element instanceof PsiExpression)) return null;
-    final PsiExpression expression = (PsiExpression)element;
-    while (element.getParent() instanceof PsiExpression) {
-      element = element.getParent();
-    }
-    final SimplifyBooleanExpressionFix fix = new SimplifyBooleanExpressionFix(expression, value);
-    // simplify intention already active
-    if (!fix.isAvailable(element.getProject(), null, element.getContainingFile()) ||
-        SimplifyBooleanExpressionFix.canBeSimplified((PsiExpression)element)) {
-      return null;
-    }
-    return fix;
-  }
-
-  private static class RedundantInstanceofFix implements LocalQuickFix {
-    @Override
-    @NotNull
-    public String getName() {
-      return InspectionsBundle.message("inspection.data.flow.redundant.instanceof.quickfix");
-    }
-
-    @Override
-    public void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
-      if (!FileModificationService.getInstance().preparePsiElementForWrite(descriptor.getPsiElement())) return;
-      final PsiElement psiElement = descriptor.getPsiElement();
-      if (psiElement instanceof PsiInstanceOfExpression) {
-        try {
-          final PsiExpression compareToNull = JavaPsiFacade.getInstance(psiElement.getProject()).getElementFactory().
-            createExpressionFromText(((PsiInstanceOfExpression)psiElement).getOperand().getText() + " != null", psiElement.getParent());
-          psiElement.replace(compareToNull);
-        }
-        catch (IncorrectOperationException e) {
-          LOG.error(e);
-        }
-      }
-    }
-
-    @Override
-    @NotNull
-    public String getFamilyName() {
-      return getName();
-    }
-  }
-
-
-  @Override
-  @NotNull
-  public String getDisplayName() {
-    return InspectionsBundle.message("inspection.data.flow.display.name");
-  }
-
-  @Override
-  @NotNull
-  public String getGroupDisplayName() {
-    return GroupNames.BUGS_GROUP_NAME;
-  }
-
-  @Override
-  @NotNull
-  public String getShortName() {
-    return SHORT_NAME;
-  }
-
   private class OptionsPanel extends JPanel {
     private final JCheckBox mySuggestNullables;
     private final JCheckBox myDontReportTrueAsserts;
@@ -627,47 +124,4 @@
     }
   }
 
-  private static class DataFlowInstructionVisitor extends StandardInstructionVisitor {
-    private final StandardDataFlowRunner myRunner;
-
-    private DataFlowInstructionVisitor(StandardDataFlowRunner runner) {
-      myRunner = runner;
-    }
-
-    @Override
-    protected void onAssigningToNotNullableVariable(AssignInstruction instruction) {
-      myRunner.onAssigningToNotNullableVariable(instruction.getRExpression());
-    }
-
-    @Override
-    protected void onNullableReturn(CheckReturnValueInstruction instruction) {
-      myRunner.onNullableReturn(instruction.getReturn());
-    }
-
-    @Override
-    protected void onInstructionProducesCCE(TypeCastInstruction instruction) {
-      myRunner.onInstructionProducesCCE(instruction);
-    }
-
-    @Override
-    protected void onInstructionProducesNPE(Instruction instruction) {
-      if (instruction instanceof MethodCallInstruction &&
-          ((MethodCallInstruction)instruction).getMethodType() == MethodCallInstruction.MethodType.UNBOXING) {
-        myRunner.onUnboxingNullable(((MethodCallInstruction)instruction).getContext());
-      }
-      else {
-        myRunner.onInstructionProducesNPE(instruction);
-      }
-    }
-
-    @Override
-    protected void onPassingNullParameter(PsiExpression arg) {
-      myRunner.onPassingNullParameter(arg);
-    }
-
-    @Override
-    protected void onPassingNullParameterToNonAnnotated(DataFlowRunner runner, PsiExpression arg) {
-      myRunner.onPassingNullParameterToNonAnnotated(arg);
-    }
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
deleted file mode 100644
index 9529296..0000000
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/DfaUtil.java
+++ /dev/null
@@ -1,379 +0,0 @@
-/*
- * Copyright 2000-2009 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.codeInspection.dataFlow;
-
-import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInspection.dataFlow.instructions.AssignInstruction;
-import com.intellij.codeInspection.dataFlow.instructions.Instruction;
-import com.intellij.codeInspection.dataFlow.instructions.PushInstruction;
-import com.intellij.codeInspection.dataFlow.value.DfaValue;
-import com.intellij.codeInspection.dataFlow.value.DfaVariableValue;
-import com.intellij.codeInspection.nullable.NullableStuffInspection;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.MultiValuesMap;
-import com.intellij.openapi.util.Ref;
-import com.intellij.psi.*;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.tree.IElementType;
-import com.intellij.psi.util.CachedValue;
-import com.intellij.psi.util.CachedValueProvider;
-import com.intellij.psi.util.CachedValuesManager;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.util.NullableFunction;
-import com.intellij.util.containers.ContainerUtil;
-import com.intellij.util.containers.Stack;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.*;
-
-/**
- * @author Gregory.Shrago
- */
-public class DfaUtil {
-  private static final Key<CachedValue<MultiValuesMap<PsiVariable, PsiExpression>>> DFA_VARIABLE_INFO_KEY = Key.create("DFA_VARIABLE_INFO_KEY");
-
-  private DfaUtil() {
-  }
-
-  private static final MultiValuesMap<PsiVariable, PsiExpression> TOO_COMPLEX = new MultiValuesMap<PsiVariable, PsiExpression>();
-  @Nullable("null means DFA analysis has failed (too complex to analyze)")
-  public static Collection<PsiExpression> getCachedVariableValues(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
-    if (variable == null || context == null) return Collections.emptyList();
-
-    CachedValue<MultiValuesMap<PsiVariable, PsiExpression>> cachedValue = context.getUserData(DFA_VARIABLE_INFO_KEY);
-    if (cachedValue == null) {
-      final PsiElement codeBlock = getEnclosingCodeBlock(variable, context);
-      cachedValue = CachedValuesManager.getManager(context.getProject()).createCachedValue(new CachedValueProvider<MultiValuesMap<PsiVariable, PsiExpression>>() {
-        @Override
-        public Result<MultiValuesMap<PsiVariable, PsiExpression>> compute() {
-          final MultiValuesMap<PsiVariable, PsiExpression> result;
-          if (codeBlock == null) {
-            result = null;
-          }
-          else {
-            final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
-            RunnerResult runnerResult = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
-            if (runnerResult == RunnerResult.OK) {
-              result = visitor.myValues;
-            }
-            else {
-              result = TOO_COMPLEX;
-            }
-          }
-          return new Result<MultiValuesMap<PsiVariable, PsiExpression>>(result, codeBlock);
-        }
-      }, false);
-      context.putUserData(DFA_VARIABLE_INFO_KEY, cachedValue);
-    }
-    final MultiValuesMap<PsiVariable, PsiExpression> value = cachedValue.getValue();
-    if (value == TOO_COMPLEX) return null;
-    final Collection<PsiExpression> expressions = value == null ? null : value.get(variable);
-    return expressions == null ? Collections.<PsiExpression>emptyList() : expressions;
-  }
-
-  @NotNull
-  public static Nullness getElementNullability(@Nullable PsiType resultType, @Nullable PsiModifierListOwner owner) {
-    if (owner == null) {
-      return Nullness.UNKNOWN;
-    }
-
-    if (NullableNotNullManager.isNullable(owner)) {
-      return Nullness.NULLABLE;
-    }
-    if (NullableNotNullManager.isNotNull(owner)) {
-      return Nullness.NOT_NULL;
-    }
-
-    if (resultType != null) {
-      NullableNotNullManager nnn = NullableNotNullManager.getInstance(owner.getProject());
-      for (PsiAnnotation annotation : resultType.getAnnotations()) {
-        String qualifiedName = annotation.getQualifiedName();
-        if (nnn.getNullables().contains(qualifiedName)) {
-          return Nullness.NULLABLE;
-        }
-        if (nnn.getNotNulls().contains(qualifiedName)) {
-          return Nullness.NOT_NULL;
-        }
-      }
-    }
-
-    return Nullness.UNKNOWN;
-  }
-
-  public static boolean isNullableInitialized(PsiVariable var, boolean nullable) {
-    if (!isFinalField(var)) {
-      return false;
-    }
-
-    List<PsiExpression> initializers = NullableStuffInspection.findAllConstructorInitializers((PsiField)var);
-    if (initializers.isEmpty()) {
-      return false;
-    }
-
-    for (PsiExpression expression : initializers) {
-      if (!(expression instanceof PsiReferenceExpression)) {
-        return false;
-      }
-      PsiElement target = ((PsiReferenceExpression)expression).resolve();
-      if (!(target instanceof PsiParameter)) {
-        return false;
-      }
-      if (nullable && NullableNotNullManager.isNullable((PsiParameter)target)) {
-        return true;
-      }
-      if (!nullable && !NullableNotNullManager.isNotNull((PsiParameter)target)) {
-        return false;
-      }
-    }
-    return !nullable;
-  }
-
-  public static boolean isPlainMutableField(PsiVariable var) {
-    return !var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && !var.hasModifierProperty(PsiModifier.VOLATILE) && var instanceof PsiField;
-  }
-
-  public static boolean isFinalField(PsiVariable var) {
-    return var.hasModifierProperty(PsiModifier.FINAL) && !var.hasModifierProperty(PsiModifier.TRANSIENT) && var instanceof PsiField;
-  }
-
-  @NotNull
-  public static Nullness checkNullness(@Nullable final PsiVariable variable, @Nullable final PsiElement context) {
-    if (variable == null || context == null) return Nullness.UNKNOWN;
-
-    final PsiElement codeBlock = getEnclosingCodeBlock(variable, context);
-    if (codeBlock == null) {
-      return Nullness.UNKNOWN;
-    }
-    final ValuableInstructionVisitor visitor = new ValuableInstructionVisitor(context);
-    RunnerResult result = new ValuableDataFlowRunner().analyzeMethod(codeBlock, visitor);
-    if (result != RunnerResult.OK) {
-      return Nullness.UNKNOWN;
-    }
-    if (visitor.myNulls.contains(variable) && !visitor.myNotNulls.contains(variable)) return Nullness.NULLABLE;
-    if (visitor.myNotNulls.contains(variable) && !visitor.myNulls.contains(variable)) return Nullness.NOT_NULL;
-    return Nullness.UNKNOWN;
-  }
-
-  @Nullable
-  public static PsiCodeBlock getTopmostBlockInSameClass(@NotNull PsiElement position) {
-    PsiCodeBlock block = PsiTreeUtil.getParentOfType(position, PsiCodeBlock.class, false, PsiMember.class, PsiFile.class);
-    if (block == null) {
-      return null;
-    }
-
-    PsiCodeBlock lastBlock = block;
-    while (true) {
-      block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class, true, PsiMember.class, PsiFile.class);
-      if (block == null) {
-        return lastBlock;
-      }
-      lastBlock = block;
-    }
-  }
-
-  private static PsiElement getEnclosingCodeBlock(final PsiVariable variable, final PsiElement context) {
-    PsiElement codeBlock;
-    if (variable instanceof PsiParameter) {
-      codeBlock = ((PsiParameter)variable).getDeclarationScope();
-      if (codeBlock instanceof PsiMethod) {
-        codeBlock = ((PsiMethod)codeBlock).getBody();
-      }
-    }
-    else if (variable instanceof PsiLocalVariable) {
-      codeBlock = PsiTreeUtil.getParentOfType(variable, PsiCodeBlock.class);
-    }
-    else {
-      codeBlock = PsiTreeUtil.getParentOfType(context, PsiCodeBlock.class);
-    }
-    while (codeBlock != null) {
-      PsiAnonymousClass anon = PsiTreeUtil.getParentOfType(codeBlock, PsiAnonymousClass.class);
-      if (anon == null) break;
-      codeBlock = PsiTreeUtil.getParentOfType(anon, PsiCodeBlock.class);
-    }
-    return codeBlock;
-  }
-
-  @NotNull
-  public static Collection<? extends PsiElement> getPossibleInitializationElements(final PsiElement qualifierExpression) {
-    if (qualifierExpression instanceof PsiMethodCallExpression) {
-      return Collections.singletonList(qualifierExpression);
-    }
-    if (qualifierExpression instanceof PsiReferenceExpression) {
-      final PsiElement targetElement = ((PsiReferenceExpression)qualifierExpression).resolve();
-      if (!(targetElement instanceof PsiVariable)) {
-        return Collections.emptyList();
-      }
-      final Collection<? extends PsiElement> variableValues = getCachedVariableValues((PsiVariable)targetElement, qualifierExpression);
-      if (variableValues == null || variableValues.isEmpty()) {
-        return getVariableAssignmentsInFile((PsiVariable)targetElement, false, qualifierExpression);
-      }
-      return variableValues;
-    }
-    if (qualifierExpression instanceof PsiLiteralExpression) {
-      return Collections.singletonList(qualifierExpression);
-    }
-    return Collections.emptyList();
-  }
-
-  @NotNull
-  public static Collection<PsiExpression> getVariableAssignmentsInFile(final PsiVariable psiVariable,
-                                                                       final boolean literalsOnly,
-                                                                       final PsiElement place) {
-    final Ref<Boolean> modificationRef = Ref.create(Boolean.FALSE);
-    final PsiCodeBlock codeBlock = place == null? null : getTopmostBlockInSameClass(place);
-    final int placeOffset = codeBlock != null? place.getTextRange().getStartOffset() : 0;
-    final List<PsiExpression> list = ContainerUtil.mapNotNull(
-      ReferencesSearch.search(psiVariable, new LocalSearchScope(new PsiElement[] {psiVariable.getContainingFile()}, null, true)).findAll(),
-      new NullableFunction<PsiReference, PsiExpression>() {
-        @Override
-        public PsiExpression fun(final PsiReference psiReference) {
-          if (modificationRef.get()) return null;
-          final PsiElement parent = psiReference.getElement().getParent();
-          if (parent instanceof PsiAssignmentExpression) {
-            final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
-            final IElementType operation = assignmentExpression.getOperationTokenType();
-            if (assignmentExpression.getLExpression() == psiReference) {
-              if (JavaTokenType.EQ.equals(operation)) {
-                final PsiExpression rValue = assignmentExpression.getRExpression();
-                if (!literalsOnly || allOperandsAreLiterals(rValue)) {
-                  // if there's a codeBlock omit the values assigned later
-                  if (codeBlock != null && PsiTreeUtil.isAncestor(codeBlock, parent, true)
-                      && placeOffset < parent.getTextRange().getStartOffset()) {
-                    return null;
-                  }
-                  return rValue;
-                }
-                else {
-                  modificationRef.set(Boolean.TRUE);
-                }
-              }
-              else if (JavaTokenType.PLUSEQ.equals(operation)) {
-                modificationRef.set(Boolean.TRUE);
-              }
-            }
-          }
-          return null;
-        }
-      });
-    if (modificationRef.get()) return Collections.emptyList();
-    if (!literalsOnly || allOperandsAreLiterals(psiVariable.getInitializer())) {
-      ContainerUtil.addIfNotNull(psiVariable.getInitializer(), list);
-    }
-    return list;
-  }
-
-  public static boolean allOperandsAreLiterals(@Nullable final PsiExpression expression) {
-    if (expression == null) return false;
-    if (expression instanceof PsiLiteralExpression) return true;
-    if (expression instanceof PsiPolyadicExpression) {
-      Stack<PsiExpression> stack = new Stack<PsiExpression>();
-      stack.add(expression);
-      while (!stack.isEmpty()) {
-        PsiExpression psiExpression = stack.pop();
-        if (psiExpression instanceof PsiPolyadicExpression) {
-          PsiPolyadicExpression binaryExpression = (PsiPolyadicExpression)psiExpression;
-          for (PsiExpression op : binaryExpression.getOperands()) {
-            stack.push(op);
-          }
-        }
-        else if (!(psiExpression instanceof PsiLiteralExpression)) {
-          return false;
-        }
-      }
-      return true;
-    }
-    return false;
-  }
-
-  private static class ValuableInstructionVisitor extends StandardInstructionVisitor {
-    final MultiValuesMap<PsiVariable, PsiExpression> myValues = new MultiValuesMap<PsiVariable, PsiExpression>(true);
-    final Set<PsiVariable> myNulls = new THashSet<PsiVariable>();
-    final Set<PsiVariable> myNotNulls = new THashSet<PsiVariable>();
-    private final PsiElement myContext;
-
-    public ValuableInstructionVisitor(@NotNull PsiElement context) {
-      myContext = context;
-    }
-
-    @Override
-    public DfaInstructionState[] visitPush(PushInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
-      if (myContext == instruction.getPlace()) {
-        final Map<DfaVariableValue,DfaVariableState> map = ((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableStates();
-        for (Map.Entry<DfaVariableValue, DfaVariableState> entry : map.entrySet()) {
-          ValuableDataFlowRunner.ValuableDfaVariableState state = (ValuableDataFlowRunner.ValuableDfaVariableState)entry.getValue();
-          DfaVariableValue variableValue = entry.getKey();
-          final PsiExpression psiExpression = state.myExpression;
-          if (psiExpression != null && variableValue.getQualifier() == null) {
-            myValues.put(variableValue.getPsiVariable(), psiExpression);
-          }
-        }
-        DfaValue value = instruction.getValue();
-        if (value instanceof DfaVariableValue && ((DfaVariableValue)value).getQualifier() == null) {
-          if (memState.isNotNull((DfaVariableValue)value)) {
-            myNotNulls.add(((DfaVariableValue)value).getPsiVariable());
-          }
-          if (memState.isNull(value)) {
-            myNulls.add(((DfaVariableValue)value).getPsiVariable());
-          }
-        }
-      }
-      return super.visitPush(instruction, runner, memState);
-    }
-
-    @Override
-    public DfaInstructionState[] visitAssign(AssignInstruction instruction, DataFlowRunner runner, DfaMemoryState memState) {
-      final Instruction nextInstruction = runner.getInstruction(instruction.getIndex() + 1);
-
-      final DfaValue dfaSource = memState.pop();
-      final DfaValue dfaDest = memState.pop();
-
-      if (dfaDest instanceof DfaVariableValue) {
-        DfaVariableValue var = (DfaVariableValue)dfaDest;
-        final PsiExpression rightValue = instruction.getRExpression();
-        final PsiElement parent = rightValue == null ? null : rightValue.getParent();
-        final IElementType type = parent instanceof PsiAssignmentExpression
-                                  ? ((PsiAssignmentExpression)parent).getOperationTokenType() : JavaTokenType.EQ;
-        // store current value - to use in case of '+='
-        final PsiExpression prevValue = ((ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var)).myExpression;
-        memState.setVarValue(var, dfaSource);
-        // state may have been changed so re-retrieve it
-        final ValuableDataFlowRunner.ValuableDfaVariableState curState = (ValuableDataFlowRunner.ValuableDfaVariableState)((ValuableDataFlowRunner.MyDfaMemoryState)memState).getVariableState(var);
-        final PsiExpression curValue = curState.myExpression;
-        final PsiExpression nextValue;
-        if (type == JavaTokenType.PLUSEQ && prevValue != null) {
-          PsiExpression tmpExpression;
-          try {
-            tmpExpression = JavaPsiFacade.getElementFactory(myContext.getProject())
-              .createExpressionFromText(prevValue.getText() + "+" + rightValue.getText(), rightValue);
-          }
-          catch (Exception e) {
-            tmpExpression = curValue == null ? rightValue : curValue;
-          }
-          nextValue = tmpExpression;
-        }
-        else {
-          nextValue = curValue == null ? rightValue : curValue;
-        }
-        curState.myExpression = nextValue;
-      }
-      memState.push(dfaDest);
-      return new DfaInstructionState[]{new DfaInstructionState(nextInstruction, memState)};
-    }
-  }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java b/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
index 154ad18..008ae77 100644
--- a/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
+++ b/java/java-impl/src/com/intellij/codeInspection/dataFlow/MethodCheckerDetailsDialog.java
@@ -39,17 +39,17 @@
  * Dialog that appears when the user clicks the Add Button or double clicks a row item in a MethodsPanel.  The MethodsPanel is accessed from the ConditionCheckDialog
  */
 class MethodCheckerDetailsDialog extends DialogWrapper implements PropertyChangeListener, ItemListener {
-  private final @NotNull ConditionChecker.Type myType;
-  private final @NotNull Project myProject;
-  private final @NotNull ParameterDropDown parameterDropDown;
-  private final @NotNull MethodDropDown methodDropDown;
-  private final @NotNull ClassField classField;
-  private final @NotNull Set<ConditionChecker> myOtherCheckers;
-  private final @Nullable ConditionChecker myPreviouslySelectedChecker;
+  @NotNull private final ConditionChecker.Type myType;
+  @NotNull private final Project myProject;
+  @NotNull private final ParameterDropDown parameterDropDown;
+  @NotNull private final MethodDropDown methodDropDown;
+  @NotNull private final ClassField classField;
+  @NotNull private final Set<ConditionChecker> myOtherCheckers;
+  @Nullable private final ConditionChecker myPreviouslySelectedChecker;
   /**
    * Set by the OK and/or Cancel actions so that the caller can retrieve it via a call to getMethodIsNullIsNotNullChecker
    */
-  private @Nullable ConditionChecker mySelectedChecker;
+  @Nullable private ConditionChecker mySelectedChecker;
 
   MethodCheckerDetailsDialog(@Nullable ConditionChecker previouslySelectedChecker,
                              @NotNull ConditionChecker.Type type,
@@ -263,8 +263,8 @@
    */
   static class ClassField extends EditorTextFieldWithBrowseButton implements ActionListener, DocumentListener {
     public static final String PROPERTY_PSICLASS = "ClassField.myPsiClass";
-    private final @NotNull Project myProject;
-    private @Nullable PsiClass myPsiClass;
+    @NotNull private final Project myProject;
+    @Nullable private PsiClass myPsiClass;
 
     public ClassField(@NotNull Project project, @Nullable PsiClass psiClass) {
       super(project, true, buildVisibilityChecker());
@@ -341,9 +341,9 @@
    * Drop Down for picking Method Name
    */
   static class MethodDropDown extends JComboBox implements PropertyChangeListener {
-    private final @NotNull ConditionChecker.Type myType;
-    private final @NotNull SortedComboBoxModel<MethodWrapper> myModel;
-    private @Nullable PsiClass myPsiClass;
+    @NotNull private final ConditionChecker.Type myType;
+    @NotNull private final SortedComboBoxModel<MethodWrapper> myModel;
+    @Nullable private PsiClass myPsiClass;
 
     MethodDropDown(@Nullable PsiClass psiClass,
                    @Nullable PsiMethod psiMethod,
@@ -478,9 +478,9 @@
    * Drop Down for picking Parameter Name
    */
   static class ParameterDropDown extends JComboBox implements PropertyChangeListener, ItemListener {
-    private final @NotNull SortedComboBoxModel<ParameterWrapper> myModel;
-    private final @NotNull ConditionChecker.Type myType;
-    private @Nullable PsiMethod myPsiMethod;
+    @NotNull private final SortedComboBoxModel<ParameterWrapper> myModel;
+    @NotNull private final ConditionChecker.Type myType;
+    @Nullable private PsiMethod myPsiMethod;
 
     public ParameterDropDown(@Nullable PsiMethod psiMethod,
                              @Nullable PsiParameter psiParameter,
@@ -582,8 +582,8 @@
     }
 
     class ParameterWrapper implements Comparable<ParameterWrapper> {
-      private final @NotNull String id;
-      private final @NotNull PsiParameter psiParameter;
+      @NotNull private final String id;
+      @NotNull private final PsiParameter psiParameter;
       private final int index;
 
       ParameterWrapper(@NotNull PsiParameter psiParameter, int index) {
@@ -624,8 +624,8 @@
   }
 
   static class MethodWrapper implements Comparable<MethodWrapper> {
-    private final @NotNull PsiMethod myPsiMethod;
-    private final @NotNull String myId;
+    @NotNull private final PsiMethod myPsiMethod;
+    @NotNull private final String myId;
 
     MethodWrapper(@NotNull PsiMethod psiMethod) {
       this.myPsiMethod = psiMethod;
diff --git a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
index db08293..8b19def 100644
--- a/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/defUse/DefUseInspection.java
@@ -25,211 +25,32 @@
 package com.intellij.codeInspection.defUse;
 
 import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.GroupNames;
 import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
-import com.intellij.codeInsight.daemon.impl.quickfix.SideEffectWarningDialog;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
-import com.intellij.psi.controlFlow.DefUseUtil;
 import com.intellij.psi.util.PsiExpressionTrimRenderer;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.IncorrectOperationException;
-import gnu.trove.THashSet;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
-import javax.swing.*;
-import javax.swing.event.ChangeEvent;
-import javax.swing.event.ChangeListener;
-import java.awt.*;
-import java.util.*;
+import java.util.ArrayList;
 import java.util.List;
 
-public class DefUseInspection extends BaseLocalInspectionTool {
-  public boolean REPORT_PREFIX_EXPRESSIONS = false;
-  public boolean REPORT_POSTFIX_EXPRESSIONS = true;
-  public boolean REPORT_REDUNDANT_INITIALIZER = true;
-
+public class DefUseInspection extends DefUseInspectionBase {
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.defUse.DefUseInspection");
 
-  public static final String DISPLAY_NAME = InspectionsBundle.message("inspection.unused.assignment.display.name");
-  @NonNls public static final String SHORT_NAME = "UnusedAssignment";
-
   @Override
-  @NotNull
-  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
-    return new JavaElementVisitor() {
-      @Override public void visitMethod(PsiMethod method) {
-        checkCodeBlock(method.getBody(), holder, isOnTheFly);
-      }
-
-      @Override public void visitClassInitializer(PsiClassInitializer initializer) {
-        checkCodeBlock(initializer.getBody(), holder, isOnTheFly);
-      }
-    };
+  protected LocalQuickFix createRemoveInitializerFix() {
+    return new RemoveInitializerFix();
   }
 
-  private void checkCodeBlock(final PsiCodeBlock body,
-                              final ProblemsHolder holder,
-                              final boolean isOnTheFly) {
-    if (body == null) return;
-    final Set<PsiVariable> usedVariables = new THashSet<PsiVariable>();
-    List<DefUseUtil.Info> unusedDefs = DefUseUtil.getUnusedDefs(body, usedVariables);
-
-    if (unusedDefs != null && !unusedDefs.isEmpty()) {
-      Collections.sort(unusedDefs, new Comparator<DefUseUtil.Info>() {
-        @Override
-        public int compare(DefUseUtil.Info o1, DefUseUtil.Info o2) {
-          int offset1 = o1.getContext().getTextOffset();
-          int offset2 = o2.getContext().getTextOffset();
-
-          if (offset1 == offset2) return 0;
-          if (offset1 < offset2) return -1;
-
-          return 1;
-        }
-      });
-
-      for (DefUseUtil.Info info : unusedDefs) {
-        PsiElement context = info.getContext();
-        PsiVariable psiVariable = info.getVariable();
-
-        if (context instanceof PsiDeclarationStatement || context instanceof PsiResourceVariable) {
-          if (!info.isRead()) {
-            if (!isOnTheFly) {
-              holder.registerProblem(psiVariable.getNameIdentifier(),
-                                     InspectionsBundle.message("inspection.unused.assignment.problem.descriptor1", "<code>#ref</code> #loc"),
-                                     ProblemHighlightType.LIKE_UNUSED_SYMBOL);
-            }
-          }
-          else {
-            if (REPORT_REDUNDANT_INITIALIZER) {
-              holder.registerProblem(psiVariable.getInitializer(),
-                                     InspectionsBundle.message("inspection.unused.assignment.problem.descriptor2",
-                                                               "<code>" + psiVariable.getName() + "</code>", "<code>#ref</code> #loc"),
-                                     ProblemHighlightType.LIKE_UNUSED_SYMBOL,
-                                     new RemoveInitializerFix());
-            }
-          }
-        }
-        else if (context instanceof PsiAssignmentExpression &&
-                 ((PsiAssignmentExpression)context).getOperationTokenType() == JavaTokenType.EQ) {
-          final PsiAssignmentExpression assignment = (PsiAssignmentExpression)context;
-          holder.registerProblem(assignment.getLExpression(),
-                                 InspectionsBundle.message("inspection.unused.assignment.problem.descriptor3",
-                                                           assignment.getRExpression().getText(), "<code>#ref</code>" + " #loc"), ProblemHighlightType.LIKE_UNUSED_SYMBOL);
-        }
-        else {
-          if (context instanceof PsiPrefixExpression && REPORT_PREFIX_EXPRESSIONS ||
-              context instanceof PsiPostfixExpression && REPORT_POSTFIX_EXPRESSIONS) {
-            holder.registerProblem(context,
-                                   InspectionsBundle.message("inspection.unused.assignment.problem.descriptor4", "<code>#ref</code> #loc"));
-          }
-        }
-      }
-    }
-
-    body.accept(new JavaRecursiveElementWalkingVisitor() {
-      @Override public void visitClass(PsiClass aClass) {
-      }
-
-      @Override public void visitLocalVariable(PsiLocalVariable variable) {
-        if (!usedVariables.contains(variable) && variable.getInitializer() == null && !isOnTheFly) {
-          holder.registerProblem(variable.getNameIdentifier(),
-                                 InspectionsBundle.message("inspection.unused.assignment.problem.descriptor5", "<code>#ref</code> #loc"),
-                                 ProblemHighlightType.LIKE_UNUSED_SYMBOL);
-        }
-      }
-
-      @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
-        PsiExpression lExpression = expression.getLExpression();
-        PsiExpression rExpression = expression.getRExpression();
-
-        if (lExpression instanceof PsiReferenceExpression && rExpression instanceof PsiReferenceExpression) {
-          PsiReferenceExpression lRef = (PsiReferenceExpression)lExpression;
-          PsiReferenceExpression rRef = (PsiReferenceExpression)rExpression;
-
-          if (lRef.resolve() != rRef.resolve()) return;
-          PsiExpression lQualifier = lRef.getQualifierExpression();
-          PsiExpression rQualifier = rRef.getQualifierExpression();
-
-          if ((lQualifier == null && rQualifier == null ||
-               lQualifier instanceof PsiThisExpression && rQualifier instanceof PsiThisExpression ||
-               lQualifier instanceof PsiThisExpression && rQualifier == null ||
-               lQualifier == null && rQualifier instanceof PsiThisExpression) && !isOnTheFly) {
-            holder.registerProblem(expression,
-                                   InspectionsBundle.message("inspection.unused.assignment.problem.descriptor6", "<code>#ref</code>"));
-          }
-        }
-      }
-    });
-  }
-
-  @Override
-  public JComponent createOptionsPanel() {
-    return new OptionsPanel();
-  }
-
-  private class OptionsPanel extends JPanel {
-    private final JCheckBox myReportPrefix;
-    private final JCheckBox myReportPostfix;
-    private final JCheckBox myReportInitializer;
-
-    private OptionsPanel() {
-      super(new GridBagLayout());
-
-      GridBagConstraints gc = new GridBagConstraints();
-      gc.weighty = 0;
-      gc.weightx = 1;
-      gc.fill = GridBagConstraints.HORIZONTAL;
-      gc.anchor = GridBagConstraints.NORTHWEST;
-
-      myReportInitializer = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option2"));
-      myReportInitializer.setSelected(REPORT_REDUNDANT_INITIALIZER);
-      myReportInitializer.getModel().addChangeListener(new ChangeListener() {
-        @Override
-        public void stateChanged(ChangeEvent e) {
-          REPORT_REDUNDANT_INITIALIZER = myReportInitializer.isSelected();
-        }
-      });
-      gc.insets = new Insets(0, 0, 15, 0);
-      gc.gridy = 0;
-      add(myReportInitializer, gc);
-
-      myReportPrefix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option"));
-      myReportPrefix.setSelected(REPORT_PREFIX_EXPRESSIONS);
-      myReportPrefix.getModel().addChangeListener(new ChangeListener() {
-        @Override
-        public void stateChanged(ChangeEvent e) {
-          REPORT_PREFIX_EXPRESSIONS = myReportPrefix.isSelected();
-        }
-      });
-      gc.insets = new Insets(0, 0, 0, 0);
-      gc.gridy++;
-      add(myReportPrefix, gc);
-
-      myReportPostfix = new JCheckBox(InspectionsBundle.message("inspection.unused.assignment.option1"));
-      myReportPostfix.setSelected(REPORT_POSTFIX_EXPRESSIONS);
-      myReportPostfix.getModel().addChangeListener(new ChangeListener() {
-        @Override
-        public void stateChanged(ChangeEvent e) {
-          REPORT_POSTFIX_EXPRESSIONS = myReportPostfix.isSelected();
-        }
-      });
-
-      gc.weighty = 1;
-      gc.gridy++;
-      add(myReportPostfix, gc);
-    }
-  }
-
-
   private static class RemoveInitializerFix implements LocalQuickFix {
-
     @Override
     @NotNull
     public String getName() {
@@ -246,20 +67,21 @@
       final PsiVariable variable = (PsiVariable)psiInitializer.getParent();
       final PsiDeclarationStatement declaration = (PsiDeclarationStatement)variable.getParent();
       final List<PsiElement> sideEffects = new ArrayList<PsiElement>();
-      boolean hasSideEffects = RemoveUnusedVariableFix.checkSideEffects(psiInitializer, variable, sideEffects);
-      int res = SideEffectWarningDialog.DELETE_ALL;
+      boolean hasSideEffects = RemoveUnusedVariableUtil.checkSideEffects(psiInitializer, variable, sideEffects);
+      int res = RemoveUnusedVariableUtil.DELETE_ALL;
       if (hasSideEffects) {
         hasSideEffects = PsiUtil.isStatement(psiInitializer);
         res = RemoveUnusedVariableFix.showSideEffectsWarning(sideEffects, variable,
                                                              FileEditorManager.getInstance(project).getSelectedTextEditor(),
                                                              hasSideEffects, sideEffects.get(0).getText(),
-                                                             variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + PsiExpressionTrimRenderer.render((PsiExpression)psiInitializer));
+                                                             variable.getTypeElement().getText() + " " + variable.getName() + ";<br>" + PsiExpressionTrimRenderer
+                                                               .render((PsiExpression)psiInitializer));
       }
       try {
-        if (res == SideEffectWarningDialog.DELETE_ALL) {
+        if (res == RemoveUnusedVariableUtil.DELETE_ALL) {
           psiInitializer.delete();
         }
-        else if (res == SideEffectWarningDialog.MAKE_STATEMENT) {
+        else if (res == RemoveUnusedVariableUtil.MAKE_STATEMENT) {
           final PsiElementFactory factory = JavaPsiFacade.getInstance(variable.getProject()).getElementFactory();
           final PsiStatement statementFromText = factory.createStatementFromText(psiInitializer.getText() + ";", null);
           declaration.getParent().addAfter(statementFromText, declaration);
@@ -277,22 +99,4 @@
       return getName();
     }
   }
-
-  @Override
-  @NotNull
-  public String getDisplayName() {
-    return DISPLAY_NAME;
-  }
-
-  @Override
-  @NotNull
-  public String getGroupDisplayName() {
-    return GroupNames.BUGS_GROUP_NAME;
-  }
-
-  @Override
-  @NotNull
-  public String getShortName() {
-    return SHORT_NAME;
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
index 53f1583..8d7eeaa 100644
--- a/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/defaultFileTemplateUsage/DefaultFileTemplateUsageInspection.java
@@ -17,7 +17,6 @@
 
 import com.intellij.codeInspection.*;
 import com.intellij.ide.fileTemplates.FileTemplate;
-import com.intellij.ide.fileTemplates.FileTemplateManager;
 import com.intellij.ide.fileTemplates.impl.FileTemplateConfigurable;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.options.ShowSettingsUtil;
@@ -29,13 +28,19 @@
 import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
-import java.util.ArrayList;
-import java.util.Collection;
 
 /**
  * @author cdr
  */
 public class DefaultFileTemplateUsageInspection extends BaseJavaLocalInspectionTool {
+  // Fields are left for the compatibility
+  @Deprecated @SuppressWarnings("UnusedDeclaration")
+  public boolean CHECK_FILE_HEADER = true;
+  @Deprecated @SuppressWarnings("UnusedDeclaration")
+  public boolean CHECK_TRY_CATCH_SECTION = true;
+  @Deprecated @SuppressWarnings("UnusedDeclaration")
+  public boolean CHECK_METHOD_BODY = true;
+
   @Override
   @NotNull
   public String getGroupDisplayName() {
diff --git a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
index e6a6608..08f1e42 100644
--- a/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/emptyMethod/EmptyMethodInspection.java
@@ -23,6 +23,7 @@
 import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.reference.*;
 import com.intellij.codeInspection.util.SpecialAnnotationsUtil;
+import com.intellij.codeInspection.util.SpecialAnnotationsUtilBase;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.extensions.Extensions;
@@ -134,10 +135,10 @@
     if (message != null) {
       final ArrayList<LocalQuickFix> fixes = new ArrayList<LocalQuickFix>();
       fixes.add(getFix(processor, needToDeleteHierarchy));
-      SpecialAnnotationsUtil.createAddToSpecialAnnotationFixes(refMethod.getElement(), new Processor<String>() {
+      SpecialAnnotationsUtilBase.createAddToSpecialAnnotationFixes(refMethod.getElement(), new Processor<String>() {
         @Override
         public boolean process(final String qualifiedName) {
-          fixes.add(SpecialAnnotationsUtil.createAddToSpecialAnnotationsListQuickFix(
+          fixes.add(SpecialAnnotationsUtilBase.createAddToSpecialAnnotationsListQuickFix(
             QuickFixBundle.message("fix.add.special.annotation.text", qualifiedName),
             QuickFixBundle.message("fix.add.special.annotation.family"),
             EXCLUDE_ANNOS, qualifiedName, refMethod.getElement()));
diff --git a/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java b/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
deleted file mode 100644
index 22631e2..0000000
--- a/java/java-impl/src/com/intellij/codeInspection/inheritance/ChangeSuperClassFix.java
+++ /dev/null
@@ -1,128 +0,0 @@
-/*
- * 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.codeInspection.inheritance;
-
-import com.intellij.codeInsight.FileModificationService;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.intention.LowPriorityAction;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
-import com.intellij.openapi.command.WriteCommandAction;
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.TestOnly;
-
-/**
- * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
- */
-public class ChangeSuperClassFix implements LocalQuickFix {
-  @NotNull
-  private final PsiClass myNewSuperClass;
-  @NotNull
-  private final PsiClass myOldSuperClass;
-  private final int myPercent;
-
-  public ChangeSuperClassFix(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
-    myNewSuperClass = newSuperClass;
-    myOldSuperClass = oldSuperClass;
-    myPercent = percent;
-  }
-
-  @NotNull
-  @TestOnly
-  public PsiClass getNewSuperClass() {
-    return myNewSuperClass;
-  }
-
-  @TestOnly
-  public int getPercent() {
-    return myPercent;
-  }
-
-  @NotNull
-  @Override
-  public String getName() {
-    return String.format("Make extends '%s' - %s%%", myNewSuperClass.getQualifiedName(), myPercent);
-  }
-
-  @NotNull
-  @Override
-  public String getFamilyName() {
-    return GroupNames.INHERITANCE_GROUP_NAME;
-  }
-
-  @Override
-  public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor problemDescriptor) {
-    changeSuperClass((PsiClass)problemDescriptor.getPsiElement(), myOldSuperClass, myNewSuperClass);
-  }
-
-  /**
-   * myOldSuperClass and myNewSuperClass can be interfaces or classes in any combination
-   * <p/>
-   * 1. not checks that myOldSuperClass is really super of aClass
-   * 2. not checks that myNewSuperClass not exists in currently existed supers
-   */
-  private static void changeSuperClass(@NotNull final PsiClass aClass,
-                                       @NotNull final PsiClass oldSuperClass,
-                                       @NotNull final PsiClass newSuperClass) {
-    if (!FileModificationService.getInstance().preparePsiElementForWrite(aClass)) return;
-
-    new WriteCommandAction.Simple(newSuperClass.getProject(), aClass.getContainingFile()) {
-      @Override
-      protected void run() throws Throwable {
-        PsiElementFactory factory = JavaPsiFacade.getInstance(aClass.getProject()).getElementFactory();
-        if (aClass instanceof PsiAnonymousClass) {
-          ((PsiAnonymousClass)aClass).getBaseClassReference().replace(factory.createClassReferenceElement(newSuperClass));
-        }
-        else if (oldSuperClass.isInterface()) {
-          final PsiReferenceList interfaceList = aClass.getImplementsList();
-          if (interfaceList != null) {
-            for (final PsiJavaCodeReferenceElement interfaceRef : interfaceList.getReferenceElements()) {
-              final PsiElement aInterface = interfaceRef.resolve();
-              if (aInterface != null && aInterface.isEquivalentTo(oldSuperClass)) {
-                interfaceRef.delete();
-              }
-            }
-          }
-
-          final PsiReferenceList extendsList = aClass.getExtendsList();
-          if (extendsList != null) {
-            final PsiJavaCodeReferenceElement newClassReference = factory.createClassReferenceElement(newSuperClass);
-            if (extendsList.getReferenceElements().length == 0) {
-              extendsList.add(newClassReference);
-            }
-          }
-        }
-        else {
-          final PsiReferenceList extendsList = aClass.getExtendsList();
-          if (extendsList != null && extendsList.getReferenceElements().length == 1) {
-            extendsList.getReferenceElements()[0].delete();
-            PsiElement ref = extendsList.add(factory.createClassReferenceElement(newSuperClass));
-            JavaCodeStyleManager.getInstance(aClass.getProject()).shortenClassReferences(ref);
-          }
-        }
-      }
-    }.execute();
-  }
-
-  public static class LowPriority extends ChangeSuperClassFix implements LowPriorityAction {
-    public LowPriority(@NotNull final PsiClass newSuperClass, final int percent, @NotNull final PsiClass oldSuperClass) {
-      super(newSuperClass, percent, oldSuperClass);
-    }
-  }
-}
diff --git a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
index bc9195d..7e8448e 100644
--- a/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/nullable/NullableStuffInspection.java
@@ -15,474 +15,23 @@
  */
 package com.intellij.codeInspection.nullable;
 
-import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.NullableNotNullDialog;
-import com.intellij.codeInsight.NullableNotNullManager;
-import com.intellij.codeInsight.daemon.GroupNames;
-import com.intellij.codeInsight.intention.AddAnnotationFix;
-import com.intellij.codeInsight.intention.impl.AddNotNullAnnotationFix;
-import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
-import com.intellij.codeInspection.*;
-import com.intellij.codeInspection.ex.BaseLocalInspectionTool;
 import com.intellij.ide.DataManager;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
-import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.psi.*;
-import com.intellij.psi.codeStyle.JavaCodeStyleManager;
-import com.intellij.psi.codeStyle.VariableKind;
-import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.search.LocalSearchScope;
-import com.intellij.psi.search.searches.OverridingMethodsSearch;
-import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.*;
-import com.intellij.refactoring.psi.PropertyUtils;
-import com.intellij.util.ArrayUtil;
-import com.intellij.util.Processor;
-import com.intellij.util.containers.ContainerUtil;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
-import java.util.List;
 
-public class NullableStuffInspection extends BaseLocalInspectionTool {
-  // deprecated fields remain to minimize changes to users inspection profiles (which are often located in version control).
-  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLABLE_METHOD_OVERRIDES_NOTNULL = true;
-  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL = true;
-  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE = true;
-  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_PARAMETER_OVERRIDES_NOTNULL = true;
-  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_GETTER = true;
-  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NOT_ANNOTATED_SETTER_PARAMETER = true;
-  @Deprecated @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = true; // remains for test
-  @SuppressWarnings({"WeakerAccess"}) public boolean REPORT_NULLS_PASSED_TO_NON_ANNOTATED_METHOD = true;
-
-  private static final Logger LOG = Logger.getInstance("#" + NullableStuffInspection.class.getName());
-
-  @Override
-  @NotNull
-  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, boolean isOnTheFly) {
-    return new JavaElementVisitor() {
-      @Override public void visitMethod(PsiMethod method) {
-        if (!PsiUtil.isLanguageLevel5OrHigher(method)) return;
-        checkNullableStuffForMethod(method, holder);
-      }
-
-      @Override public void visitField(PsiField field) {
-        if (!PsiUtil.isLanguageLevel5OrHigher(field)) return;
-        final PsiType type = field.getType();
-        final Annotated annotated = check(field, holder, type);
-        if (TypeConversionUtil.isPrimitiveAndNotNull(type)) {
-          return;
-        }
-        Project project = holder.getProject();
-        final NullableNotNullManager manager = NullableNotNullManager.getInstance(project);
-        if (annotated.isDeclaredNotNull ^ annotated.isDeclaredNullable) {
-          final String anno = annotated.isDeclaredNotNull ? manager.getDefaultNotNull() : manager.getDefaultNullable();
-          final List<String> annoToRemove = annotated.isDeclaredNotNull ? manager.getNullables() : manager.getNotNulls();
-
-          if (!AnnotationUtil.isAnnotatingApplicable(field, anno)) {
-            final PsiAnnotation notNull = AnnotationUtil.findAnnotation(field, manager.getNotNulls());
-            final PsiAnnotation nullable = AnnotationUtil.findAnnotation(field, manager.getNullables());
-            holder.registerProblem(field.getNameIdentifier(), "Nullable/NotNull defaults are not accessible in current context",
-                                   new ChangeNullableDefaultsFix(notNull, nullable, manager));
-            return;
-          }
-
-          String propName = JavaCodeStyleManager.getInstance(project).variableNameToPropertyName(field.getName(), VariableKind.FIELD);
-          final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
-          final PsiMethod getter = PropertyUtil.findPropertyGetter(field.getContainingClass(), propName, isStatic, false);
-          final String nullableSimpleName = StringUtil.getShortName(manager.getDefaultNullable());
-          final String notNullSimpleName = StringUtil.getShortName(manager.getDefaultNotNull());
-          final PsiIdentifier nameIdentifier = getter == null ? null : getter.getNameIdentifier();
-          if (nameIdentifier != null && nameIdentifier.isPhysical()) {
-            if (PropertyUtils.isSimpleGetter(getter)) {
-              if (REPORT_NOT_ANNOTATED_GETTER) {
-                if (!AnnotationUtil.isAnnotated(getter, manager.getAllAnnotations(), false, false) &&
-                    !TypeConversionUtil.isPrimitiveAndNotNull(getter.getReturnType())) {
-                  holder.registerProblem(nameIdentifier, InspectionsBundle
-                    .message("inspection.nullable.problems.annotated.field.getter.not.annotated", StringUtil.getShortName(anno)),
-                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
-                }
-              }
-              if (annotated.isDeclaredNotNull && manager.isNullable(getter, false)) {
-                holder.registerProblem(nameIdentifier, InspectionsBundle.message(
-                  "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), nullableSimpleName),
-                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
-              } else if (annotated.isDeclaredNullable && manager.isNotNull(getter, false)) {
-                holder.registerProblem(nameIdentifier, InspectionsBundle.message(
-                  "inspection.nullable.problems.annotated.field.getter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
-                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AnnotateMethodFix(anno, ArrayUtil.toStringArray(annoToRemove)));
-              }
-            }
-          }
-
-          final PsiClass containingClass = field.getContainingClass();
-          final PsiMethod setter = PropertyUtil.findPropertySetter(containingClass, propName, isStatic, false);
-          if (setter != null) {
-            final PsiParameter[] parameters = setter.getParameterList().getParameters();
-            assert parameters.length == 1 : setter.getText();
-            final PsiParameter parameter = parameters[0];
-            LOG.assertTrue(parameter != null, setter.getText());
-            if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
-              final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
-              assertValidElement(setter, parameter, nameIdentifier1);
-              holder.registerProblem(nameIdentifier1,
-                                     InspectionsBundle.message("inspection.nullable.problems.annotated.field.setter.parameter.not.annotated",
-                                                               StringUtil.getShortName(anno)),
-                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                     new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-            }
-            if (PropertyUtils.isSimpleSetter(setter)) {
-              if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
-                final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
-                assertValidElement(setter, parameter, nameIdentifier1);
-                holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
-                                       "inspection.nullable.problems.annotated.field.setter.parameter.conflict",
-                                       StringUtil.getShortName(anno), nullableSimpleName),
-                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                       new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-              }
-              else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
-                final PsiIdentifier nameIdentifier1 = parameter.getNameIdentifier();
-                assertValidElement(setter, parameter, nameIdentifier1);
-                holder.registerProblem(nameIdentifier1, InspectionsBundle.message(
-                  "inspection.nullable.problems.annotated.field.setter.parameter.conflict", StringUtil.getShortName(anno), notNullSimpleName),
-                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                       new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-              }
-            }
-          }
-
-          for (PsiExpression rhs : findAllConstructorInitializers(field)) {
-            if (rhs instanceof PsiReferenceExpression) {
-              PsiElement target = ((PsiReferenceExpression)rhs).resolve();
-              if (target instanceof PsiParameter) {
-                PsiParameter parameter = (PsiParameter)target;
-                if (REPORT_NOT_ANNOTATED_GETTER && !AnnotationUtil.isAnnotated(parameter, manager.getAllAnnotations(), false, false) && !TypeConversionUtil.isPrimitiveAndNotNull(parameter.getType())) {
-                  final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
-                  assert nameIdentifier2 != null : parameter;
-                  holder.registerProblem(nameIdentifier2, InspectionsBundle
-                    .message("inspection.nullable.problems.annotated.field.constructor.parameter.not.annotated",
-                             StringUtil.getShortName(anno)),
-                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-                  continue;
-                }
-                if (annotated.isDeclaredNotNull && manager.isNullable(parameter, false)) {
-                  final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
-                  assert nameIdentifier2 != null : parameter;
-                  holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
-                    "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
-                    nullableSimpleName),
-                                         ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                         new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-                }
-                else if (annotated.isDeclaredNullable && manager.isNotNull(parameter, false)) {
-                  boolean usedAsQualifier = !ReferencesSearch.search(parameter).forEach(new Processor<PsiReference>() {
-                    @Override
-                    public boolean process(PsiReference reference) {
-                      final PsiElement element = reference.getElement();
-                      if (element instanceof PsiReferenceExpression && element.getParent() instanceof PsiReferenceExpression) {
-                        return false;
-                      }
-                      return true;
-                    }
-                  });
-                  if (!usedAsQualifier) {
-                    final PsiIdentifier nameIdentifier2 = parameter.getNameIdentifier();
-                    assert nameIdentifier2 != null : parameter;
-                    holder.registerProblem(nameIdentifier2, InspectionsBundle.message(
-                      "inspection.nullable.problems.annotated.field.constructor.parameter.conflict", StringUtil.getShortName(anno),
-                      notNullSimpleName),
-                                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                           new AddAnnotationFix(anno, parameter, ArrayUtil.toStringArray(annoToRemove)));
-                  }
-                }
-
-              }
-            }
-          }
-        }
-      }
-
-      private void assertValidElement(PsiMethod setter, PsiParameter parameter, PsiIdentifier nameIdentifier1) {
-        LOG.assertTrue(nameIdentifier1 != null && nameIdentifier1.isPhysical(), setter.getText());
-        LOG.assertTrue(parameter.isPhysical(), setter.getText());
-      }
-
-      @Override public void visitParameter(PsiParameter parameter) {
-        if (!PsiUtil.isLanguageLevel5OrHigher(parameter)) return;
-        check(parameter, holder, parameter.getType());
-      }
-    };
-  }
-
-  private static class Annotated {
-    private final boolean isDeclaredNotNull;
-    private final boolean isDeclaredNullable;
-
-    private Annotated(final boolean isDeclaredNotNull, final boolean isDeclaredNullable) {
-      this.isDeclaredNotNull = isDeclaredNotNull;
-      this.isDeclaredNullable = isDeclaredNullable;
-    }
-  }
-  private static Annotated check(final PsiModifierListOwner parameter, final ProblemsHolder holder, PsiType type) {
-    final NullableNotNullManager manager = NullableNotNullManager.getInstance(holder.getProject());
-    PsiAnnotation isDeclaredNotNull = AnnotationUtil.findAnnotation(parameter, manager.getNotNulls());
-    PsiAnnotation isDeclaredNullable = AnnotationUtil.findAnnotation(parameter, manager.getNullables());
-    if (isDeclaredNullable != null && isDeclaredNotNull != null) {
-      reportNullableNotNullConflict(holder, parameter, isDeclaredNullable,  isDeclaredNotNull);
-    }
-    if ((isDeclaredNotNull != null || isDeclaredNullable != null) && type != null && TypeConversionUtil.isPrimitive(type.getCanonicalText())) {
-      PsiAnnotation annotation = isDeclaredNotNull == null ? isDeclaredNullable : isDeclaredNotNull;
-      reportPrimitiveType(holder, annotation, annotation, parameter);
-    }
-    return new Annotated(isDeclaredNotNull != null,isDeclaredNullable != null);
-  }
-
-  private static void reportPrimitiveType(final ProblemsHolder holder, final PsiElement psiElement, final PsiAnnotation annotation,
-                                          final PsiModifierListOwner listOwner) {
-    holder.registerProblem(psiElement.isPhysical() ? psiElement : listOwner.getNavigationElement(),
-                           InspectionsBundle.message("inspection.nullable.problems.primitive.type.annotation"),
-                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(annotation, listOwner));
-  }
-
-  @Override
-  @NotNull
-  public String getDisplayName() {
-    return InspectionsBundle.message("inspection.nullable.problems.display.name");
-  }
-
-  @Override
-  @NotNull
-  public String getGroupDisplayName() {
-    return GroupNames.BUGS_GROUP_NAME;
-  }
-
-  @Override
-  @NotNull
-  public String getShortName() {
-    return "NullableProblems";
-  }
-
-  private void checkNullableStuffForMethod(PsiMethod method, final ProblemsHolder holder) {
-    Annotated annotated = check(method, holder, method.getReturnType());
-
-    PsiParameter[] parameters = method.getParameterList().getParameters();
-
-    List<MethodSignatureBackedByPsiMethod> superMethodSignatures = method.findSuperMethodSignaturesIncludingStatic(true);
-    boolean reported_not_annotated_method_overrides_notnull = false;
-    boolean reported_nullable_method_overrides_notnull = false;
-    boolean[] reported_notnull_parameter_overrides_nullable = new boolean[parameters.length];
-    boolean[] reported_not_annotated_parameter_overrides_notnull = new boolean[parameters.length];
-
-    final NullableNotNullManager nullableManager = NullableNotNullManager.getInstance(holder.getProject());
-    for (MethodSignatureBackedByPsiMethod superMethodSignature : superMethodSignatures) {
-      PsiMethod superMethod = superMethodSignature.getMethod();
-      if (!reported_nullable_method_overrides_notnull
-          && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE
-          && annotated.isDeclaredNullable
-          && NullableNotNullManager.isNotNull(superMethod)) {
-        reported_nullable_method_overrides_notnull = true;
-        holder.registerProblem(method.getNameIdentifier(),
-                               InspectionsBundle.message("inspection.nullable.problems.Nullable.method.overrides.NotNull"),
-                               ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
-      }
-      if (!reported_not_annotated_method_overrides_notnull
-          && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL
-          && !annotated.isDeclaredNullable
-          && !annotated.isDeclaredNotNull
-          && NullableNotNullManager.isNotNull(superMethod)) {
-        reported_not_annotated_method_overrides_notnull = true;
-        final String defaultNotNull = nullableManager.getDefaultNotNull();
-        final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
-        final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull)
-                                  ? createAnnotateMethodFix(defaultNotNull, annotationsToRemove)
-                                  : createChangeDefaultNotNullFix(nullableManager, superMethod);
-        holder.registerProblem(method.getNameIdentifier(),
-                               InspectionsBundle.message("inspection.nullable.problems.method.overrides.NotNull"),
-                               ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                               wrapFix(fix));
-      }
-      if (REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE || REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
-        PsiParameter[] superParameters = superMethod.getParameterList().getParameters();
-        if (superParameters.length != parameters.length) {
-          continue;
-        }
-        for (int i = 0; i < parameters.length; i++) {
-          PsiParameter parameter = parameters[i];
-          PsiParameter superParameter = superParameters[i];
-          if (!reported_notnull_parameter_overrides_nullable[i] && REPORT_NOTNULL_PARAMETER_OVERRIDES_NULLABLE &&
-              nullableManager.isNotNull(parameter, false) &&
-              nullableManager.isNullable(superParameter, false)) {
-            reported_notnull_parameter_overrides_nullable[i] = true;
-            holder.registerProblem(parameter.getNameIdentifier(),
-                                   InspectionsBundle.message("inspection.nullable.problems.NotNull.parameter.overrides.Nullable"),
-                                   ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
-          }
-          if (!reported_not_annotated_parameter_overrides_notnull[i] && REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL) {
-            if (!AnnotationUtil.isAnnotated(parameter, nullableManager.getAllAnnotations(), false, false) &&
-                nullableManager.isNotNull(superParameter, false)) {
-              reported_not_annotated_parameter_overrides_notnull[i] = true;
-              final LocalQuickFix fix = AnnotationUtil.isAnnotatingApplicable(parameter, nullableManager.getDefaultNotNull())
-                                        ? new AddNotNullAnnotationFix(parameter)
-                                        : createChangeDefaultNotNullFix(nullableManager, superParameter);
-              holder.registerProblem(parameter.getNameIdentifier(),
-                                     InspectionsBundle.message("inspection.nullable.problems.parameter.overrides.NotNull"),
-                                     ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                     wrapFix(fix));
-            }
-          }
-        }
-      }
-    }
-
-    if (REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS) {
-      boolean[] parameterAnnotated = new boolean[parameters.length];
-      boolean[] parameterQuickFixSuggested = new boolean[parameters.length];
-      boolean hasAnnotatedParameter = false;
-      for (int i = 0; i < parameters.length; i++) {
-        PsiParameter parameter = parameters[i];
-        parameterAnnotated[i] = nullableManager.isNotNull(parameter, false);
-        hasAnnotatedParameter |= parameterAnnotated[i];
-      }
-      if (hasAnnotatedParameter || annotated.isDeclaredNotNull) {
-        PsiManager manager = method.getManager();
-        final String defaultNotNull = nullableManager.getDefaultNotNull();
-        final boolean superMethodApplicable = AnnotationUtil.isAnnotatingApplicable(method, defaultNotNull);
-        PsiMethod[] overridings =
-          OverridingMethodsSearch.search(method, GlobalSearchScope.allScope(manager.getProject()), true).toArray(PsiMethod.EMPTY_ARRAY);
-        boolean methodQuickFixSuggested = false;
-        for (PsiMethod overriding : overridings) {
-          if (!manager.isInProject(overriding)) continue;
-
-          final boolean applicable = AnnotationUtil.isAnnotatingApplicable(overriding, defaultNotNull);
-          if (!methodQuickFixSuggested
-              && annotated.isDeclaredNotNull
-              && !nullableManager.isNotNull(overriding, false)
-              && (nullableManager.isNullable(overriding, false) || !nullableManager.isNullable(overriding, true))) {
-            method.getNameIdentifier(); //load tree
-            PsiAnnotation annotation = AnnotationUtil.findAnnotation(method, nullableManager.getNotNulls());
-            final String[] annotationsToRemove = ArrayUtil.toStringArray(nullableManager.getNullables());
-
-            final LocalQuickFix fix;
-            if (applicable) {
-              fix = new MyAnnotateMethodFix(defaultNotNull, annotationsToRemove);
-            }
-            else {
-              fix = superMethodApplicable ? null : createChangeDefaultNotNullFix(nullableManager, method);
-            }
-
-            PsiElement psiElement = annotation;
-            if (!annotation.isPhysical()) {
-              psiElement = method.getNameIdentifier();
-              if (psiElement == null) continue;
-            }
-            holder.registerProblem(psiElement, InspectionsBundle.message("nullable.stuff.problems.overridden.methods.are.not.annotated"),
-                                   ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                   wrapFix(fix));
-            methodQuickFixSuggested = true;
-          }
-          if (hasAnnotatedParameter) {
-            PsiParameter[] psiParameters = overriding.getParameterList().getParameters();
-            for (int i = 0; i < psiParameters.length; i++) {
-              if (parameterQuickFixSuggested[i]) continue;
-              PsiParameter parameter = psiParameters[i];
-              if (parameterAnnotated[i] && !nullableManager.isNotNull(parameter, false) && !nullableManager.isNullable(parameter, false)) {
-                parameters[i].getNameIdentifier(); //be sure that corresponding tree element available
-                PsiAnnotation annotation = AnnotationUtil.findAnnotation(parameters[i], nullableManager.getNotNulls());
-                PsiElement psiElement = annotation;
-                if (!annotation.isPhysical()) {
-                  psiElement = parameters[i].getNameIdentifier();
-                  if (psiElement == null) continue;
-                }
-                holder.registerProblem(psiElement,
-                                       InspectionsBundle.message("nullable.stuff.problems.overridden.method.parameters.are.not.annotated"),
-                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING,
-                                       wrapFix(!applicable
-                                               ? createChangeDefaultNotNullFix(nullableManager, parameters[i])
-                                               : new AnnotateOverriddenMethodParameterFix(defaultNotNull,
-                                                                                          nullableManager.getDefaultNullable())));
-                parameterQuickFixSuggested[i] = true;
-              }
-            }
-          }
-        }
-      }
-    }
-  }
-
-  private static LocalQuickFix[] wrapFix(LocalQuickFix fix) {
-    if (fix == null) return LocalQuickFix.EMPTY_ARRAY;
-    return new LocalQuickFix[]{fix};
-  }
-
-  private static LocalQuickFix createChangeDefaultNotNullFix(NullableNotNullManager nullableManager, PsiModifierListOwner modifierListOwner) {
-    final PsiAnnotation annotation = AnnotationUtil.findAnnotation(modifierListOwner, nullableManager.getNotNulls());
-    if (annotation != null) {
-      final PsiJavaCodeReferenceElement referenceElement = annotation.getNameReferenceElement();
-      if (referenceElement != null && referenceElement.resolve() != null) {
-        return new ChangeNullableDefaultsFix(annotation.getQualifiedName(), null, nullableManager);
-      }
-    }
-    return null;
-  }
-
-  protected AnnotateMethodFix createAnnotateMethodFix(final String defaultNotNull, final String[] annotationsToRemove) {
-    return new AnnotateMethodFix(defaultNotNull, annotationsToRemove);
-  }
-
-  private static void reportNullableNotNullConflict(final ProblemsHolder holder, final PsiModifierListOwner listOwner, final PsiAnnotation declaredNullable,
-                                                    final PsiAnnotation declaredNotNull) {
-    holder.registerProblem(declaredNotNull.isPhysical() ? declaredNotNull : listOwner.getNavigationElement(),
-                           InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
-                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNotNull, listOwner));
-    holder.registerProblem(declaredNullable.isPhysical() ? declaredNullable : listOwner.getNavigationElement(),
-                           InspectionsBundle.message("inspection.nullable.problems.Nullable.NotNull.conflict"),
-                           ProblemHighlightType.GENERIC_ERROR_OR_WARNING, new RemoveAnnotationQuickFix(declaredNullable, listOwner));
-  }
-
+public class NullableStuffInspection extends NullableStuffInspectionBase {
   @Override
   public JComponent createOptionsPanel() {
     return new OptionsPanel();
   }
 
-  private static class MyAddNullableAnnotationFix extends AddNullableAnnotationFix {
-    public MyAddNullableAnnotationFix(PsiParameter parameter) {
-      super(parameter);
-    }
-
-    @Override
-    public boolean isAvailable(@NotNull Project project,
-                               @NotNull PsiFile file,
-                               @NotNull PsiElement startElement,
-                               @NotNull PsiElement endElement) {
-      return true;
-    }
-  }
-
-  private static class MyAnnotateMethodFix extends AnnotateMethodFix {
-    public MyAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
-      super(defaultNotNull, annotationsToRemove);
-    }
-
-    @Override
-    protected boolean annotateOverriddenMethods() {
-      return true;
-    }
-
-    @Override
-    @NotNull
-    public String getName() {
-      return InspectionsBundle.message("annotate.overridden.methods.as.notnull", ClassUtil.extractClassName(myAnnotation));
-    }
-  }
-
   private class OptionsPanel extends JPanel {
     private JCheckBox myNNParameterOverridesN;
     private JCheckBox myNAMethodOverridesNN;
@@ -528,42 +77,4 @@
       REPORT_ANNOTATION_NOT_PROPAGATED_TO_OVERRIDERS = REPORT_NOT_ANNOTATED_METHOD_OVERRIDES_NOTNULL;
     }
   }
-
-  public static List<PsiExpression> findAllConstructorInitializers(PsiField field) {
-    final List<PsiExpression> result = ContainerUtil.createLockFreeCopyOnWriteList();
-    ContainerUtil.addIfNotNull(result, field.getInitializer());
-
-    PsiClass containingClass = field.getContainingClass();
-    if (containingClass != null) {
-      LocalSearchScope scope = new LocalSearchScope(containingClass.getConstructors());
-      ReferencesSearch.search(field, scope, false).forEach(new Processor<PsiReference>() {
-        @Override
-        public boolean process(PsiReference reference) {
-          final PsiElement element = reference.getElement();
-          if (element instanceof PsiReferenceExpression) {
-            final PsiAssignmentExpression assignment = getAssignmentExpressionIfOnAssignmentLhs(element);
-            final PsiMethod method = PsiTreeUtil.getParentOfType(assignment, PsiMethod.class);
-            if (method != null && method.isConstructor() && assignment != null) {
-              ContainerUtil.addIfNotNull(result, assignment.getRExpression());
-            }
-          }
-          return true;
-        }
-      });
-    }
-    return result;
-  }
-
-  @Nullable
-  private static PsiAssignmentExpression getAssignmentExpressionIfOnAssignmentLhs(PsiElement expression) {
-    PsiElement parent = PsiTreeUtil.skipParentsOfType(expression, PsiParenthesizedExpression.class);
-    if (!(parent instanceof PsiAssignmentExpression)) {
-      return null;
-    }
-    final PsiAssignmentExpression assignmentExpression = (PsiAssignmentExpression)parent;
-    if (!PsiTreeUtil.isAncestor(assignmentExpression.getLExpression(), expression, false)) {
-      return null;
-    }
-    return assignmentExpression;
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
index a5e71fb..b8fea07 100644
--- a/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
+++ b/java/java-impl/src/com/intellij/codeInspection/reference/RefJavaManagerImpl.java
@@ -15,10 +15,7 @@
  */
 package com.intellij.codeInspection.reference;
 
-import com.intellij.codeInspection.InspectionProfileEntry;
-import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.SuppressManager;
-import com.intellij.codeInspection.SuppressionUtil;
+import com.intellij.codeInspection.*;
 import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
 import com.intellij.codeInspection.ex.EntryPointsManager;
 import com.intellij.codeInspection.ex.EntryPointsManagerImpl;
@@ -450,7 +447,7 @@
     @Override
     public void visitAnnotation(PsiAnnotation annotation) {
       super.visitAnnotation(annotation);
-      if (Comparing.strEqual(annotation.getQualifiedName(), SuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME)) {
+      if (Comparing.strEqual(annotation.getQualifiedName(), BatchSuppressManager.SUPPRESS_INSPECTIONS_ANNOTATION_NAME)) {
         final PsiModifierListOwner listOwner = PsiTreeUtil.getParentOfType(annotation, PsiModifierListOwner.class);
         if (listOwner != null) {
           final RefElementImpl element = (RefElementImpl)myRefManager.getReference(listOwner);
diff --git a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
index 2d363ec..24cc9d1 100644
--- a/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/uncheckedWarnings/UncheckedWarningLocalInspection.java
@@ -17,8 +17,8 @@
 package com.intellij.codeInspection.uncheckedWarnings;
 
 import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.HighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.daemon.impl.quickfix.GenerifyFileFix;
 import com.intellij.codeInsight.daemon.impl.quickfix.VariableArrayTypeFix;
 import com.intellij.codeInsight.intention.IntentionAction;
@@ -177,7 +177,7 @@
     };
   }
 
-  public abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
+  private abstract class UncheckedWarningsVisitor extends JavaElementVisitor {
     private final boolean myOnTheFly;
     private final LocalQuickFix[] myGenerifyFixes;
 
@@ -194,7 +194,7 @@
       if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
       if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
       final JavaResolveResult result = expression.advancedResolve(false);
-      if (GenericsHighlightUtil.isUncheckedWarning(expression, result)) {
+      if (JavaGenericsUtil.isUncheckedWarning(expression, result)) {
         registerProblem("Unchecked generics array creation for varargs parameter", expression, LocalQuickFix.EMPTY_ARRAY);
       }
     }
@@ -205,7 +205,7 @@
       if (IGNORE_UNCHECKED_GENERICS_ARRAY_CREATION) return;
       if (!PsiUtil.isLanguageLevel5OrHigher(expression)) return;
       final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
-      if (GenericsHighlightUtil.isUncheckedWarning(classReference, expression.resolveMethodGenerics())) {
+      if (JavaGenericsUtil.isUncheckedWarning(classReference, expression.resolveMethodGenerics())) {
         registerProblem("Unchecked generics array creation for varargs parameter", classReference, LocalQuickFix.EMPTY_ARRAY);
       }
     }
@@ -223,9 +223,10 @@
       final PsiType exprType = operand.getType();
       if (exprType == null) return;
       if (!TypeConversionUtil.areTypesConvertible(exprType, castType)) return;
-      if (GenericsHighlightUtil.isUncheckedCast(castType, exprType)) {
+      if (JavaGenericsUtil.isUncheckedCast(castType, exprType)) {
         final String description =
-          JavaErrorMessages.message("generics.unchecked.cast", HighlightUtil.formatType(exprType), HighlightUtil.formatType(castType));
+          JavaErrorMessages.message("generics.unchecked.cast", JavaHighlightUtil.formatType(exprType), JavaHighlightUtil
+            .formatType(castType));
         registerProblem(description, expression, myGenerifyFixes);
       }
     }
@@ -289,7 +290,7 @@
       final PsiType parameterType = parameter.getType();
       final PsiExpression iteratedValue = statement.getIteratedValue();
       if (iteratedValue == null) return;
-      final PsiType itemType = GenericsHighlightUtil.getCollectionItemType(iteratedValue);
+      final PsiType itemType = JavaGenericsUtil.getCollectionItemType(iteratedValue);
       if (!PsiUtil.isLanguageLevel5OrHigher(statement)) return;
       checkRawToGenericsAssignment(parameter, parameterType, itemType, true, myOnTheFly ? getChangeVariableTypeFixes(parameter, itemType) : LocalQuickFix.EMPTY_ARRAY);
     }
@@ -335,12 +336,12 @@
 
         if (itemType == null) continue;
         if (!TypeConversionUtil.isAssignable(componentType, itemType)) continue;
-        if (GenericsHighlightUtil.isRawToGeneric(componentType, itemType)) {
+        if (JavaGenericsUtil.isRawToGeneric(componentType, itemType)) {
           String description = JavaErrorMessages.message("generics.unchecked.assignment",
-                                                         HighlightUtil.formatType(itemType),
-                                                         HighlightUtil.formatType(componentType));
+                                                         JavaHighlightUtil.formatType(itemType),
+                                                         JavaHighlightUtil.formatType(componentType));
           if (!arrayTypeFixChecked) {
-            final PsiType checkResult = HighlightUtil.sameType(initializers);
+            final PsiType checkResult = JavaHighlightUtil.sameType(initializers);
             fix = checkResult != null ? new VariableArrayTypeFix(arrayInitializer, checkResult) : null;
             arrayTypeFixChecked = true;
           }
@@ -359,10 +360,10 @@
                                               @NotNull LocalQuickFix[] quickFixes) {
       if (parameterType == null || itemType == null) return;
       if (checkAssignability && !TypeConversionUtil.isAssignable(parameterType, itemType)) return;
-      if (GenericsHighlightUtil.isRawToGeneric(parameterType, itemType)) {
+      if (JavaGenericsUtil.isRawToGeneric(parameterType, itemType)) {
         String description = JavaErrorMessages.message("generics.unchecked.assignment",
-                                                       HighlightUtil.formatType(itemType),
-                                                       HighlightUtil.formatType(parameterType));
+                                                       JavaHighlightUtil.formatType(itemType),
+                                                       JavaHighlightUtil.formatType(parameterType));
         registerProblem(description, parameter, quickFixes);
       }
     }
@@ -384,10 +385,10 @@
             final PsiType baseReturnType = substitutor.substitute(baseMethod.getReturnType());
             final PsiType overriderReturnType = method.getReturnType();
             if (baseReturnType == null || overriderReturnType == null) return;
-            if (GenericsHighlightUtil.isRawToGeneric(baseReturnType, overriderReturnType)) {
+            if (JavaGenericsUtil.isRawToGeneric(baseReturnType, overriderReturnType)) {
               final String message = JavaErrorMessages.message("unchecked.overriding.incompatible.return.type",
-                                                               HighlightUtil.formatType(overriderReturnType),
-                                                               HighlightUtil.formatType(baseReturnType));
+                                                               JavaHighlightUtil.formatType(overriderReturnType),
+                                                               JavaHighlightUtil.formatType(baseReturnType));
 
               final PsiTypeElement returnTypeElement = method.getReturnTypeElement();
               LOG.assertTrue(returnTypeElement != null);
@@ -470,8 +471,8 @@
           final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(method.getProject()).getElementFactory();
           PsiType type = elementFactory.createType(method.getContainingClass(), substitutor);
           return JavaErrorMessages.message("generics.unchecked.call.to.member.of.raw.type",
-                                                         HighlightUtil.formatMethod(method),
-                                                         HighlightUtil.formatType(type));
+                                                         JavaHighlightUtil.formatMethod(method),
+                                                         JavaHighlightUtil.formatType(type));
         }
       }
       return null;
diff --git a/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java b/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
index 6e90687..1e630d4 100644
--- a/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
+++ b/java/java-impl/src/com/intellij/codeInspection/util/SpecialAnnotationsUtil.java
@@ -16,12 +16,8 @@
 
 package com.intellij.codeInspection.util;
 
-import com.intellij.codeInsight.AnnotationUtil;
 import com.intellij.codeInsight.intention.IntentionAction;
-import com.intellij.codeInspection.InspectionProfile;
 import com.intellij.codeInspection.InspectionsBundle;
-import com.intellij.codeInspection.LocalQuickFix;
-import com.intellij.codeInspection.ProblemDescriptor;
 import com.intellij.ide.DataManager;
 import com.intellij.ide.util.ClassFilter;
 import com.intellij.ide.util.TreeClassChooser;
@@ -32,24 +28,18 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.project.ProjectManager;
 import com.intellij.openapi.ui.Messages;
-import com.intellij.openapi.util.text.StringUtil;
-import com.intellij.profile.codeInspection.InspectionProfileManager;
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.ui.*;
 import com.intellij.ui.components.JBList;
 import com.intellij.util.IconUtil;
 import com.intellij.util.IncorrectOperationException;
-import com.intellij.util.Processor;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 import javax.swing.event.ListDataEvent;
 import javax.swing.event.ListDataListener;
 import java.awt.*;
-import java.util.Collections;
 import java.util.Comparator;
 import java.util.List;
 
@@ -169,7 +159,7 @@
 
       @Override
       public void invoke(@NotNull Project project, Editor editor, PsiFile file) throws IncorrectOperationException {
-        doQuickFixInternal(project, targetList, qualifiedName);
+        SpecialAnnotationsUtilBase.doQuickFixInternal(project, targetList, qualifiedName);
       }
 
       @Override
@@ -178,62 +168,4 @@
       }
     };
   }
-
-  public static LocalQuickFix createAddToSpecialAnnotationsListQuickFix(final String text,
-                                                                        final String family,
-                                                                        final List<String> targetList,
-                                                                        final String qualifiedName,
-                                                                        final PsiElement context) {
-    return new LocalQuickFix() {
-      @Override
-      @NotNull
-      public String getName() {
-        return text;
-      }
-
-      @Override
-      @NotNull
-      public String getFamilyName() {
-        return family;
-      }
-
-      @Override
-      public void applyFix(@NotNull final Project project, @NotNull final ProblemDescriptor descriptor) {
-        doQuickFixInternal(project, targetList, qualifiedName);
-      }
-    };
-  }
-
-  private static void doQuickFixInternal(final Project project, final List<String> targetList, final String qualifiedName) {
-    targetList.add(qualifiedName);
-    Collections.sort(targetList);
-    final InspectionProfile inspectionProfile = InspectionProjectProfileManager.getInstance(project).getInspectionProfile();
-    //correct save settings
-
-    //TODO lesya
-    InspectionProfileManager.getInstance().fireProfileChanged(inspectionProfile);
-    /*
-    try {
-      inspectionProfile.save();
-    }
-    catch (IOException e) {
-      Messages.showErrorDialog(project, e.getMessage(), CommonBundle.getErrorTitle());
-    }
-
-    */
-  }
-
-  public static void createAddToSpecialAnnotationFixes(final PsiModifierListOwner owner, final Processor<String> processor) {
-    final PsiModifierList modifierList = owner.getModifierList();
-    if (modifierList != null) {
-      final PsiAnnotation[] psiAnnotations = modifierList.getAnnotations();
-      for (PsiAnnotation psiAnnotation : psiAnnotations) {
-        @NonNls final String name = psiAnnotation.getQualifiedName();
-        if (name == null) continue;
-        if (name.startsWith("java.") || name.startsWith("javax.") ||
-            (name.startsWith("org.jetbrains.") && AnnotationUtil.isJetbrainsAnnotation(StringUtil.getShortName(name)))) continue;
-        if (!processor.process(name)) break;
-      }
-    }
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
index bbe84bd..6dd3558 100644
--- a/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
+++ b/java/java-impl/src/com/intellij/codeInspection/varScopeCanBeNarrowed/BaseConvertToLocalQuickFix.java
@@ -41,7 +41,7 @@
 import java.util.Set;
 
 /**
- * refactored from {@link com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection.MyQuickFix}
+ * refactored from {@link com.intellij.codeInspection.varScopeCanBeNarrowed.FieldCanBeLocalInspection}
  *
  * @author Danila Ponomarenko
  */
@@ -57,8 +57,8 @@
   @Override
   public final void applyFix(@NotNull Project project, @NotNull ProblemDescriptor descriptor) {
     final V variable = getVariable(descriptor);
-    final PsiFile myFile = variable.getContainingFile();
     if (variable == null || !variable.isValid()) return; //weird. should not get here when field becomes invalid
+    final PsiFile myFile = variable.getContainingFile();
 
     try {
       final PsiElement newDeclaration = moveDeclaration(project, variable);
@@ -142,12 +142,12 @@
     );
   }
 
-  protected PsiElement applyChanges(final @NotNull Project project,
-                                    final @NotNull String localName,
-                                    final @Nullable PsiExpression initializer,
-                                    final @NotNull V variable,
-                                    final @NotNull Collection<PsiReference> references,
-                                    final @NotNull NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
+  protected PsiElement applyChanges(@NotNull final Project project,
+                                    @NotNull final String localName,
+                                    @Nullable final PsiExpression initializer,
+                                    @NotNull final V variable,
+                                    @NotNull final Collection<PsiReference> references,
+                                    @NotNull final NotNullFunction<PsiDeclarationStatement, PsiElement> action) {
     final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(project);
 
     return ApplicationManager.getApplication().runWriteAction(
@@ -202,11 +202,7 @@
 
     final PsiReferenceExpression leftExpression = (PsiReferenceExpression)expression.getLExpression();
 
-    if (!leftExpression.isReferenceTo(variable)) {
-      return false;
-    }
-
-    return true;
+    return leftExpression.isReferenceTo(variable);
   }
 
   @NotNull
@@ -273,9 +269,4 @@
     }
     return result;
   }
-
-
-  public boolean runForWholeFile() {
-    return true;
-  }
 }
diff --git a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
index e6fc026..3f4bd05 100644
--- a/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
+++ b/java/java-impl/src/com/intellij/codeInspection/wrongPackageStatement/WrongPackageStatementInspection.java
@@ -15,105 +15,22 @@
  */
 package com.intellij.codeInspection.wrongPackageStatement;
 
-import com.intellij.codeHighlighting.HighlightDisplayLevel;
-import com.intellij.codeInsight.daemon.JavaErrorMessages;
-import com.intellij.codeInspection.*;
-import com.intellij.openapi.application.ApplicationManager;
-import com.intellij.openapi.util.Comparing;
-import com.intellij.psi.*;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.codeInspection.MoveToPackageFix;
+import com.intellij.psi.PsiFile;
 
-import java.util.ArrayList;
 import java.util.List;
 
 /**
  * User: anna
  * Date: 14-Nov-2005
  */
-public class WrongPackageStatementInspection extends BaseJavaLocalInspectionTool {
+public class WrongPackageStatementInspection extends WrongPackageStatementInspectionBase {
   @Override
-  @Nullable
-  public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
-    // does not work in tests since CodeInsightTestCase copies file into temporary location
-    if (ApplicationManager.getApplication().isUnitTestMode()) return null;
-    if (file instanceof PsiJavaFile) {
-      if (JspPsiUtil.isInJspFile(file)) return null;
-      PsiJavaFile javaFile = (PsiJavaFile)file;
-
-      PsiDirectory directory = javaFile.getContainingDirectory();
-      if (directory == null) return null;
-      PsiPackage dirPackage = JavaDirectoryService.getInstance().getPackage(directory);
-      if (dirPackage == null) return null;
-      PsiPackageStatement packageStatement = javaFile.getPackageStatement();
-
-      // highlight the first class in the file only
-      PsiClass[] classes = javaFile.getClasses();
-      if (classes.length == 0 && packageStatement == null) return null;
-
-      String packageName = dirPackage.getQualifiedName();
-      if (!Comparing.strEqual(packageName, "", true) && packageStatement == null) {
-        String description = JavaErrorMessages.message("missing.package.statement", packageName);
-
-        return new ProblemDescriptor[]{manager.createProblemDescriptor(classes[0].getNameIdentifier(), description,
-                                                                       new AdjustPackageNameFix(packageName),
-                                                                       ProblemHighlightType.GENERIC_ERROR_OR_WARNING, isOnTheFly)};
-      }
-      if (packageStatement != null) {
-        final PsiJavaCodeReferenceElement packageReference = packageStatement.getPackageReference();
-        PsiPackage classPackage = (PsiPackage)packageReference.resolve();
-        List<LocalQuickFix> availableFixes = new ArrayList<LocalQuickFix>();
-        if (classPackage == null || !Comparing.equal(dirPackage.getQualifiedName(), packageReference.getQualifiedName(), true)) {
-          availableFixes.add(new AdjustPackageNameFix(packageName));
-          MoveToPackageFix moveToPackageFix = new MoveToPackageFix(classPackage != null ? classPackage.getQualifiedName() : packageReference.getQualifiedName());
-          if (moveToPackageFix.isAvailable(file)) {
-            availableFixes.add(moveToPackageFix);
-          }
-        }
-        if (!availableFixes.isEmpty()){
-          String description = JavaErrorMessages.message("package.name.file.path.mismatch",
-                                                         packageReference.getQualifiedName(),
-                                                         dirPackage.getQualifiedName());
-          LocalQuickFix[] fixes = availableFixes.toArray(new LocalQuickFix[availableFixes.size()]);
-          ProblemDescriptor descriptor =
-            manager.createProblemDescriptor(packageStatement.getPackageReference(), description, isOnTheFly,
-                                            fixes, ProblemHighlightType.GENERIC_ERROR_OR_WARNING);
-          return new ProblemDescriptor[]{descriptor};
-
-        }
-      }
+  protected void addMoveToPackageFix(PsiFile file, String packName, List<LocalQuickFix> availableFixes) {
+    MoveToPackageFix moveToPackageFix = new MoveToPackageFix(packName);
+    if (moveToPackageFix.isAvailable(file)) {
+      availableFixes.add(moveToPackageFix);
     }
-    return null;
-  }
-
-  @Override
-  @NotNull
-  public String getGroupDisplayName() {
-    return "";
-  }
-
-  @Override
-  @NotNull
-  public HighlightDisplayLevel getDefaultLevel() {
-    return HighlightDisplayLevel.ERROR;
-  }
-
-  @Override
-  @NotNull
-  public String getDisplayName() {
-    return InspectionsBundle.message("wrong.package.statement");
-  }
-
-  @Override
-  @NotNull
-  @NonNls
-  public String getShortName() {
-    return "WrongPackageStatement";
-  }
-
-  @Override
-  public boolean isEnabledByDefault() {
-    return true;
   }
 }
diff --git a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java b/java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
similarity index 98%
rename from java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java
rename to java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
index d1f5bfa..29f991c 100644
--- a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectData.java
+++ b/java/java-impl/src/com/intellij/externalSystem/JavaProjectData.java
@@ -18,7 +18,7 @@
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.externalSystem.model.Key;
 import com.intellij.openapi.externalSystem.model.ProjectSystemId;
-import com.intellij.openapi.externalSystem.model.project.AbstractProjectEntityData;
+import com.intellij.openapi.externalSystem.model.project.AbstractExternalEntityData;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.pom.java.LanguageLevel;
@@ -32,7 +32,7 @@
  * @author Denis Zhdanov
  * @since 4/12/13 12:27 PM
  */
-public class JavaProjectData extends AbstractProjectEntityData {
+public class JavaProjectData extends AbstractExternalEntityData {
   
   @NotNull public static final Key<JavaProjectData> KEY = Key.create(JavaProjectData.class);
   
diff --git a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java b/java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
similarity index 95%
rename from java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
rename to java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
index 626763a..47f4b0a 100644
--- a/java/java-psi-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
+++ b/java/java-impl/src/com/intellij/externalSystem/JavaProjectDataService.java
@@ -17,7 +17,6 @@
 
 import com.intellij.openapi.externalSystem.model.DataNode;
 import com.intellij.openapi.externalSystem.model.Key;
-import com.intellij.openapi.externalSystem.model.ProjectSystemId;
 import com.intellij.openapi.externalSystem.service.project.manage.ProjectDataService;
 import com.intellij.openapi.externalSystem.util.ExternalSystemApiUtil;
 import com.intellij.openapi.project.Project;
@@ -106,7 +105,7 @@
     if (languageLevelExtension.getLanguageLevel().isAtLeast(languageLevel)) {
       return;
     }
-    ExternalSystemApiUtil.executeProjectChangeAction(project, ProjectSystemId.IDE, synchronous, new Runnable() {
+    ExternalSystemApiUtil.executeProjectChangeAction(synchronous, new Runnable() {
       @Override
       public void run() {
         languageLevelExtension.setLanguageLevel(languageLevel);
diff --git a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
index 4f49420..de3446e 100644
--- a/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
+++ b/java/java-impl/src/com/intellij/ide/actions/JavaQualifiedNameProvider.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.ide.actions;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.editor.Document;
 import com.intellij.openapi.editor.Editor;
@@ -220,7 +220,7 @@
         catch (IncorrectOperationException e) {
           // failed to bind
         }
-        if (referenceExpression.isValid() && !isReferencedTo(referenceExpression, targetElement)) {
+        if (!referenceExpression.isValid() || !isReferencedTo(referenceExpression, targetElement)) {
           toInsert = fqn;
         }
       }
@@ -241,7 +241,7 @@
         LOG.error(e);
       }
     }
-    CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(file);
+    CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(file);
     try {
       CodeStyleManager.getInstance(project).adjustLineIndent(file, offset);
     }
diff --git a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
index cec7c4a..c4d1369 100644
--- a/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
+++ b/java/java-impl/src/com/intellij/ide/highlighter/JavaFileHighlighter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -18,7 +18,6 @@
 import com.intellij.lexer.JavaHighlightingLexer;
 import com.intellij.lexer.Lexer;
 import com.intellij.openapi.editor.HighlighterColors;
-import com.intellij.openapi.editor.SyntaxHighlighterColors;
 import com.intellij.openapi.editor.colors.TextAttributesKey;
 import com.intellij.openapi.fileTypes.SyntaxHighlighterBase;
 import com.intellij.pom.java.LanguageLevel;
@@ -39,21 +38,11 @@
   private static final Map<IElementType, TextAttributesKey> ourMap1;
   private static final Map<IElementType, TextAttributesKey> ourMap2;
 
-  private final LanguageLevel myLanguageLevel;
-
-  public JavaFileHighlighter() {
-    this(LanguageLevel.HIGHEST);
-  }
-
-  public JavaFileHighlighter(LanguageLevel languageLevel) {
-    myLanguageLevel = languageLevel;
-  }
-
   static {
     ourMap1 = new HashMap<IElementType, TextAttributesKey>();
     ourMap2 = new HashMap<IElementType, TextAttributesKey>();
 
-    fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, JavaHighlightingColors .KEYWORD);
+    fillMap(ourMap1, ElementType.KEYWORD_BIT_SET, JavaHighlightingColors.KEYWORD);
     fillMap(ourMap1, ElementType.LITERAL_BIT_SET, JavaHighlightingColors.KEYWORD);
     fillMap(ourMap1, ElementType.OPERATION_BIT_SET, JavaHighlightingColors.OPERATION_SIGN);
 
@@ -96,25 +85,28 @@
     ourMap1.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT);
     ourMap2.put(JavaDocTokenType.DOC_TAG_NAME, JavaHighlightingColors.DOC_COMMENT_TAG);
 
-    IElementType[] javaDocMarkup = new IElementType[]{XmlTokenType.XML_START_TAG_START,
-                                        XmlTokenType.XML_END_TAG_START,
-                                        XmlTokenType.XML_TAG_END,
-                                        XmlTokenType.XML_EMPTY_ELEMENT_END,
-                                        XmlTokenType.TAG_WHITE_SPACE,
-                                        XmlTokenType.XML_TAG_NAME,
-                                        XmlTokenType.XML_NAME,
-                                        XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN,
-                                        XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER,
-                                        XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER,
-                                        XmlTokenType.XML_CHAR_ENTITY_REF,
-                                        XmlTokenType.XML_EQ};
-
+    IElementType[] javaDocMarkup = {
+      XmlTokenType.XML_START_TAG_START, XmlTokenType.XML_END_TAG_START, XmlTokenType.XML_TAG_END, XmlTokenType.XML_EMPTY_ELEMENT_END,
+      XmlTokenType.TAG_WHITE_SPACE, XmlTokenType.XML_TAG_NAME, XmlTokenType.XML_NAME, XmlTokenType.XML_ATTRIBUTE_VALUE_TOKEN,
+      XmlTokenType.XML_ATTRIBUTE_VALUE_START_DELIMITER, XmlTokenType.XML_ATTRIBUTE_VALUE_END_DELIMITER, XmlTokenType.XML_CHAR_ENTITY_REF,
+      XmlTokenType.XML_EQ
+    };
     for (IElementType idx : javaDocMarkup) {
       ourMap1.put(idx, JavaHighlightingColors.DOC_COMMENT);
       ourMap2.put(idx, JavaHighlightingColors.DOC_COMMENT_MARKUP);
     }
   }
 
+  private final LanguageLevel myLanguageLevel;
+
+  public JavaFileHighlighter() {
+    this(LanguageLevel.HIGHEST);
+  }
+
+  public JavaFileHighlighter(@NotNull LanguageLevel languageLevel) {
+    myLanguageLevel = languageLevel;
+  }
+
   @NotNull
   public Lexer getHighlightingLexer() {
     return new JavaHighlightingLexer(myLanguageLevel);
diff --git a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
index 2aae5d8..e8197bb 100644
--- a/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
+++ b/java/java-impl/src/com/intellij/ide/projectView/impl/ClassesTreeStructureProvider.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -21,10 +21,12 @@
 import com.intellij.ide.projectView.impl.nodes.ClassTreeNode;
 import com.intellij.ide.projectView.impl.nodes.PsiFileNode;
 import com.intellij.ide.util.treeView.AbstractTreeNode;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.project.DumbAware;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.jsp.JspFile;
@@ -67,7 +69,12 @@
         }
 
         if (fileInRoots(file)) {
-          PsiClass[] classes = classOwner.getClasses();
+          PsiClass[] classes = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass[]>() {
+            @Override
+            public PsiClass[] compute() {
+              return classOwner.getClasses();
+            }
+          });
           if (classes.length == 1 && !(classes[0] instanceof SyntheticElement) &&
               (file == null || file.getNameWithoutExtension().equals(classes[0].getName()))) {
             result.add(new ClassTreeNode(myProject, classes[0], settings1));
diff --git a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
index 245f342..2ad3edc 100644
--- a/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
+++ b/java/java-impl/src/com/intellij/ide/util/PackageChooserDialog.java
@@ -22,6 +22,11 @@
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.event.*;
+import com.intellij.openapi.editor.event.DocumentAdapter;
+import com.intellij.openapi.fileChooser.ex.FileChooserDialogImpl;
+import com.intellij.openapi.fileChooser.ex.TextFieldAction;
+import com.intellij.openapi.fileTypes.StdFileTypes;
 import com.intellij.openapi.module.Module;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.roots.ContentIterator;
@@ -35,9 +40,10 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
-import com.intellij.ui.ScrollPaneFactory;
-import com.intellij.ui.TreeSpeedSearch;
+import com.intellij.ui.*;
+import com.intellij.ui.components.labels.LinkLabel;
 import com.intellij.ui.treeStructure.Tree;
+import com.intellij.util.Alarm;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.PlatformIcons;
 import com.intellij.util.containers.Convertor;
@@ -66,6 +72,9 @@
   private final Project myProject;
   private final String myTitle;
   private Module myModule;
+  private EditorTextField myPathEditor;
+
+  private Alarm myAlarm = new Alarm(getDisposable()); 
 
   public PackageChooserDialog(String title, @NotNull Module module) {
     super(module.getProject(), true);
@@ -147,19 +156,69 @@
         else {
           setTitle(myTitle);
         }
+        updatePathFromTree();
       }
     });
 
     panel.add(scrollPane, BorderLayout.CENTER);
     DefaultActionGroup group = createActionGroup(myTree);
 
+    final JPanel northPanel = new JPanel(new BorderLayout());
+    panel.add(northPanel, BorderLayout.NORTH);
     ActionToolbar toolBar = ActionManager.getInstance().createActionToolbar(ActionPlaces.UNKNOWN, group, true);
-    panel.add(toolBar.getComponent(), BorderLayout.NORTH);
-    toolBar.getComponent().setAlignmentX(JComponent.LEFT_ALIGNMENT);
-
+    northPanel.add(toolBar.getComponent(), BorderLayout.WEST);
+    setupPathComponent(northPanel);
     return panel;
   }
 
+  private void setupPathComponent(final JPanel northPanel) {
+    northPanel.add(new TextFieldAction() {
+      @Override
+      public void linkSelected(LinkLabel aSource, Object aLinkData) {
+        toggleShowPathComponent(northPanel, this);
+      }
+    }, BorderLayout.EAST);
+    myPathEditor = new EditorTextField(JavaReferenceEditorUtil.createDocument("", myProject, false), myProject, StdFileTypes.JAVA);
+    myPathEditor.addDocumentListener(new DocumentAdapter() {
+      @Override
+      public void documentChanged(DocumentEvent e) {
+        myAlarm.cancelAllRequests();
+        myAlarm.addRequest(new Runnable() {
+          @Override
+          public void run() {
+            updateTreeFromPath();
+          }
+        }, 300);
+      }
+    });
+    myPathEditor.setBorder(BorderFactory.createEmptyBorder(0, 0, 2, 0));
+    northPanel.add(myPathEditor, BorderLayout.SOUTH);
+  }
+
+  private void toggleShowPathComponent(JPanel northPanel, TextFieldAction fieldAction) {
+    boolean toShowTextField = !isPathShowing();
+    PropertiesComponent.getInstance().setValue(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, Boolean.toString(toShowTextField));
+    myPathEditor.setVisible(toShowTextField);
+    fieldAction.update();
+    northPanel.revalidate();
+    northPanel.repaint();
+    updatePathFromTree();
+  }
+
+  private static boolean isPathShowing() {
+    return PropertiesComponent.getInstance().getBoolean(FileChooserDialogImpl.FILE_CHOOSER_SHOW_PATH_PROPERTY, true);
+  }
+
+  private void updatePathFromTree() {
+    if (!isPathShowing()) return;
+    final PsiPackage selection = getTreeSelection();
+    myPathEditor.setText(selection != null ? selection.getQualifiedName() : "");
+  }
+
+  private void updateTreeFromPath() {
+    selectPackage(myPathEditor.getText().trim());
+  }
+  
   private DefaultActionGroup createActionGroup(JComponent component) {
     final DefaultActionGroup group = new DefaultActionGroup();
     final DefaultActionGroup temp = new DefaultActionGroup();
diff --git a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
index 15c17f6..eb09ceb 100644
--- a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
+++ b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningDialog.java
@@ -80,12 +80,19 @@
                                  ? IdeBundle.message("label.overrides.method.of_class_or_interface.name", methodString, classType, className)
                                  : IdeBundle.message("label.implements.method.of_class_or_interface.name", methodString, classType, className)));
     } else {
-      labelsPanel.add(new JLabel(IdeBundle.message("label.implements.method.of_interfaces")));
+      final JLabel multLabel = new JLabel(IdeBundle.message("label.implements.method.of_interfaces"));
+      multLabel.setBorder(BorderFactory.createEmptyBorder(0, 0, 5, 0));
+      labelsPanel.add(multLabel);
+ 
       for (final String className : myClassNames) {
         labelsPanel.add(new JLabel("    " + className));
       }
     }
-    labelsPanel.add(new JLabel(IdeBundle.message("prompt.do.you.want.to.action_verb.the.method.from_class", myActionString, myClassNames.length > 1 ? 2 : 1)));
+ 
+    final JLabel doYouWantLabel = new JLabel(
+      IdeBundle.message("prompt.do.you.want.to.action_verb.the.method.from_class", myActionString, myClassNames.length > 1 ? 2 : 1));
+    doYouWantLabel.setBorder(BorderFactory.createEmptyBorder(5, 0, 0, 0));
+    labelsPanel.add(doYouWantLabel);
     panel.add(labelsPanel, BorderLayout.CENTER);
     return panel;
   }
diff --git a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
index 5ac29a8..efb05d7 100644
--- a/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
+++ b/java/java-impl/src/com/intellij/ide/util/SuperMethodWarningUtil.java
@@ -15,9 +15,12 @@
  */
 package com.intellij.ide.util;
 
+import com.intellij.codeInspection.InspectionsBundle;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.editor.Editor;
 import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.ui.popup.JBPopupFactory;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiElement;
@@ -27,7 +30,6 @@
 import com.intellij.psi.search.PsiElementProcessor;
 import com.intellij.psi.search.searches.DeepestSuperMethodsSearch;
 import com.intellij.ui.components.JBList;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.ArrayUtil;
 import org.jetbrains.annotations.NotNull;
 
@@ -68,7 +70,7 @@
     }
 
     SuperMethodWarningDialog dialog =
-        new SuperMethodWarningDialog(method.getProject(), UsageViewUtil.getDescriptiveName(method), actionString, superAbstract,
+        new SuperMethodWarningDialog(method.getProject(), DescriptiveNameUtil.getDescriptiveName(method), actionString, superAbstract,
                                      parentInterface, aClass.isInterface(), ArrayUtil.toStringArray(superClasses));
     dialog.show();
 
@@ -97,7 +99,7 @@
     SuperMethodWarningDialog dialog =
         new SuperMethodWarningDialog(
             method.getProject(),
-            UsageViewUtil.getDescriptiveName(method), actionString, containingClass.isInterface() || superMethod.hasModifierProperty(PsiModifier.ABSTRACT),
+            DescriptiveNameUtil.getDescriptiveName(method), actionString, containingClass.isInterface() || superMethod.hasModifierProperty(PsiModifier.ABSTRACT),
             containingClass.isInterface(), aClass.isInterface(), containingClass.getQualifiedName()
         );
     dialog.show();
@@ -154,4 +156,16 @@
         }
       }).createPopup().showInBestPositionFor(editor);
   }
+
+  public static int askWhetherShouldAnnotateBaseMethod(@NotNull PsiMethod method, @NotNull PsiMethod superMethod) {
+    String implement = !method.hasModifierProperty(PsiModifier.ABSTRACT) && superMethod.hasModifierProperty(PsiModifier.ABSTRACT)
+                  ? InspectionsBundle.message("inspection.annotate.quickfix.implements")
+                  : InspectionsBundle.message("inspection.annotate.quickfix.overrides");
+    String message = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.messages",
+                                               DescriptiveNameUtil.getDescriptiveName(method), implement,
+                                               DescriptiveNameUtil.getDescriptiveName(superMethod));
+    String title = InspectionsBundle.message("inspection.annotate.quickfix.overridden.method.warning");
+    return Messages.showYesNoCancelDialog(method.getProject(), message, title, Messages.getQuestionIcon());
+
+  }
 }
\ No newline at end of file
diff --git a/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java b/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
index 075e091..99826b8 100644
--- a/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
+++ b/java/java-impl/src/com/intellij/ide/util/scopeChooser/ClassHierarchyScopeDescriptor.java
@@ -30,7 +30,7 @@
 import com.intellij.psi.search.LocalSearchScope;
 import com.intellij.psi.search.SearchScope;
 import com.intellij.psi.search.searches.ClassInheritorsSearch;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.LinkedList;
@@ -64,7 +64,7 @@
 
       classesToSearch.addAll(ClassInheritorsSearch.search(aClass, true).findAll());
 
-      myCachedScope = new LocalSearchScope(PsiUtilBase.toPsiElementArray(classesToSearch),
+      myCachedScope = new LocalSearchScope(PsiUtilCore.toPsiElementArray(classesToSearch),
                                            IdeBundle.message("scope.hierarchy", ClassPresentationUtil.getNameForClass(aClass, true)));
     }
 
diff --git a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
index 87d9e78..918b8ff 100644
--- a/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
+++ b/java/java-impl/src/com/intellij/lang/java/JavaSyntaxHighlighterFactory.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2011 JetBrains s.r.o.
+ * 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.
@@ -16,19 +16,44 @@
 package com.intellij.lang.java;
 
 import com.intellij.ide.highlighter.JavaFileHighlighter;
+import com.intellij.openapi.fileTypes.FileType;
 import com.intellij.openapi.fileTypes.SyntaxHighlighter;
 import com.intellij.openapi.fileTypes.SyntaxHighlighterFactory;
+import com.intellij.openapi.fileTypes.SyntaxHighlighterProvider;
 import com.intellij.openapi.module.LanguageLevelUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.impl.compiled.ClsFileImpl;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
-public class JavaSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
+public class JavaSyntaxHighlighterFactory extends SyntaxHighlighterFactory implements SyntaxHighlighterProvider {
+  /**
+   * SyntaxHighlighterFactory implementation (for Java source files).
+   */
   @Override
   @NotNull
-  public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
-    return new JavaFileHighlighter(
-      virtualFile != null ? LanguageLevelUtil.getLanguageLevelForFile(virtualFile) : LanguageLevel.HIGHEST);
+  public SyntaxHighlighter getSyntaxHighlighter(@Nullable Project project, @Nullable VirtualFile file) {
+    return new JavaFileHighlighter(LanguageLevelUtil.getLanguageLevelForFile(file));
+  }
+
+  /**
+   * SyntaxHighlighterProvider implementation (for class files).
+   */
+  @Nullable
+  @Override
+  public SyntaxHighlighter create(FileType fileType, @Nullable Project project, @Nullable VirtualFile file) {
+    if (project != null && file != null) {
+      PsiFile psiFile = PsiManager.getInstance(project).findFile(file);
+      if (psiFile instanceof ClsFileImpl) {
+        LanguageLevel sourceLevel = ((ClsFileImpl)psiFile).getSourceLanguageLevel();
+        return new JavaFileHighlighter(sourceLevel);
+      }
+    }
+
+    return new JavaFileHighlighter();
   }
 }
diff --git a/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java b/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
index 5404d0a..e1d50a7 100644
--- a/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
+++ b/java/java-impl/src/com/intellij/profile/codeInspection/JavaAwareInspectionProfileManager.java
@@ -25,7 +25,7 @@
 import com.intellij.codeInspection.ex.InspectionToolRegistrar;
 import com.intellij.openapi.options.SchemesManagerFactory;
 
-public class JavaAwareInspectionProfileManager extends InspectionProfileManager{
+public class JavaAwareInspectionProfileManager extends InspectionProfileManagerImpl {
   public JavaAwareInspectionProfileManager(InspectionToolRegistrar registrar, SchemesManagerFactory schemesManagerFactory) {
     super(registrar, schemesManagerFactory);
   }
diff --git a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
index 5853791..d26892e 100644
--- a/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
+++ b/java/java-impl/src/com/intellij/psi/AbstractQualifiedReference.java
@@ -40,7 +40,8 @@
 /**
  * @author peter
  */
-public abstract class AbstractQualifiedReference<T extends AbstractQualifiedReference<T>> extends ASTWrapperPsiElement implements PsiPolyVariantReference, PsiQualifiedReference {
+public abstract class AbstractQualifiedReference<T extends AbstractQualifiedReference<T>> extends ASTWrapperPsiElement
+  implements PsiPolyVariantReference, PsiQualifiedReferenceElement {
   private static final ResolveCache.PolyVariantResolver<AbstractQualifiedReference> MY_RESOLVER = new ResolveCache.PolyVariantResolver<AbstractQualifiedReference>() {
     @NotNull
     @Override
diff --git a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
index 89c7d47..001745c 100644
--- a/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
+++ b/java/java-impl/src/com/intellij/psi/codeStyle/arrangement/JavaRearranger.java
@@ -292,7 +292,7 @@
     and(matchRules, CLASS, STATIC);
     and(matchRules, CLASS);
 
-    return new StdArrangementSettings(groupingRules, matchRules);
+    return new StdRulePriorityAwareSettings(groupingRules, matchRules);
   }
 
   @Nullable
diff --git a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
index 611992b..6f5b426 100644
--- a/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
+++ b/java/java-impl/src/com/intellij/psi/impl/light/LightParameter.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -30,7 +30,7 @@
   private final boolean myVarArgs;
 
   public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language) {
-    this(name, type, declarationScope, language, false);
+    this(name, type, declarationScope, language, type instanceof PsiEllipsisType);
   }
 
   public LightParameter(@NotNull String name, @NotNull PsiType type, PsiElement declarationScope, Language language, boolean isVarArgs) {
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
index a75bca9..4239f03 100644
--- a/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
+++ b/java/java-impl/src/com/intellij/psi/impl/smartPointers/ImplicitVariableElementInfoFactory.java
@@ -15,16 +15,11 @@
  */
 package com.intellij.psi.impl.smartPointers;
 
-import com.intellij.openapi.editor.Document;
-import com.intellij.openapi.editor.RangeMarker;
 import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Segment;
-import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.ImplicitVariable;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiIdentifier;
-import com.intellij.psi.util.PsiUtilCore;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -38,69 +33,25 @@
     return null;
   }
 
-  private static class ImplicitVariableInfo implements SmartPointerElementInfo {
-    private final ImplicitVariable myVar;
-    private final Project myProject;
-
+  private static class ImplicitVariableInfo extends HardElementInfo {
     public ImplicitVariableInfo(@NotNull ImplicitVariable var, @NotNull Project project) {
-      myVar = var;
-      myProject = project;
+      super(project, var);
     }
 
     @Override
     public PsiElement restoreElement() {
+      ImplicitVariable myVar = (ImplicitVariable)super.restoreElement();
       PsiIdentifier psiIdentifier = myVar.getNameIdentifier();
       if (psiIdentifier == null || psiIdentifier.isValid()) return myVar;
       return null;
     }
 
     @Override
-    @Nullable
-    public Document getDocumentToSynchronize() {
-      return null;
-    }
-
-    @Override
-    public void documentAndPsiInSync() {
-    }
-
-    @Override
-    public void fastenBelt(int offset, RangeMarker[] cachedRangeMarker) {
-    }
-
-    @Override
-    public void unfastenBelt(int offset) {
-    }
-
-    @Override
-    public int elementHashCode() {
-      return myVar.hashCode();
-    }
-
-    @Override
-    public boolean pointsToTheSameElementAs(@NotNull SmartPointerElementInfo other) {
-      if (other instanceof ImplicitVariableInfo) {
-        return myVar == ((ImplicitVariableInfo)other).myVar;
-      }
-      return Comparing.equal(restoreElement(), other.restoreElement());
-    }
-
-    @Override
-    public VirtualFile getVirtualFile() {
-      return PsiUtilCore.getVirtualFile(myVar);
-    }
-
-    @Override
     public Segment getRange() {
+      ImplicitVariable myVar = (ImplicitVariable)super.restoreElement();
       PsiIdentifier psiIdentifier = myVar.getNameIdentifier();
       if (psiIdentifier == null || !psiIdentifier.isValid()) return null;
       return psiIdentifier.getTextRange();
     }
-
-    @NotNull
-    @Override
-    public Project getProject() {
-      return myProject;
-    }
   }
 }
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
index a25476a..0f9e286 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/codeStyle/ReferenceAdjuster.java
@@ -207,15 +207,15 @@
 
   private static ASTNode makeShortReference(@NotNull CompositeElement reference, @NotNull PsiClass refClass, boolean addImports) {
     @NotNull final PsiJavaCodeReferenceElement psiReference = (PsiJavaCodeReferenceElement)reference.getPsi();
-    final PsiQualifiedReference reference1 = getClassReferenceToShorten(refClass, addImports, psiReference);
+    final PsiQualifiedReferenceElement reference1 = getClassReferenceToShorten(refClass, addImports, psiReference);
     if (reference1 != null) replaceReferenceWithShort(reference1);
     return reference;
   }
 
   @Nullable
-  public static PsiQualifiedReference getClassReferenceToShorten(@NotNull final PsiClass refClass,
+  public static PsiQualifiedReferenceElement getClassReferenceToShorten(@NotNull final PsiClass refClass,
                                                                  final boolean addImports,
-                                                                 @NotNull final PsiQualifiedReference reference) {
+                                                                 @NotNull final PsiQualifiedReferenceElement reference) {
     PsiClass parentClass = refClass.getContainingClass();
     if (parentClass != null) {
       JavaPsiFacade facade = JavaPsiFacade.getInstance(parentClass.getProject());
@@ -227,7 +227,7 @@
       if (!CodeStyleSettingsManager.getSettings(reference.getProject()).INSERT_INNER_CLASS_IMPORTS) {
         final PsiElement qualifier = reference.getQualifier();
         if (qualifier instanceof PsiQualifiedReference) {
-          return getClassReferenceToShorten(parentClass, addImports, (PsiQualifiedReference)qualifier);
+          return getClassReferenceToShorten(parentClass, addImports, (PsiQualifiedReferenceElement)qualifier);
         }
         return null;
       }
@@ -255,7 +255,7 @@
   }
 
   @NotNull
-  private static ASTNode replaceReferenceWithShort(PsiQualifiedReference reference) {
+  private static ASTNode replaceReferenceWithShort(PsiQualifiedReferenceElement reference) {
     ASTNode node = reference.getNode();
     assert node != null;
     deQualifyImpl((CompositeElement)node);
diff --git a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
index 6e34ca2..f6ba9fd 100644
--- a/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
+++ b/java/java-impl/src/com/intellij/psi/impl/source/tree/JavaTreeGenerator.java
@@ -114,10 +114,10 @@
     if (original instanceof PsiCompiledElement) {
       PsiElement sourceVersion = original.getNavigationElement();
       if (sourceVersion != original) {
-        return ChangeUtil.generateTreeElement(sourceVersion, table,manager);
+        return ChangeUtil.generateTreeElement(sourceVersion, table, manager);
       }
-      ASTNode mirror = SourceTreeToPsiMap.psiElementToTree(((PsiCompiledElement)original).getMirror());
-      return ChangeUtil.generateTreeElement(SourceTreeToPsiMap.treeElementToPsi(mirror), table,manager);
+      PsiElement mirror = ((PsiCompiledElement)original).getMirror();
+      return ChangeUtil.generateTreeElement(mirror, table, manager);
     }
 
     if (original instanceof PsiTypeElement) {
diff --git a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
index 3f6d158..7bca3c0 100644
--- a/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/anonymousToInner/AnonymousToInnerDialog.java
@@ -30,6 +30,7 @@
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.refactoring.util.ParameterTablePanel;
 import com.intellij.refactoring.util.RefactoringMessageUtil;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.NonFocusableCheckBox;
 import com.intellij.util.Function;
@@ -49,7 +50,7 @@
   private final boolean myShowCanBeStatic;
 
   private NameSuggestionsField myNameField;
-  private final ParameterTablePanel.VariableData[] myVariableData;
+  private final VariableData[] myVariableData;
   private final Map<PsiVariable,VariableInfo> myVariableToInfoMap = new HashMap<PsiVariable, VariableInfo>();
   private JCheckBox myCbMakeStatic;
 
@@ -65,7 +66,7 @@
     for (VariableInfo info : variableInfos) {
       myVariableToInfoMap.put(info.variable, info);
     }
-    myVariableData = new ParameterTablePanel.VariableData[variableInfos.length];
+    myVariableData = new VariableData[variableInfos.length];
 
     final JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
     for(int idx = 0; idx < variableInfos.length; idx++){
@@ -74,7 +75,7 @@
       VariableKind kind = codeStyleManager.getVariableKind(info.variable);
       name = codeStyleManager.variableNameToPropertyName(name, kind);
       name = codeStyleManager.propertyNameToVariableName(name, VariableKind.PARAMETER);
-      ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(info.variable);
+      VariableData data = new VariableData(info.variable);
       data.name = name;
       data.passAsParameter = true;
       myVariableData[idx] = data;
@@ -127,7 +128,7 @@
     JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
     VariableInfo[] infos = new VariableInfo[myVariableData.length];
     for (int idx = 0; idx < myVariableData.length; idx++) {
-      ParameterTablePanel.VariableData data = myVariableData[idx];
+      VariableData data = myVariableData[idx];
       VariableInfo info = myVariableToInfoMap.get(data.variable);
 
       info.passAsParameter = data.passAsParameter;
diff --git a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
index f8ff36b..f8e27c4 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeClassSignature/ChangeClassSignatureDialog.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.changeClassSignature;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.psi.*;
@@ -27,7 +28,6 @@
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.ui.*;
 import com.intellij.ui.table.JBTable;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.containers.ContainerUtil;
 import com.intellij.util.ui.EditableModel;
 import org.jetbrains.annotations.NotNull;
@@ -116,7 +116,7 @@
   }
 
   protected JComponent createNorthPanel() {
-    return new JLabel(RefactoringBundle.message("changeClassSignature.class.label.text", UsageViewUtil.getDescriptiveName(myClass)));
+    return new JLabel(RefactoringBundle.message("changeClassSignature.class.label.text", DescriptiveNameUtil.getDescriptiveName(myClass)));
   }
 
   @Override
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
index e1ad62f..250efce 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/DetectedJavaChangeInfo.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.changeSignature;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.openapi.editor.Document;
@@ -25,7 +26,6 @@
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.util.CanonicalTypes;
 import com.intellij.usageView.UsageInfo;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 import org.jetbrains.annotations.NotNull;
@@ -288,7 +288,7 @@
               temporallyRevertChanges(method, oldText);
               doRefactor(processor);
             }
-          }, RefactoringBundle.message("changing.signature.of.0", UsageViewUtil.getDescriptiveName(currentMethod)), null);
+          }, RefactoringBundle.message("changing.signature.of.0", DescriptiveNameUtil.getDescriptiveName(currentMethod)), null);
         }
 
         private void doRefactor(BaseRefactoringProcessor processor) {
diff --git a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
index e480912..cc4d0cd 100644
--- a/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/changeSignature/JavaChangeSignatureUsageProcessor.java
@@ -16,6 +16,7 @@
 package com.intellij.refactoring.changeSignature;
 
 import com.intellij.codeInsight.ExceptionUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.lang.StdLanguages;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
@@ -245,7 +246,7 @@
 
     if (toCatchExceptions) {
       if (!(ref instanceof PsiReferenceExpression &&
-            RefactoringUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) {
+            JavaHighlightUtil.isSuperOrThisCall(PsiTreeUtil.getParentOfType(ref, PsiStatement.class), true, false))) {
         if (needToCatchExceptions(changeInfo, caller)) {
           PsiClassType[] newExceptions =
             callee != null ? getCalleeChangedExceptionInfo(callee) : getPrimaryChangedExceptionInfo(changeInfo);
diff --git a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
index c3b911b..180e28d 100644
--- a/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/encapsulateFields/EncapsulateFieldsProcessor.java
@@ -16,6 +16,7 @@
  */
 package com.intellij.refactoring.encapsulateFields;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
@@ -75,7 +76,7 @@
   }
 
   protected String getCommandName() {
-    return RefactoringBundle.message("encapsulate.fields.command.name", UsageViewUtil.getDescriptiveName(myClass));
+    return RefactoringBundle.message("encapsulate.fields.command.name", DescriptiveNameUtil.getDescriptiveName(myClass));
   }
 
   protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
index 1e2448e..061d04e 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractInterface/ExtractInterfaceHandler.java
@@ -17,6 +17,7 @@
 
 import com.intellij.history.LocalHistory;
 import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
@@ -34,7 +35,6 @@
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.refactoring.util.DocCommentPolicy;
 import com.intellij.refactoring.util.classMembers.MemberInfo;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.MultiMap;
@@ -150,7 +150,7 @@
   }
 
   private String getCommandName() {
-    return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, UsageViewUtil.getDescriptiveName(myClass));
+    return RefactoringBundle.message("extract.interface.command.name", myInterfaceName, DescriptiveNameUtil.getDescriptiveName(myClass));
   }
 
   public boolean isEnabledOnElements(PsiElement[] elements) {
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
index 2e4531c..7e49181 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/AbstractExtractDialog.java
@@ -23,7 +23,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.DialogWrapper;
 import com.intellij.psi.PsiModifier;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 
 public abstract class AbstractExtractDialog extends DialogWrapper {
   protected AbstractExtractDialog(Project project) {
@@ -33,7 +33,7 @@
 
   public abstract String getChosenMethodName();
 
-  public abstract ParameterTablePanel.VariableData[] getChosenParameters();
+  public abstract VariableData[] getChosenParameters();
 
   @PsiModifier.ModifierConstant
   public abstract String getVisibility();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
index 5e64113..0f31912 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodDialog.java
@@ -32,6 +32,7 @@
 import com.intellij.refactoring.ui.MethodSignatureComponent;
 import com.intellij.refactoring.util.ConflictsUtil;
 import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.ui.EditorTextField;
 import com.intellij.ui.IdeBorderFactory;
 import com.intellij.ui.NonFocusableCheckBox;
@@ -81,7 +82,7 @@
   private final JCheckBox myFoldParameters = new NonFocusableCheckBox(RefactoringBundle.message("declare.folded.parameters"));
   public JPanel myCenterPanel;
   public JPanel myParamTable;
-  private ParameterTablePanel.VariableData[] myInputVariables;
+  private VariableData[] myInputVariables;
 
   public ExtractMethodDialog(Project project,
                              PsiClass targetClass, final InputVariables inputVariables, PsiType returnType,
@@ -156,7 +157,7 @@
     return myNameField.getText();
   }
 
-  public ParameterTablePanel.VariableData[] getChosenParameters() {
+  public VariableData[] getChosenParameters() {
     return myInputVariables;
   }
 
@@ -182,7 +183,7 @@
     }
 
     if (myMakeVarargs != null && myMakeVarargs.isSelected()) {
-      final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1];
+      final VariableData data = myInputVariables[myInputVariables.length - 1];
       if (data.type instanceof PsiArrayType) {
         data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType());
       }
@@ -243,12 +244,12 @@
     myFoldParameters.setSelected(myVariableData.isFoldingSelectedByDefault());
     myFoldParameters.setVisible(myVariableData.isFoldable());
     myVariableData.setFoldingAvailable(myFoldParameters.isSelected());
-    myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+    myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
     myFoldParameters.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         myVariableData.setFoldingAvailable(myFoldParameters.isSelected());
         myInputVariables =
-          myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+          myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
         updateVarargsEnabled();
         createParametersPanel();
         updateSignature();
@@ -258,7 +259,7 @@
     myFoldParameters.setBorder(emptyBorder);
 
     boolean canBeVarargs = false;
-    for (ParameterTablePanel.VariableData data : myInputVariables) {
+    for (VariableData data : myInputVariables) {
       canBeVarargs |= data.type instanceof PsiArrayType;
     }
     if (myVariableData.isFoldable()) {
@@ -453,10 +454,10 @@
 
     final String INDENT = StringUtil.repeatSymbol(' ', buffer.length());
 
-    final ParameterTablePanel.VariableData[] datas = myInputVariables;
+    final VariableData[] datas = myInputVariables;
     int count = 0;
     for (int i = 0; i < datas.length;i++) {
-      ParameterTablePanel.VariableData data = datas[i];
+      VariableData data = datas[i];
       if (data.passAsParameter) {
         //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable,
         //  PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE);
@@ -500,7 +501,7 @@
       PsiElementFactory factory = JavaPsiFacade.getInstance(myProject).getElementFactory();
       prototype = factory.createMethod(myNameField.getText().trim(), myReturnType);
       if (myTypeParameterList != null) prototype.getTypeParameterList().replace(myTypeParameterList);
-      for (ParameterTablePanel.VariableData data : myInputVariables) {
+      for (VariableData data : myInputVariables) {
         if (data.passAsParameter) {
           prototype.getParameterList().add(factory.createParameter(data.name, data.type));
         }
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
index 70d031b..21de8fc 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodHandler.java
@@ -16,6 +16,7 @@
 package com.intellij.refactoring.extractMethod;
 
 import com.intellij.codeInsight.CodeInsightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.LangDataKeys;
@@ -80,8 +81,7 @@
     editor.getScrollingModel().scrollToCaret(ScrollType.MAKE_VISIBLE);
     if (!editor.getSelectionModel().hasSelection()) {
       final int offset = editor.getCaretModel().getOffset();
-      final PsiElement[] statementsInRange = IntroduceVariableBase.findStatementsAtOffset(editor, file, offset);
-      final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
+      final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, true);
       if (expressions.isEmpty()) {
         editor.getSelectionModel().selectLineAtCaret();
       }
@@ -166,7 +166,7 @@
                                                      final Project project,
                                                      final PsiFile file,
                                                      final Editor editor,
-                                                     final boolean showErrorMessages, 
+                                                     final boolean showErrorMessages,
                                                      final @Nullable Pass<ExtractMethodProcessor> pass) {
     if (elements == null || elements.length == 0) {
       if (showErrorMessages) {
@@ -178,7 +178,7 @@
     }
 
     for (PsiElement element : elements) {
-      if (element instanceof PsiStatement && RefactoringUtil.isSuperOrThisCall((PsiStatement)element, true, true)) {
+      if (element instanceof PsiStatement && JavaHighlightUtil.isSuperOrThisCall((PsiStatement)element, true, true)) {
         if (showErrorMessages) {
           String message = RefactoringBundle
             .getCannotRefactorMessage(RefactoringBundle.message("selected.block.contains.invocation.of.another.class.constructor"));
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
index 14535e0..7279f90 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethod/ExtractMethodProcessor.java
@@ -18,6 +18,7 @@
 import com.intellij.codeInsight.ChangeContextUtil;
 import com.intellij.codeInsight.ExceptionUtil;
 import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.codeInsight.intention.impl.AddNullableAnnotationFix;
 import com.intellij.codeInsight.navigation.NavigationUtil;
@@ -66,10 +67,7 @@
 import com.intellij.refactoring.introduceVariable.IntroduceVariableBase;
 import com.intellij.refactoring.util.*;
 import com.intellij.refactoring.util.classMembers.ElementNeedsThis;
-import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
-import com.intellij.refactoring.util.duplicates.Match;
-import com.intellij.refactoring.util.duplicates.MatchProvider;
-import com.intellij.refactoring.util.duplicates.VariableReturnValue;
+import com.intellij.refactoring.util.duplicates.*;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.Processor;
@@ -104,7 +102,7 @@
   protected String myMethodName; // name for extracted method
   protected PsiType myReturnType; // return type for extracted method
   protected PsiTypeParameterList myTypeParameterList; //type parameter list of extracted method
-  private ParameterTablePanel.VariableData[] myVariableDatum; // parameter data for extracted method
+  private VariableData[] myVariableDatum; // parameter data for extracted method
   protected PsiClassType[] myThrownExceptions; // exception to declare as thrown by extracted method
   protected boolean myStatic; // whether to declare extracted method static
 
@@ -446,7 +444,7 @@
   private boolean shouldBeStatic() {
     for(PsiElement element: myElements) {
       final PsiExpressionStatement statement = PsiTreeUtil.getParentOfType(element, PsiExpressionStatement.class);
-      if (statement != null && RefactoringUtil.isSuperOrThisCall(statement, true, true)) {
+      if (statement != null && JavaHighlightUtil.isSuperOrThisCall(statement, true, true)) {
         return true;
       }
     }
@@ -546,7 +544,7 @@
   public void testPrepare() {
     myInputVariables.setFoldingAvailable(myInputVariables.isFoldingSelectedByDefault());
     myMethodName = myInitialMethodName;
-    myVariableDatum = new ParameterTablePanel.VariableData[myInputVariables.getInputVariables().size()];
+    myVariableDatum = new VariableData[myInputVariables.getInputVariables().size()];
     for (int i = 0; i < myInputVariables.getInputVariables().size(); i++) {
       myVariableDatum[i] = myInputVariables.getInputVariables().get(i);
     }
@@ -805,7 +803,7 @@
 
     adjustFinalParameters(newMethod);
     int i = 0;
-    for (ParameterTablePanel.VariableData data : myVariableDatum) {
+    for (VariableData data : myVariableDatum) {
       if (!data.passAsParameter) continue;
       final PsiVariable variable = data.variable;
       final PsiParameter psiParameter = newMethod.getParameterList().getParameters()[i++];
@@ -926,20 +924,20 @@
   }
 
   public PsiElement processMatch(Match match) throws IncorrectOperationException {
-    match.changeSignature(myExtractedMethod);
+    MatchUtil.changeSignature(match, myExtractedMethod);
     if (RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass())) {
       PsiUtil.setModifierProperty(myExtractedMethod, PsiModifier.STATIC, true);
     }
     final PsiMethodCallExpression methodCallExpression = generateMethodCall(match.getInstanceExpression(), false);
 
-    ArrayList<ParameterTablePanel.VariableData> datas = new ArrayList<ParameterTablePanel.VariableData>();
-    for (final ParameterTablePanel.VariableData variableData : myVariableDatum) {
+    ArrayList<VariableData> datas = new ArrayList<VariableData>();
+    for (final VariableData variableData : myVariableDatum) {
       if (variableData.passAsParameter) {
         datas.add(variableData);
       }
     }
     final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(myProject);
-    for (ParameterTablePanel.VariableData data : datas) {
+    for (VariableData data : datas) {
       final List<PsiElement> parameterValue = match.getParameterValues(data.variable);
       if (parameterValue != null) {
         for (PsiElement val : parameterValue) {
@@ -983,7 +981,7 @@
   }
 
   private void renameInputVariables() throws IncorrectOperationException {
-    for (ParameterTablePanel.VariableData data : myVariableDatum) {
+    for (VariableData data : myVariableDatum) {
       PsiVariable variable = data.variable;
       if (!data.name.equals(variable.getName())) {
         for (PsiElement element : myElements) {
@@ -1015,7 +1013,7 @@
 
     boolean isFinal = CodeStyleSettingsManager.getSettings(myProject).GENERATE_FINAL_PARAMETERS;
     PsiParameterList list = newMethod.getParameterList();
-    for (ParameterTablePanel.VariableData data : myVariableDatum) {
+    for (VariableData data : myVariableDatum) {
       if (data.passAsParameter) {
         PsiParameter parm = myElementFactory.createParameter(data.name, data.type);
         if (isFinal) {
@@ -1053,7 +1051,7 @@
         final PsiClass nullableAnnotationClass =
           JavaPsiFacade.getInstance(myProject).findClass(manager.getDefaultNullable(), GlobalSearchScope.allScope(myProject));
         if (nullableAnnotationClass != null) {
-          new AddNullableAnnotationFix(newMethod).invoke(myProject, myEditor, myTargetClass.getContainingFile());
+          new AddNullableAnnotationFix(newMethod).invoke(myProject, myTargetClass.getContainingFile(), newMethod, newMethod);
         }
       }
     }
@@ -1104,7 +1102,7 @@
     buffer.append("(");
     if (generateArgs) {
       int count = 0;
-      for (ParameterTablePanel.VariableData data : myVariableDatum) {
+      for (VariableData data : myVariableDatum) {
         if (data.passAsParameter) {
           if (count > 0) {
             buffer.append(",");
@@ -1252,7 +1250,7 @@
   }
 
   private String getNewVariableName(PsiVariable variable) {
-    for (ParameterTablePanel.VariableData data : myVariableDatum) {
+    for (VariableData data : myVariableDatum) {
       if (data.variable.equals(variable)) {
         return data.name;
       }
@@ -1373,7 +1371,8 @@
   @Nullable
   public String getConfirmDuplicatePrompt(Match match) {
     final boolean needToBeStatic = RefactoringUtil.isInStaticContext(match.getMatchStart(), myExtractedMethod.getContainingClass());
-    final String changedSignature = match.getChangedSignature(myExtractedMethod, needToBeStatic, VisibilityUtil.getVisibilityStringToDisplay(myExtractedMethod));
+    final String changedSignature = MatchUtil
+      .getChangedSignature(match, myExtractedMethod, needToBeStatic, VisibilityUtil.getVisibilityStringToDisplay(myExtractedMethod));
     if (changedSignature != null) {
       return RefactoringBundle.message("replace.this.code.fragment.and.change.signature", changedSignature);
     }
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
index b5a9099..2a41db9 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractMethodObject/ExtractMethodObjectDialog.java
@@ -27,6 +27,7 @@
 import com.intellij.refactoring.extractMethod.InputVariables;
 import com.intellij.refactoring.ui.ConflictsDialog;
 import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.ui.EditorTextField;
 import com.intellij.util.Function;
 import com.intellij.util.VisibilityUtil;
@@ -78,7 +79,7 @@
   private JPanel myAnonymousClassPanel;
   private JCheckBox myFoldCb;
   private ButtonGroup myVisibilityGroup;
-  private ParameterTablePanel.VariableData[] myInputVariables;
+  private VariableData[] myInputVariables;
 
 
   public ExtractMethodObjectDialog(Project project, PsiClass targetClass, final InputVariables inputVariables, PsiType returnType,
@@ -96,7 +97,7 @@
     myMultipleExitPoints = multipleExitPoints;
 
     boolean canBeVarargs = false;
-    for (ParameterTablePanel.VariableData data : inputVariables.getInputVariables()) {
+    for (VariableData data : inputVariables.getInputVariables()) {
       canBeVarargs |= data.type instanceof PsiArrayType;
     }
     canBeVarargs |= inputVariables.isFoldable()  && inputVariables.isFoldingSelectedByDefault();
@@ -136,7 +137,7 @@
     return myCreateInnerClassRb.isSelected() ? myInnerClassName.getText() : myMethodName.getText();
   }
 
-  public ParameterTablePanel.VariableData[] getChosenParameters() {
+  public VariableData[] getChosenParameters() {
     return myInputVariables;
   }
 
@@ -167,7 +168,7 @@
 
     final JCheckBox makeVarargsCb = myCreateInnerClassRb.isSelected() ? myCbMakeVarargs : myCbMakeVarargsAnonymous;
     if (makeVarargsCb != null && makeVarargsCb.isSelected()) {
-      final ParameterTablePanel.VariableData data = myInputVariables[myInputVariables.length - 1];
+      final VariableData data = myInputVariables[myInputVariables.length - 1];
       if (data.type instanceof PsiArrayType) {
         data.type = new PsiEllipsisType(((PsiArrayType)data.type).getComponentType());
       }
@@ -212,7 +213,7 @@
   protected JComponent createCenterPanel() {
     mySignatureArea.setEditable(false);
     myCreateInnerClassRb.setSelected(true);
-   
+
     final ActionListener enableDisableListener = new ActionListener() {
       public void actionPerformed(final ActionEvent e) {
         enable(myCreateInnerClassRb.isSelected());
@@ -225,11 +226,11 @@
     myFoldCb.setSelected(myVariableData.isFoldingSelectedByDefault());
     myFoldCb.setVisible(myVariableData.isFoldable());
     myVariableData.setFoldingAvailable(myFoldCb.isSelected());
-    myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+    myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
     myFoldCb.addActionListener(new ActionListener() {
       public void actionPerformed(ActionEvent e) {
         myVariableData.setFoldingAvailable(myFoldCb.isSelected());
-        myInputVariables = myVariableData.getInputVariables().toArray(new ParameterTablePanel.VariableData[myVariableData.getInputVariables().size()]);
+        myInputVariables = myVariableData.getInputVariables().toArray(new VariableData[myVariableData.getInputVariables().size()]);
         myParametersTableContainer.removeAll();
         myParametersTableContainer.add(createParametersPanel(), BorderLayout.CENTER);
         updateSignature();
@@ -359,8 +360,8 @@
       buffer.append("\n}.");
       buffer.append(myMethodName.getText());
       buffer.append("(");
-      buffer.append(StringUtil.join(myInputVariables, new Function<ParameterTablePanel.VariableData, String>() {
-        public String fun(final ParameterTablePanel.VariableData variableData) {
+      buffer.append(StringUtil.join(myInputVariables, new Function<VariableData, String>() {
+        public String fun(final VariableData variableData) {
           return variableData.name;
         }
       }, ", "));
@@ -375,7 +376,7 @@
     int count = 0;
     final String indent = "    ";
     for (int i = 0; i < myInputVariables.length; i++) {
-      ParameterTablePanel.VariableData data = myInputVariables[i];
+      VariableData data = myInputVariables[i];
       if (data.passAsParameter) {
         //String typeAndModifiers = PsiFormatUtil.formatVariable(data.variable,
         //  PsiFormatUtil.SHOW_MODIFIERS | PsiFormatUtil.SHOW_TYPE);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
index b2509d9..96019d4 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperClassUtil.java
@@ -27,10 +27,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.search.GlobalSearchScope;
-import com.intellij.psi.util.MethodSignature;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
-import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.psi.util.*;
 import com.intellij.refactoring.memberPullUp.PullUpHelper;
 import com.intellij.refactoring.ui.ConflictsDialog;
 import com.intellij.refactoring.util.DocCommentPolicy;
@@ -76,7 +73,7 @@
     clearPsiReferenceList(subclass.getExtendsList());
 
     // make original class extend extracted superclass
-    PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos); 
+    PsiJavaCodeReferenceElement ref = createExtendingReference(superclass, subclass, selectedMemberInfos);
     subclass.getExtendsList().add(ref);
 
     PullUpHelper pullUpHelper = new PullUpHelper(subclass, superclass, selectedMemberInfos,
@@ -185,7 +182,7 @@
                                                                                                                            .getName()) !=
                                                                                                                        null;
                                                                                                                    }
-                                                                                                                 }, PsiUtilBase
+                                                                                                                 }, PsiUtilCore
       .toPsiElementArray(movedElements));
     final PsiTypeParameterList originalTypeParameterList = superClass.getTypeParameterList();
     assert originalTypeParameterList != null;
diff --git a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
index 4352e96..4a4e8d8 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractSuperclass/ExtractSuperclassHandler.java
@@ -22,6 +22,7 @@
 
 import com.intellij.history.LocalHistory;
 import com.intellij.history.LocalHistoryAction;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.actionSystem.DataContext;
 import com.intellij.openapi.actionSystem.PlatformDataKeys;
 import com.intellij.openapi.application.ApplicationManager;
@@ -41,7 +42,6 @@
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.refactoring.util.DocCommentPolicy;
 import com.intellij.refactoring.util.classMembers.MemberInfo;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.MultiMap;
@@ -182,7 +182,7 @@
   }
 
   private String getCommandName(final PsiClass subclass, String newName) {
-    return RefactoringBundle.message("extract.superclass.command.name", newName, UsageViewUtil.getDescriptiveName(subclass));
+    return RefactoringBundle.message("extract.superclass.command.name", newName, DescriptiveNameUtil.getDescriptiveName(subclass));
   }
 
   public boolean isEnabledOnElements(PsiElement[] elements) {
diff --git a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
index 8aaf941..d096db5 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/extractclass/ExtractClassProcessor.java
@@ -53,6 +53,7 @@
 import com.intellij.refactoring.util.classMembers.MemberInfo;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.ContainerUtil;
@@ -320,7 +321,7 @@
     super.performRefactoring(usageInfos);
     if (myNewVisibility == null) return;
     for (PsiMember member : members) {
-      VisibilityUtil.fixVisibility(usageInfos, member, myNewVisibility);
+      VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usageInfos), member, myNewVisibility);
     }
   }
 
diff --git a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
index 6d9cc0a..28650c7 100644
--- a/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inheritanceToDelegation/InheritanceToDelegationProcessor.java
@@ -16,9 +16,11 @@
 package com.intellij.refactoring.inheritanceToDelegation;
 
 import com.intellij.codeInsight.NullableNotNullManager;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.generation.GenerateMembersUtil;
 import com.intellij.codeInsight.generation.OverrideImplementUtil;
 import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
@@ -37,14 +39,12 @@
 import com.intellij.refactoring.util.CommonRefactoringUtil;
 import com.intellij.refactoring.util.ConflictsUtil;
 import com.intellij.refactoring.util.RefactoringUIUtil;
-import com.intellij.refactoring.util.RefactoringUtil;
 import com.intellij.refactoring.util.classMembers.ClassMemberReferencesVisitor;
 import com.intellij.refactoring.util.classRefs.ClassInstanceScanner;
 import com.intellij.refactoring.util.classRefs.ClassReferenceScanner;
 import com.intellij.refactoring.util.classRefs.ClassReferenceSearchingScanner;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.usages.UsageInfoToUsageConverter;
 import com.intellij.usages.UsageTarget;
 import com.intellij.usages.UsageViewManager;
@@ -682,7 +682,7 @@
         }
       }
       final @NonNls String assignmentText = fieldQualifier + myFieldName + "= new " + defaultClassFieldType() + "()";
-      if (statements.length < 1 || !RefactoringUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) {
+      if (statements.length < 1 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true) || myBaseClass.isInterface()) {
         PsiExpressionStatement assignmentStatement =
           (PsiExpressionStatement)myFactory.createStatementFromText(
             assignmentText, body
@@ -698,7 +698,7 @@
 
         assignmentStatement = (PsiExpressionStatement)CodeStyleManager.getInstance(myProject).reformat(assignmentStatement);
         if (statements.length > 0) {
-          if (!RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) {
+          if (!JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) {
             body.addBefore(assignmentStatement, statements[0]);
           }
           else {
@@ -711,7 +711,7 @@
       }
       else {
         final PsiExpressionStatement callStatement = ((PsiExpressionStatement)statements[0]);
-        if (!RefactoringUtil.isSuperOrThisCall(callStatement, false, true)) {
+        if (!JavaHighlightUtil.isSuperOrThisCall(callStatement, false, true)) {
           final PsiMethodCallExpression superConstructorCall =
             (PsiMethodCallExpression)callStatement.getExpression();
           PsiAssignmentExpression assignmentExpression =
@@ -736,7 +736,7 @@
     PsiMethod[] constructors = myClass.getConstructors();
     for (PsiMethod constructor : constructors) {
       final PsiStatement[] statements = constructor.getBody().getStatements();
-      if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) return false;
+      if (statements.length > 0 && JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) return false;
     }
     return true;
   }
@@ -749,7 +749,7 @@
       PsiMethod[] constructors = myClass.getConstructors();
       for (PsiMethod constructor : constructors) {
         final PsiStatement[] statements = constructor.getBody().getStatements();
-        if (statements.length > 0 && RefactoringUtil.isSuperOrThisCall(statements[0], true, false)) {
+        if (statements.length > 0 && JavaHighlightUtil.isSuperOrThisCall(statements[0], true, false)) {
           final PsiMethodCallExpression superConstructorCall =
             (PsiMethodCallExpression)((PsiExpressionStatement)statements[0]).getExpression();
           PsiElement superConstructor = superConstructorCall.getMethodExpression().resolve();
@@ -906,7 +906,7 @@
 
 
   protected String getCommandName() {
-    return RefactoringBundle.message("replace.inheritance.with.delegation.command", UsageViewUtil.getDescriptiveName(myClass));
+    return RefactoringBundle.message("replace.inheritance.with.delegation.command", DescriptiveNameUtil.getDescriptiveName(myClass));
   }
 
   private Set<PsiMember> getAllBaseClassMembers() {
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
index bcf0b35..edb86b4 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineConstantFieldProcessor.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.inline;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
@@ -30,7 +31,6 @@
 import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
@@ -179,8 +179,8 @@
         } else if (initializer1 instanceof PsiMethodCallExpression) {
           referenceExpression = ((PsiMethodCallExpression)initializer1).getMethodExpression();
         }
-        if (referenceExpression != null && 
-            referenceExpression.getQualifierExpression() == null && 
+        if (referenceExpression != null &&
+            referenceExpression.getQualifierExpression() == null &&
             !(referenceExpression.advancedResolve(false).getCurrentFileResolveScope() instanceof PsiImportStaticStatement)) {
           referenceExpression.setQualifierExpression(qExpression);
         }
@@ -212,7 +212,7 @@
   }
 
   protected String getCommandName() {
-    return RefactoringBundle.message("inline.field.command", UsageViewUtil.getDescriptiveName(myField));
+    return RefactoringBundle.message("inline.field.command", DescriptiveNameUtil.getDescriptiveName(myField));
   }
 
   protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
index 344a5f0..3171175 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineLocalHandler.java
@@ -36,7 +36,7 @@
 import com.intellij.psi.tree.IElementType;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.util.CommonRefactoringUtil;
@@ -104,7 +104,7 @@
               }
               innerClass = parentPsiClass;
               continue;
-            } 
+            }
             innerClassesWithUsages.add(innerClass);
             innerClassUsages.add(element);
           }
@@ -143,7 +143,7 @@
       CommonRefactoringUtil.showErrorHint(project, editor, message, REFACTORING_NAME, HelpID.INLINE_VARIABLE);
       return;
     }
-    final PsiElement[] refsToInline = PsiUtilBase.toPsiElementArray(refsToInlineList);
+    final PsiElement[] refsToInline = PsiUtilCore.toPsiElementArray(refsToInlineList);
 
     EditorColorsManager manager = EditorColorsManager.getInstance();
     final TextAttributes attributes = manager.getGlobalScheme().getAttributes(EditorColors.SEARCH_RESULT_ATTRIBUTES);
diff --git a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
index 7c55aae..1659cac 100644
--- a/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/inline/InlineMethodProcessor.java
@@ -19,6 +19,7 @@
 import com.intellij.history.LocalHistory;
 import com.intellij.history.LocalHistoryAction;
 import com.intellij.lang.Language;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.lang.java.JavaLanguage;
 import com.intellij.lang.refactoring.InlineHandler;
 import com.intellij.openapi.diagnostic.Logger;
@@ -51,7 +52,6 @@
 import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.HashMap;
@@ -110,7 +110,7 @@
     myFactory = JavaPsiFacade.getInstance(myManager.getProject()).getElementFactory();
     myCodeStyleManager = CodeStyleManager.getInstance(myProject);
     myJavaCodeStyle = JavaCodeStyleManager.getInstance(myProject);
-    myDescriptiveName = UsageViewUtil.getDescriptiveName(myMethod);
+    myDescriptiveName = DescriptiveNameUtil.getDescriptiveName(myMethod);
   }
 
   protected String getCommandName() {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
index 0d1aacf..d186ef9 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/BaseExpressionToFieldHandler.java
@@ -54,7 +54,7 @@
 import com.intellij.psi.search.PsiElementProcessor;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.IntroduceHandlerBase;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.introduce.inplace.AbstractInplaceIntroducer;
@@ -819,7 +819,7 @@
 
           if (myEditor != null) {
             if (!ApplicationManager.getApplication().isUnitTestMode()) {
-              PsiElement[] exprsToHighlight = PsiUtilBase.toPsiElementArray(array);
+              PsiElement[] exprsToHighlight = PsiUtilCore.toPsiElementArray(array);
               HighlightManager highlightManager = HighlightManager.getInstance(myProject);
               highlightManager.addOccurrenceHighlights(myEditor, exprsToHighlight, highlightAttributes(), true, null);
               WindowManager
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
index 93e19e3..9e4f79c 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceField/ElementToWorkOn.java
@@ -99,7 +99,7 @@
         }
 
         if (!editor.getSelectionModel().hasSelection()){
-          final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset, statementsInRange);
+          final List<PsiExpression> expressions = IntroduceVariableBase.collectExpressions(file, editor, offset);
           for (Iterator<PsiExpression> iterator = expressions.iterator(); iterator.hasNext(); ) {
             PsiExpression expression = iterator.next();
             if (!processor.accept(new ElementToWorkOn(null, expression))) {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
index 189fe82..8f0f5fb 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceParameter/IntroduceParameterProcessor.java
@@ -25,6 +25,7 @@
 package com.intellij.refactoring.introduceParameter;
 
 import com.intellij.codeInsight.ChangeContextUtil;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Pair;
@@ -535,7 +536,7 @@
   }
 
   protected String getCommandName() {
-    return RefactoringBundle.message("introduce.parameter.command", UsageViewUtil.getDescriptiveName(myMethodToReplaceIn));
+    return RefactoringBundle.message("introduce.parameter.command", DescriptiveNameUtil.getDescriptiveName(myMethodToReplaceIn));
   }
 
   @Nullable
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
index 3e18ae1..740c2cc 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceVariable/IntroduceVariableBase.java
@@ -125,7 +125,7 @@
       }
 
       if (!selectionModel.hasSelection()) {
-        final List<PsiExpression> expressions = collectExpressions(file, editor, offset, statementsInRange);
+        final List<PsiExpression> expressions = collectExpressions(file, editor, offset);
         if (expressions.isEmpty()) {
           selectionModel.selectLineAtCaret();
         } else if (expressions.size() == 1) {
@@ -162,7 +162,16 @@
     return Boolean.valueOf(PropertiesComponent.getInstance().getOrInit(PREFER_STATEMENTS_OPTION, "false")).booleanValue() || Registry.is(PREFER_STATEMENTS_OPTION, false);
   }
 
-  public static List<PsiExpression> collectExpressions(final PsiFile file, final Editor editor, final int offset, final PsiElement... statementsInRange) {
+  public static List<PsiExpression> collectExpressions(final PsiFile file,
+                                                       final Editor editor,
+                                                       final int offset) {
+    return collectExpressions(file, editor, offset, false);
+  }
+
+  public static List<PsiExpression> collectExpressions(final PsiFile file,
+                                                       final Editor editor,
+                                                       final int offset,
+                                                       boolean acceptVoid) {
     Document document = editor.getDocument();
     CharSequence text = document.getCharsSequence();
     int correctedOffset = offset;
@@ -196,7 +205,8 @@
     }*/
     PsiExpression expression = PsiTreeUtil.getParentOfType(elementAtCaret, PsiExpression.class);
     while (expression != null) {
-      if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && expression.getType() != PsiType.VOID) {
+      if (!expressions.contains(expression) && !(expression instanceof PsiParenthesizedExpression) && !(expression instanceof PsiSuperExpression) && 
+          (acceptVoid || expression.getType() != PsiType.VOID)) {
         if (expression instanceof PsiMethodReferenceExpression) {
           expressions.add(expression);
         }
@@ -592,14 +602,14 @@
         final boolean allOccurences = choice != OccurrencesChooser.ReplaceChoice.NO;
         final PsiElement chosenAnchor = allOccurences ? anchorStatementIfAll : anchorStatement;
         final Ref<SmartPsiElementPointer<PsiVariable>> variable = new Ref<SmartPsiElementPointer<PsiVariable>>();
-        
+
         final Editor topLevelEditor;
         if (!InjectedLanguageManager.getInstance(project).isInjectedFragment(anchorStatement.getContainingFile())) {
           topLevelEditor = InjectedLanguageUtil.getTopLevelEditor(editor);
         } else {
           topLevelEditor = editor;
         }
-        
+
         final IntroduceVariableSettings settings =
           getSettings(project, topLevelEditor, expr, occurrences, typeSelectorManager, inFinalContext, hasWriteAccess, validator, chosenAnchor, choice);
         if (!settings.isOK()) {
@@ -840,9 +850,9 @@
             if (!deleteSelf && replaceSelf && expr1 instanceof PsiPolyadicExpression && expr1.isValid() && !expr1.isPhysical() ) {
               array.add(replace(expr1, ref, project));
             }
-            
+
             if (editor != null) {
-              final PsiElement[] replacedOccurences = PsiUtilBase.toPsiElementArray(array);
+              final PsiElement[] replacedOccurences = PsiUtilCore.toPsiElementArray(array);
               highlightReplacedOccurences(project, editor, replacedOccurences);
             }
           } else {
@@ -900,7 +910,7 @@
     }
     return false;
   }
-  
+
   public static PsiExpression replaceExplicitWithDiamondWhenApplicable(final PsiExpression initializer,
                                                                        final PsiType expectedType) {
     if (initializer instanceof PsiNewExpression) {
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
index 4260c05..7ca675c 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectDialog.java
@@ -32,6 +32,7 @@
 import com.intellij.refactoring.ui.PackageNameReferenceEditorCombo;
 import com.intellij.refactoring.ui.RefactoringDialog;
 import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.ui.ComboboxWithBrowseButton;
 import com.intellij.ui.DocumentAdapter;
 import com.intellij.ui.RecentsManager;
@@ -53,7 +54,7 @@
 public class IntroduceParameterObjectDialog extends RefactoringDialog {
 
   private final PsiMethod sourceMethod;
-  private final ParameterTablePanel.VariableData[] parameterInfo;
+  private final VariableData[] parameterInfo;
   private JTextField sourceMethodTextField;
 
   private JRadioButton useExistingClassButton;
@@ -94,9 +95,9 @@
     myInnerClassNameTextField.getDocument().addDocumentListener(docListener);
     final PsiParameterList parameterList = sourceMethod.getParameterList();
     final PsiParameter[] parameters = parameterList.getParameters();
-    parameterInfo = new ParameterTablePanel.VariableData[parameters.length];
+    parameterInfo = new VariableData[parameters.length];
     for (int i = 0; i < parameterInfo.length; i++) {
-      parameterInfo[i] = new ParameterTablePanel.VariableData(parameters[i]);
+      parameterInfo[i] = new VariableData(parameters[i]);
       parameterInfo[i].name = parameters[i].getName();
       parameterInfo[i].passAsParameter = true;
     }
@@ -164,8 +165,8 @@
       packageName = getPackageName();
       className = getClassName();
     }
-    List<ParameterTablePanel.VariableData> parameters = new ArrayList<ParameterTablePanel.VariableData>();
-    for (ParameterTablePanel.VariableData data : parameterInfo) {
+    List<VariableData> parameters = new ArrayList<VariableData>();
+    for (VariableData data : parameterInfo) {
       if (data.passAsParameter) {
         parameters.add(data);
       }
@@ -175,7 +176,7 @@
     final MoveDestination moveDestination = ((DestinationFolderComboBox)myDestinationCb)
       .selectDirectory(new PackageWrapper(PsiManager.getInstance(myProject), packageName), false);
     invokeRefactoring(new IntroduceParameterObjectProcessor(className, packageName, moveDestination, sourceMethod,
-                                                            parameters.toArray(new ParameterTablePanel.VariableData[parameters.size()]),
+                                                            parameters.toArray(new VariableData[parameters.size()]),
                                                             keepMethod, useExistingClass,
                                                             createInnerClass, newVisibility, myGenerateAccessorsCheckBox.isSelected()));
   }
@@ -238,7 +239,7 @@
   @NotNull
   public List<PsiParameter> getParametersToExtract() {
     final List<PsiParameter> out = new ArrayList<PsiParameter>();
-    for (ParameterTablePanel.VariableData info : parameterInfo) {
+    for (VariableData info : parameterInfo) {
       if (info.passAsParameter) {
         out.add((PsiParameter)info.variable);
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
index bcd84bd..5fdf3f7 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/IntroduceParameterObjectProcessor.java
@@ -26,6 +26,7 @@
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.impl.source.javadoc.PsiDocParamRef;
 import com.intellij.psi.javadoc.PsiDocComment;
 import com.intellij.psi.javadoc.PsiDocTag;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -37,13 +38,10 @@
 import com.intellij.refactoring.MoveDestination;
 import com.intellij.refactoring.RefactorJBundle;
 import com.intellij.refactoring.introduceparameterobject.usageInfo.*;
-import com.intellij.refactoring.psi.PropertyUtils;
-import com.intellij.refactoring.util.FixableUsageInfo;
-import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
-import com.intellij.refactoring.util.ParameterTablePanel;
-import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.MultiMap;
@@ -77,7 +75,7 @@
                                            String packageName,
                                            MoveDestination moveDestination,
                                            PsiMethod method,
-                                           ParameterTablePanel.VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass,
+                                           VariableData[] parameters, boolean keepMethodAsDelegate, final boolean useExistingClass,
                                            final boolean createInnerClass,
                                            String newVisibility,
                                            boolean generateAccessors) {
@@ -92,14 +90,14 @@
     myNewVisibility = newVisibility;
     myGenerateAccessors = generateAccessors;
     this.parameters = new ArrayList<ParameterChunk>();
-    for (ParameterTablePanel.VariableData parameter : parameters) {
+    for (VariableData parameter : parameters) {
       this.parameters.add(new ParameterChunk(parameter));
     }
     final PsiParameterList parameterList = method.getParameterList();
     final PsiParameter[] methodParams = parameterList.getParameters();
     paramsToMerge = new int[parameters.length];
     for (int p = 0; p < parameters.length; p++) {
-      ParameterTablePanel.VariableData parameter = parameters[p];
+      VariableData parameter = parameters[p];
       for (int i = 0; i < methodParams.length; i++) {
         final PsiParameter methodParam = methodParams[i];
         if (parameter.variable.equals(methodParam)) {
@@ -119,7 +117,7 @@
         return super.visitClassType(classType);
       }
     };
-    for (ParameterTablePanel.VariableData parameter : parameters) {
+    for (VariableData parameter : parameters) {
       parameter.type.accept(typeParametersVisitor);
     }
     typeParams = new ArrayList<PsiTypeParameter>(typeParamSet);
@@ -266,7 +264,7 @@
     beanClassBuilder.setClassName(className);
     beanClassBuilder.setPackageName(packageName);
     for (ParameterChunk parameterChunk : parameters) {
-      final ParameterTablePanel.VariableData parameter = parameterChunk.parameter;
+      final VariableData parameter = parameterChunk.parameter;
       final boolean setterRequired = paramsNeedingSetters.contains(parameter.variable);
       beanClassBuilder.addField((PsiParameter)parameter.variable,  parameter.name, parameter.type, setterRequired);
     }
@@ -316,6 +314,16 @@
       for (PsiDocTag paramTag : paramTags) {
         final PsiElement[] dataElements = paramTag.getDataElements();
         if (dataElements.length > 0) {
+          if (dataElements[0] instanceof PsiDocParamRef) {
+            final PsiReference reference = dataElements[0].getReference();
+            if (reference != null) {
+              final PsiElement resolve = reference.resolve();
+              if (resolve instanceof PsiParameter) {
+                final int parameterIndex = method.getParameterList().getParameterIndex((PsiParameter)resolve);
+                if (ArrayUtil.find(paramsToMerge, parameterIndex) < 0) continue;
+              }
+            }
+          }
           mergedTags.add((PsiDocTag)paramTag.copy());
         }
       }
@@ -411,12 +419,12 @@
 
       parameterChunk.setField(field);
 
-      final PsiMethod getterForField = PropertyUtils.findGetterForField(field);
+      final PsiMethod getterForField = PropertyUtil.findGetterForField(field);
       if (getterForField != null) {
         parameterChunk.setGetter(getterForField.getName());
       }
 
-      final PsiMethod setterForField = PropertyUtils.findSetterForField(field);
+      final PsiMethod setterForField = PropertyUtil.findSetterForField(field);
       if (setterForField != null) {
         parameterChunk.setSetter(setterForField.getName());
       }
@@ -439,12 +447,12 @@
   }
 
   public static class ParameterChunk {
-    private final ParameterTablePanel.VariableData parameter;
+    private final VariableData parameter;
     private PsiField field;
     private String getter;
     private String setter;
 
-    public ParameterChunk(ParameterTablePanel.VariableData parameter) {
+    public ParameterChunk(VariableData parameter) {
       this.parameter = parameter;
     }
 
diff --git a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
index 3161380..fab0644 100644
--- a/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/introduceparameterobject/usageInfo/BeanClassVisibilityUsageInfo.java
@@ -24,6 +24,7 @@
 import com.intellij.psi.PsiMethod;
 import com.intellij.refactoring.util.FixableUsageInfo;
 import com.intellij.usageView.UsageInfo;
+import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 
@@ -46,9 +47,9 @@
 
   @Override
   public void fixUsage() throws IncorrectOperationException {
-    VisibilityUtil.fixVisibility(usages, existingClass, myNewVisibility);
+    VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), existingClass, myNewVisibility);
     if (myExistingClassCompatibleConstructor != null) {
-      VisibilityUtil.fixVisibility(usages, myExistingClassCompatibleConstructor, myNewVisibility);
+      VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), myExistingClassCompatibleConstructor, myNewVisibility);
     }
   }
 }
diff --git a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
index c230a87..4870241 100644
--- a/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/invertBoolean/InvertBooleanDialog.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.invertBoolean;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.psi.PsiNamedElement;
@@ -47,7 +48,7 @@
     myLabel.setText(RefactoringBundle.message("invert.boolean.name.of.inverted.element", typeString));
     myCaptionLabel.setText(RefactoringBundle.message("invert.0.1",
                                                      typeString,
-                                                     UsageViewUtil.getDescriptiveName(myElement)));
+                                                     DescriptiveNameUtil.getDescriptiveName(myElement)));
 
     setTitle(InvertBooleanHandler.REFACTORING_NAME);
     init();
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
index e76ad57..a990681 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/AbstractMakeStaticDialog.java
@@ -19,7 +19,7 @@
  * User: dsl
  * Date: 04.07.2002
  * Time: 13:14:49
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.refactoring.makeStatic;
@@ -30,7 +30,7 @@
 import com.intellij.psi.PsiTypeParameterListOwner;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.ui.RefactoringDialog;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.usageView.UsageViewUtil;
 
 import javax.swing.*;
@@ -68,7 +68,7 @@
 
   public abstract String getClassParameterName();
 
-  public abstract ParameterTablePanel.VariableData[] getVariableData();
+  public abstract VariableData[] getVariableData();
 
   public abstract boolean isReplaceUsages();
 
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
index ac618d8..2e6467b 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeMethodOrClassStaticProcessor.java
@@ -24,6 +24,7 @@
  */
 package com.intellij.refactoring.makeStatic;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
@@ -274,7 +275,7 @@
   }
 
   protected String getCommandName() {
-    return RefactoringBundle.message("make.static.command", UsageViewUtil.getDescriptiveName(myMember));
+    return RefactoringBundle.message("make.static.command", DescriptiveNameUtil.getDescriptiveName(myMember));
   }
 
   public T getMember() {
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
index c737e10..40e1d5e 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeParameterizedStaticDialog.java
@@ -24,6 +24,7 @@
  */
 package com.intellij.refactoring.makeStatic;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.ComboBox;
@@ -33,8 +34,8 @@
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.RefactoringBundle;
 import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.ui.DocumentAdapter;
-import com.intellij.ui.IdeBorderFactory;
 import com.intellij.usageView.UsageViewUtil;
 
 import javax.swing.*;
@@ -52,7 +53,7 @@
   private final JCheckBox myMakeFieldParameters = new JCheckBox();
 
   private ParameterTablePanel myParameterPanel;
-  private ParameterTablePanel.VariableData[] myVariableData;
+  private VariableData[] myVariableData;
   private final boolean myAnyNonFieldMembersUsed;
 
 
@@ -71,10 +72,10 @@
   }
 
   private boolean buildVariableData(InternalUsageInfo[] internalUsages) {
-    ArrayList<ParameterTablePanel.VariableData> variableDatum = new ArrayList<ParameterTablePanel.VariableData>();
+    ArrayList<VariableData> variableDatum = new ArrayList<VariableData>();
     boolean nonFieldUsages = MakeStaticUtil.collectVariableData(myMember, internalUsages, variableDatum);
 
-    myVariableData = variableDatum.toArray(new ParameterTablePanel.VariableData[0]);
+    myVariableData = variableDatum.toArray(new VariableData[0]);
     return nonFieldUsages;
   }
 
@@ -109,7 +110,7 @@
    *
    * @return null if field parameters are not selected
    */
-  public ParameterTablePanel.VariableData[] getVariableData() {
+  public VariableData[] getVariableData() {
     if(myMakeFieldParameters != null && myMakeFieldParameters.isSelected()) {
       return myVariableData;
     }
@@ -222,7 +223,8 @@
     if (isMakeClassParameter()) {
       final PsiMethod methodWithParameter = checkParameterDoesNotExist();
       if (methodWithParameter != null) {
-        String who = methodWithParameter == myMember ? RefactoringBundle.message("this.method") : UsageViewUtil.getDescriptiveName(methodWithParameter);
+        String who = methodWithParameter == myMember ? RefactoringBundle.message("this.method") : DescriptiveNameUtil
+          .getDescriptiveName(methodWithParameter);
         String message = RefactoringBundle.message("0.already.has.parameter.named.1.use.this.name.anyway", who, getClassParameterName());
         ret = Messages.showYesNoDialog(myProject, message, RefactoringBundle.message("warning.title"), Messages.getWarningIcon());
         myClassParameterNameInputField.requestFocusInWindow();
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
index c1e2269..e5c966f 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/MakeStaticUtil.java
@@ -29,8 +29,8 @@
 import com.intellij.psi.codeStyle.VariableKind;
 import com.intellij.psi.util.InheritanceUtil;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
 import com.intellij.refactoring.util.RefactoringUtil;
+import com.intellij.refactoring.util.VariableData;
 
 import java.util.ArrayList;
 import java.util.Collections;
@@ -132,13 +132,13 @@
     return false;
   }
 
-  public static boolean buildVariableData(PsiTypeParameterListOwner member, ArrayList<ParameterTablePanel.VariableData> result) {
+  public static boolean buildVariableData(PsiTypeParameterListOwner member, ArrayList<VariableData> result) {
     final InternalUsageInfo[] classRefsInMethod = findClassRefsInMember(member, false);
     return collectVariableData(member, classRefsInMethod, result);
   }
 
   public static boolean collectVariableData(PsiMember member, InternalUsageInfo[] internalUsages,
-                                             ArrayList<ParameterTablePanel.VariableData> variableDatum) {
+                                             ArrayList<VariableData> variableDatum) {
     HashSet<PsiField> reported = new HashSet<PsiField>();
     HashSet<PsiField> accessedForWriting = new HashSet<PsiField>();
     boolean needClassParameter = false;
@@ -165,7 +165,7 @@
     });
     for (final PsiField field : psiFields) {
       if (accessedForWriting.contains(field)) continue;
-      ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(field);
+      VariableData data = new VariableData(field);
       JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(member.getProject());
       String name = field.getName();
       name = codeStyleManager.variableNameToPropertyName(name, VariableKind.FIELD);
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
index e3bdccf..cd76eb9 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/Settings.java
@@ -19,14 +19,14 @@
  * User: dsl
  * Date: 01.07.2002
  * Time: 15:48:33
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.refactoring.makeStatic;
 
 import com.intellij.psi.PsiField;
 import com.intellij.psi.PsiType;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.util.containers.HashMap;
 import org.jetbrains.annotations.Nullable;
 
@@ -56,7 +56,7 @@
 
 
   public Settings(boolean replaceUsages, String classParameterName,
-                  ParameterTablePanel.VariableData[] variableDatum) {
+                  VariableData[] variableDatum) {
     myReplaceUsages = replaceUsages;
     myMakeClassParameter = classParameterName != null;
     myClassParameterName = classParameterName;
@@ -64,7 +64,7 @@
     myFieldToNameList = new ArrayList<FieldParameter>();
     if(myMakeFieldParameters) {
       myFieldToNameMapping = new com.intellij.util.containers.HashMap<PsiField, String>();
-      for (ParameterTablePanel.VariableData data : variableDatum) {
+      for (VariableData data : variableDatum) {
         if (data.passAsParameter) {
           myFieldToNameMapping.put((PsiField)data.variable, data.name);
           myFieldToNameList.add(new FieldParameter((PsiField)data.variable, data.name, data.type));
@@ -76,7 +76,7 @@
     }
   }
 
-  public Settings(boolean replaceUsages, String classParameterName, 
+  public Settings(boolean replaceUsages, String classParameterName,
                   PsiField[] fields, String[] names) {
     myReplaceUsages = replaceUsages;
     myMakeClassParameter = classParameterName != null;
@@ -96,7 +96,7 @@
       myFieldToNameMapping = null;
     }
   }
-  
+
   public boolean isReplaceUsages() {
     return myReplaceUsages;
   }
diff --git a/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java b/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
index 995255a..3bbc129 100644
--- a/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/makeStatic/SimpleMakeStaticDialog.java
@@ -19,7 +19,7 @@
  * User: dsl
  * Date: 04.07.2002
  * Time: 13:54:39
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.refactoring.makeStatic;
@@ -30,8 +30,7 @@
 import com.intellij.psi.PsiTypeParameterListOwner;
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.refactoring.util.ParameterTablePanel;
-import com.intellij.ui.IdeBorderFactory;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.usageView.UsageViewUtil;
 
 import javax.swing.*;
@@ -59,7 +58,7 @@
     return null;
   }
 
-  public ParameterTablePanel.VariableData[] getVariableData() {
+  public VariableData[] getVariableData() {
     return null;
   }
 
diff --git a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
index 0f7b115..95c826f 100644
--- a/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
+++ b/java/java-impl/src/com/intellij/refactoring/memberPullUp/PullUpHelper.java
@@ -29,6 +29,7 @@
 import com.intellij.codeInsight.ChangeContextUtil;
 import com.intellij.codeInsight.PsiEquivalenceUtil;
 import com.intellij.codeInsight.intention.AddAnnotationFix;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.ModalityState;
 import com.intellij.openapi.diagnostic.Logger;
@@ -54,7 +55,6 @@
 import com.intellij.refactoring.util.duplicates.MethodDuplicatesHandler;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.Query;
 import com.intellij.util.VisibilityUtil;
@@ -154,7 +154,7 @@
   }
 
   protected String getCommandName() {
-    return RefactoringBundle.message("pullUp.command", UsageViewUtil.getDescriptiveName(mySourceClass));
+    return RefactoringBundle.message("pullUp.command", DescriptiveNameUtil.getDescriptiveName(mySourceClass));
   }
 
   public void moveMembersToBase() throws IncorrectOperationException {
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
index ca3ecc3..48ab4c4 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassToInnerProcessor.java
@@ -24,10 +24,7 @@
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.search.searches.ReferencesSearch;
-import com.intellij.psi.util.PsiElementFilter;
-import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.*;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.PackageWrapper;
 import com.intellij.refactoring.RefactoringBundle;
@@ -186,7 +183,7 @@
         elementsToMakeWritable.add(element);
       }
     }
-    if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilBase.toPsiElementArray(elementsToMakeWritable))) {
+    if (!CommonRefactoringUtil.checkReadOnlyStatus(myProject, PsiUtilCore.toPsiElementArray(elementsToMakeWritable))) {
       return false;
     }
     return true;
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
index 83851b3..e94e32e 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesDialog.java
@@ -25,6 +25,7 @@
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.options.ConfigurationException;
 import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectFileIndex;
 import com.intellij.openapi.roots.ProjectRootManager;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.openapi.util.Pass;
@@ -32,6 +33,8 @@
 import com.intellij.psi.*;
 import com.intellij.psi.search.ProjectScope;
 import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.*;
 import com.intellij.refactoring.move.MoveCallback;
 import com.intellij.refactoring.move.MoveClassesOrPackagesCallback;
@@ -47,6 +50,7 @@
 import com.intellij.ui.ReferenceEditorWithBrowseButton;
 import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.hash.HashSet;
 import com.intellij.util.ui.UIUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -56,6 +60,7 @@
 import java.awt.*;
 import java.awt.event.ActionEvent;
 import java.awt.event.ActionListener;
+import java.util.Set;
 
 public class MoveClassesOrPackagesDialog extends RefactoringDialog {
   @NonNls private static final String RECENTS_KEY = "MoveClassesOrPackagesDialog.RECENTS_KEY";
@@ -270,7 +275,12 @@
 
     if (initialTargetDirectory != null && 
         JavaMoveClassesOrPackagesHandler.packageHasMultipleDirectoriesInModule(myProject, initialTargetDirectory)) {
-      initialTargetDirectory = null;
+      final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(myProject).getFileIndex();
+      final Set<VirtualFile> initialRoots = new HashSet<VirtualFile>();
+      collectSourceRoots(psiElements, fileIndex, initialRoots);
+      if (initialRoots.size() > 1) {
+        initialTargetDirectory = null;
+      }
     }
     ((DestinationFolderComboBox)myDestinationFolderCB).setData(myProject, initialTargetDirectory,
                                                                new Pass<String>() {
@@ -284,6 +294,20 @@
     myHelpID = helpID;
   }
 
+  private static void collectSourceRoots(PsiElement[] psiElements, ProjectFileIndex fileIndex, Set<VirtualFile> initialRoots) {
+    for (PsiElement element : psiElements) {
+      final VirtualFile file = PsiUtilCore.getVirtualFile(element);
+      if (file != null) {
+        final VirtualFile sourceRootForFile = fileIndex.getSourceRootForFile(file);
+        if (sourceRootForFile != null) {
+          initialRoots.add(sourceRootForFile);
+        }
+      } else if (element instanceof PsiDirectoryContainer) {
+        collectSourceRoots(((PsiDirectoryContainer)element).getDirectories(), fileIndex, initialRoots);
+      }
+    }
+  }
+
   protected void doHelpAction() {
     HelpManager.getInstance().invokeHelp(myHelpID);
   }
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
index f487e94..2982483 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveClassesOrPackages/MoveClassesOrPackagesUtil.java
@@ -275,14 +275,15 @@
 
     PsiDirectory[] directories = aPackage != null ? aPackage.getDirectories() : null;
     final ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
-    final boolean filterOutSources = baseDir != null && fileIndex.isInTestSourceContent(baseDir.getVirtualFile());
-    if (directories != null && directories.length == 1 && !(filterOutSources &&
-                                                            !fileIndex.isInTestSourceContent(directories[0].getVirtualFile()))) {
+    final VirtualFile baseDirVirtualFile = baseDir != null ? baseDir.getVirtualFile() : null;
+    final boolean isBaseDirInTestSources = baseDirVirtualFile != null && fileIndex.isInTestSourceContent(baseDirVirtualFile);
+    if (directories != null && directories.length == 1 && (baseDirVirtualFile == null ||
+                                                           fileIndex.isInTestSourceContent(directories[0].getVirtualFile()) == isBaseDirInTestSources)) {
       directory = directories[0];
     }
     else {
       final VirtualFile[] contentSourceRoots = ProjectRootManager.getInstance(project).getContentSourceRoots();
-      if (contentSourceRoots.length == 1 && !(filterOutSources && !fileIndex.isInTestSourceContent(contentSourceRoots[0]))) {
+      if (contentSourceRoots.length == 1 && (baseDirVirtualFile == null || fileIndex.isInTestSourceContent(contentSourceRoots[0]) == isBaseDirInTestSources)) {
         directory = ApplicationManager.getApplication().runWriteAction(new Computable<PsiDirectory>() {
           @Override
           public PsiDirectory compute() {
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
index c67b7b7..0f64675 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveFilesOrDirectories/JavaMoveFilesOrDirectoriesHandler.java
@@ -25,7 +25,7 @@
 import com.intellij.psi.impl.file.JavaDirectoryServiceImpl;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.move.MoveCallback;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.Function;
@@ -63,7 +63,7 @@
     for (PsiElement sourceElement : sourceElements) {
       result.add(sourceElement instanceof PsiClass ? sourceElement.getContainingFile() : sourceElement);
     }
-    return PsiUtilBase.toPsiElementArray(result);
+    return PsiUtilCore.toPsiElementArray(result);
   }
 
   @Override
@@ -91,7 +91,7 @@
                   adjustedElements.add(element);
                 }
               }
-              result.setResult(PsiUtilBase.toPsiElementArray(adjustedElements));
+              result.setResult(PsiUtilCore.toPsiElementArray(adjustedElements));
             }
           }.execute().getResultObject();
         }
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
index 57936c6..35ca3e2 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInner/MoveInnerProcessor.java
@@ -16,7 +16,8 @@
 package com.intellij.refactoring.move.moveInner;
 
 import com.intellij.codeInsight.ChangeContextUtil;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileEditor.FileEditorManager;
 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
@@ -39,7 +40,6 @@
 import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.Function;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
@@ -171,7 +171,7 @@
 
       ChangeContextUtil.encodeContextInfo(myInnerClass, false);
 
-      myInnerClass = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(myInnerClass);
+      myInnerClass = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(myInnerClass);
 
       final MoveInnerOptions moveInnerOptions = new MoveInnerOptions(myInnerClass, myOuterClass, myTargetContainer, myNewClassName);
       final MoveInnerHandler handler = MoveInnerHandler.EP_NAME.forLanguage(myInnerClass.getLanguage());
@@ -407,7 +407,7 @@
                     @NotNull final PsiElement targetContainer) {
     myNewClassName = className;
     myInnerClass = innerClass;
-    myDescriptiveName = UsageViewUtil.getDescriptiveName(myInnerClass);
+    myDescriptiveName = DescriptiveNameUtil.getDescriptiveName(myInnerClass);
     myOuterClass = myInnerClass.getContainingClass();
     myTargetContainer = targetContainer;
     JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(myProject);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
index 67a1c98..1196d73 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodDialogBase.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.move.moveInstanceMethod;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.ui.Messages;
 import com.intellij.psi.PsiClass;
@@ -28,7 +29,6 @@
 import com.intellij.refactoring.ui.RefactoringDialog;
 import com.intellij.ui.ScrollPaneFactory;
 import com.intellij.ui.components.JBList;
-import com.intellij.usageView.UsageViewUtil;
 
 import javax.swing.*;
 import javax.swing.event.ListSelectionEvent;
@@ -109,14 +109,15 @@
     if (targetClass.isInterface()) {
       final Project project = getProject();
       if (ClassInheritorsSearch.search(targetClass, false).findFirst() == null) {
-        final String message = RefactoringBundle.message("0.is.an.interface.that.has.no.implementing.classes", UsageViewUtil.getDescriptiveName(targetClass));
+        final String message = RefactoringBundle.message("0.is.an.interface.that.has.no.implementing.classes", DescriptiveNameUtil
+          .getDescriptiveName(targetClass));
 
         Messages.showErrorDialog(project, message, myRefactoringName);
         return false;
       }
 
       final String message = RefactoringBundle.message("0.is.an.interface.method.implementation.will.be.added.to.all.directly.implementing.classes",
-                                                       UsageViewUtil.getDescriptiveName(targetClass));
+                                                       DescriptiveNameUtil.getDescriptiveName(targetClass));
 
       final int result = Messages.showYesNoDialog(project, message, myRefactoringName,
                                                   Messages.getQuestionIcon());
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
index 5784665..ca844f0 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveInstanceMethod/MoveInstanceMethodProcessor.java
@@ -34,6 +34,7 @@
 import com.intellij.refactoring.util.*;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
+import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.HashSet;
@@ -245,7 +246,7 @@
       for (PsiReference reference : docRefs) {
         reference.bindToElement(method);
       }
-      VisibilityUtil.fixVisibility(usages, method, myNewVisibility);
+      VisibilityUtil.fixVisibility(UsageViewUtil.toElements(usages), method, myNewVisibility);
     }
     catch (IncorrectOperationException e) {
       LOG.error(e);
diff --git a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
index 4efd85f..3f4f59a 100644
--- a/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/move/moveMembers/MoveMembersProcessor.java
@@ -22,7 +22,7 @@
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.util.PsiTreeUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.HelpID;
 import com.intellij.refactoring.RefactoringBundle;
@@ -105,7 +105,7 @@
 
   @NotNull
   protected UsageViewDescriptor createUsageViewDescriptor(UsageInfo[] usages) {
-    return new MoveMemberViewDescriptor(PsiUtilBase.toPsiElementArray(myMembersToMove));
+    return new MoveMemberViewDescriptor(PsiUtilCore.toPsiElementArray(myMembersToMove));
   }
 
   @NotNull
@@ -203,7 +203,7 @@
           final PsiElement anchor;
           if (anchorsInSourceClass.containsKey(member)) {
             final PsiMember memberInSourceClass = anchorsInSourceClass.get(member);
-            //anchor should be already moved as myMembersToMove contains members in order they appear in source class 
+            //anchor should be already moved as myMembersToMove contains members in order they appear in source class
             anchor = memberInSourceClass != null ? movedMembers.get(memberInSourceClass) : null;
           }
           else {
@@ -258,7 +258,8 @@
         filtered.add(usage);
       }
     }
-    VisibilityUtil.fixVisibility(filtered.toArray(new UsageInfo[filtered.size()]), newMember, myNewVisibility);
+    UsageInfo[] infos = filtered.toArray(new UsageInfo[filtered.size()]);
+    VisibilityUtil.fixVisibility(UsageViewUtil.toElements(infos), newMember, myNewVisibility);
   }
 
   protected boolean preprocessUsages(Ref<UsageInfo[]> refUsages) {
diff --git a/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java b/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java
deleted file mode 100644
index 9d188b7..0000000
--- a/java/java-impl/src/com/intellij/refactoring/psi/PropertyUtils.java
+++ /dev/null
@@ -1,281 +0,0 @@
-/*
- * Copyright 2000-2011 JetBrains s.r.o.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-package com.intellij.refactoring.psi;
-
-import com.intellij.openapi.project.Project;
-import com.intellij.psi.*;
-import com.intellij.psi.util.InheritanceUtil;
-import com.intellij.psi.util.PropertyUtil;
-import org.jetbrains.annotations.NonNls;
-import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-public class PropertyUtils {
-    private PropertyUtils() {
-    }
-
-    public static PsiMethod findSetterForField(PsiField field) {
-        final PsiClass containingClass = field.getContainingClass();
-        final Project project = field.getProject();
-        final String propertyName = PropertyUtil.suggestPropertyName(project, field);
-        final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
-        return PropertyUtil.findPropertySetter(containingClass, propertyName, isStatic, true);
-    }
-
-    public static PsiMethod findGetterForField(PsiField field) {
-        final PsiClass containingClass = field.getContainingClass();
-        final Project project = field.getProject();
-        final String propertyName = PropertyUtil.suggestPropertyName(project, field);
-        final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
-        return PropertyUtil.findPropertyGetter(containingClass, propertyName, isStatic, true);
-    }
-
-  /**
-   * If the name of the method looks like a getter and the body consists of a single return statement,
-   * returns the returned expression. Otherwise, returns null.
-   *
-   * @param method the method to check
-   * @return the return value, or null if it doesn't match the condotions.
-   */
-  @Nullable
-  public static PsiExpression getGetterReturnExpression(PsiMethod method) {
-    return method != null && hasGetterSignature(method) ? getSingleReturnValue(method) : null;
-  }
-
-  private static boolean hasGetterSignature(@NotNull PsiMethod method) {
-    return PropertyUtil.isSimplePropertyGetter(method) && !method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
-  }
-
-  @Nullable
-  public static PsiExpression getSingleReturnValue(@NotNull PsiMethod method) {
-    final PsiCodeBlock body = method.getBody();
-    if (body == null) {
-      return null;
-    }
-    final PsiStatement[] statements = body.getStatements();
-    final PsiStatement statement = statements.length != 1 ? null : statements[0];
-    return statement instanceof PsiReturnStatement ? ((PsiReturnStatement)statement).getReturnValue() : null;
-  }
-
-  @Nullable
-  public static PsiField getFieldOfGetter(PsiMethod method) {
-    PsiField field = getSimplyReturnedField(method, getGetterReturnExpression(method));
-    if (field != null) {
-      final PsiType returnType = method.getReturnType();
-      if (returnType != null && field.getType().equalsToText(returnType.getCanonicalText())) {
-        return field;
-      }
-    }
-    return null;
-  }
-
-  @Nullable
-  public static PsiField getSimplyReturnedField(PsiMethod method, @Nullable PsiExpression value) {
-    if (!(value instanceof PsiReferenceExpression)) {
-      return null;
-    }
-
-    final PsiReferenceExpression reference = (PsiReferenceExpression)value;
-    if (hasSubstantialQualifier(reference)) {
-      return null;
-    }
-
-    final PsiElement referent = reference.resolve();
-    if (!(referent instanceof PsiField)) {
-      return null;
-    }
-
-    final PsiField field = (PsiField)referent;
-    return InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), field.getContainingClass(), true) ? field : null;
-  }
-
-  private static boolean hasSubstantialQualifier(PsiReferenceExpression reference) {
-    final PsiExpression qualifier = reference.getQualifierExpression();
-    if (qualifier == null) return false;
-
-    if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) {
-      return false;
-    }
-
-    if (qualifier instanceof PsiReferenceExpression) {
-      return !(((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass);
-    }
-    return true;
-  }
-
-  public static boolean isSimpleGetter(PsiMethod method) {
-    return getFieldOfGetter(method) != null;
-  }
-
-  @Nullable
-  public static PsiField getFieldOfSetter(PsiMethod method) {
-    if (method == null) {
-      return null;
-    }
-    final PsiParameterList parameterList = method.getParameterList();
-    if (parameterList.getParametersCount() != 1) {
-      return null;
-    }
-    @NonNls final String name = method.getName();
-    if (!name.startsWith("set")) {
-      return null;
-    }
-    if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
-      return null;
-    }
-    final PsiCodeBlock body = method.getBody();
-    if (body == null) {
-      return null;
-    }
-    final PsiStatement[] statements = body.getStatements();
-    if (statements.length != 1) {
-      return null;
-    }
-    final PsiStatement statement = statements[0];
-    if (!(statement instanceof PsiExpressionStatement)) {
-      return null;
-    }
-    final PsiExpressionStatement possibleAssignmentStatement = (PsiExpressionStatement)statement;
-    final PsiExpression possibleAssignment = possibleAssignmentStatement.getExpression();
-    if (!(possibleAssignment instanceof PsiAssignmentExpression)) {
-      return null;
-    }
-    final PsiAssignmentExpression assignment = (PsiAssignmentExpression)possibleAssignment;
-    if (!JavaTokenType.EQ.equals(assignment.getOperationTokenType())) {
-      return null;
-    }
-    final PsiExpression lhs = assignment.getLExpression();
-    if (!(lhs instanceof PsiReferenceExpression)) {
-      return null;
-    }
-    final PsiReferenceExpression reference = (PsiReferenceExpression)lhs;
-    final PsiExpression qualifier = reference.getQualifierExpression();
-    if (qualifier instanceof PsiReferenceExpression) {
-      final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
-      final PsiElement target = referenceExpression.resolve();
-      if (!(target instanceof PsiClass)) {
-        return null;
-      }
-    }
-    else if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) {
-      return null;
-    }
-    final PsiElement referent = reference.resolve();
-    if (referent == null) {
-      return null;
-    }
-    if (!(referent instanceof PsiField)) {
-      return null;
-    }
-    final PsiField field = (PsiField)referent;
-    final PsiClass fieldContainingClass = field.getContainingClass();
-    final PsiClass methodContainingClass = method.getContainingClass();
-    if (!InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)) {
-      return null;
-    }
-    final PsiExpression rhs = assignment.getRExpression();
-    if (!(rhs instanceof PsiReferenceExpression)) {
-      return null;
-    }
-    final PsiReferenceExpression rReference = (PsiReferenceExpression)rhs;
-    final PsiExpression rQualifier = rReference.getQualifierExpression();
-    if (rQualifier != null) {
-      return null;
-    }
-    final PsiElement rReferent = rReference.resolve();
-    if (rReferent == null) {
-      return null;
-    }
-    if (!(rReferent instanceof PsiParameter)) {
-      return null;
-    }
-    final PsiType fieldType = field.getType();
-    final PsiType parameterType = ((PsiVariable)rReferent).getType();
-    if (fieldType.equalsToText(parameterType.getCanonicalText())) {
-      return field;
-    }
-    else {
-      return null;
-    }
-  }
-
-  public static boolean isSimpleSetter(PsiMethod method) {
-    return getFieldOfSetter(method) != null;
-  }
-
-  @Nullable
-  public static PsiMethod getReversePropertyMethod(PsiMethod propertyMethod) {
-    if (propertyMethod == null) {
-      return null;
-    }
-    final PsiClass aClass = propertyMethod.getContainingClass();
-    if (aClass == null) {
-      return null;
-    }
-    final String methodName = propertyMethod.getName();
-    final String prefix;
-    if (methodName.startsWith("get")) {
-      prefix = "get";
-    }
-    else if (methodName.startsWith("is")) {
-      prefix = "is";
-    }
-    else if (methodName.startsWith("set")) {
-      prefix = "set";
-    }
-    else {
-      return null;
-    }
-    final String name = methodName.substring(prefix.length());
-    final PsiField field;
-    if (prefix.equals("set")) {
-      field = getFieldOfSetter(propertyMethod);
-    }
-    else {
-      field = getFieldOfGetter(propertyMethod);
-    }
-    if (field == null) {
-      return null;
-    }
-    if (prefix.equals("set")) {
-      final PsiMethod result = findPropertyMethod(aClass, "get", name, field);
-      if (result != null) {
-        return result;
-      }
-      return findPropertyMethod(aClass, "is", name, field);
-    }
-    else {
-      return findPropertyMethod(aClass, "set", name, field);
-    }
-  }
-
-  private static PsiMethod findPropertyMethod(@NotNull PsiClass aClass, @NotNull String prefix, @NotNull String propertyName, @NotNull PsiField field1) {
-    final PsiMethod[] methods = aClass.findMethodsByName(prefix + propertyName, true);
-    for (PsiMethod method : methods) {
-      final PsiField field2;
-      if (prefix.equals("set")) {
-        field2 = getFieldOfSetter(method);
-      }
-      else {
-        field2 = getFieldOfGetter(method);
-      }
-      if (field1.equals(field2)) {
-        return method;
-      }
-    }
-    return null;
-  }
-}
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
index 785c5da..4f3bf58 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/BeanPropertyRenameHandler.java
@@ -23,6 +23,9 @@
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiFile;
 import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.VariableKind;
 import com.intellij.psi.impl.beanProperties.BeanProperty;
 import com.intellij.psi.util.PropertyUtil;
 import com.intellij.refactoring.RenameRefactoring;
@@ -65,6 +68,15 @@
     if (setter != null) {
       final String setterName = PropertyUtil.suggestSetterName(newName);
       rename.addElement(setter, setterName);
+
+      final PsiParameter[] setterParameters = setter.getParameterList().getParameters();
+      if (setterParameters.length == 1) {
+        final JavaCodeStyleManager manager = JavaCodeStyleManager.getInstance(psiElement.getProject());
+        final String suggestedParameterName = manager.propertyNameToVariableName(property.getName(), VariableKind.PARAMETER);
+        if (suggestedParameterName.equals(setterParameters[0].getName())) {
+          rename.addElement(setterParameters[0], manager.propertyNameToVariableName(newName, VariableKind.PARAMETER));
+        }
+      }
     }
 
     final PsiMethod getter = property.getGetter();
diff --git a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
index 1573362..7e485dc 100644
--- a/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/rename/RenameJavaVariableProcessor.java
@@ -260,6 +260,16 @@
   }
 
   @Override
+  public void findExistingNameConflicts(PsiElement element,
+                                        String newName,
+                                        MultiMap<PsiElement, String> conflicts,
+                                        Map<PsiElement, String> allRenames) {
+    for (PsiElement psiElement : allRenames.keySet()) {
+      RenamePsiElementProcessor.forElement(psiElement).findExistingNameConflicts(psiElement, allRenames.get(psiElement), conflicts);
+    }
+  }
+
+  @Override
   public void findExistingNameConflicts(PsiElement element, String newName, MultiMap<PsiElement, String> conflicts) {
     if (element instanceof PsiCompiledElement) return;
     if (element instanceof PsiField) {
diff --git a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
index 2f7af47..202a990 100644
--- a/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/replaceConstructorWithFactory/ReplaceConstructorWithFactoryProcessor.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.replaceConstructorWithFactory;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Ref;
@@ -30,7 +31,6 @@
 import com.intellij.refactoring.util.RefactoringUIUtil;
 import com.intellij.usageView.UsageInfo;
 import com.intellij.usageView.UsageViewDescriptor;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.VisibilityUtil;
 import com.intellij.util.containers.MultiMap;
@@ -300,11 +300,11 @@
   protected String getCommandName() {
     if (myConstructor != null) {
       return RefactoringBundle.message("replace.constructor.0.with.a.factory.method",
-                                       UsageViewUtil.getDescriptiveName(myConstructor));
+                                       DescriptiveNameUtil.getDescriptiveName(myConstructor));
     }
     else {
       return RefactoringBundle.message("replace.default.constructor.of.0.with.a.factory.method",
-                                       UsageViewUtil.getDescriptiveName(myOriginalClass));
+                                       DescriptiveNameUtil.getDescriptiveName(myOriginalClass));
     }
   }
 
diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
index 871c964..ccdeb37 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteProcessor.java
@@ -15,7 +15,7 @@
  */
 package com.intellij.refactoring.safeDelete;
 
-import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableFix;
+import com.intellij.codeInsight.daemon.impl.quickfix.RemoveUnusedVariableUtil;
 import com.intellij.find.findUsages.PsiElement2UsageTargetAdapter;
 import com.intellij.ide.util.SuperMethodWarningUtil;
 import com.intellij.openapi.application.ApplicationManager;
@@ -88,7 +88,9 @@
         boolean hasSideEffects = false;
         if (PsiUtil.isOnAssignmentLeftHand(referencedElement)) {
           hasSideEffects =
-            RemoveUnusedVariableFix.checkSideEffects(((PsiAssignmentExpression)referencedElement.getParent()).getRExpression(), ((PsiLocalVariable)element), new ArrayList<PsiElement>());
+            RemoveUnusedVariableUtil
+              .checkSideEffects(((PsiAssignmentExpression)referencedElement.getParent()).getRExpression(), ((PsiLocalVariable)element),
+                                new ArrayList<PsiElement>());
         }
         usages.add(new SafeDeleteReferenceJavaDeleteUsageInfo(statement, element, isSafeToDelete && !hasSideEffects));
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
index 6d7f6c5..4b586aa 100644
--- a/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
+++ b/java/java-impl/src/com/intellij/refactoring/safeDelete/usageInfo/SafeDeleteExtendsClassUsageInfo.java
@@ -50,7 +50,7 @@
     final PsiReferenceList extendingImplementsList = myExtendingClass.getImplementsList();
     if (extendsList != null) {
       final PsiClassType[] referenceTypes = extendsList.getReferencedTypes();
-      final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() ? myExtendingClass.getExtendsList() : extendingImplementsList;
+      final PsiReferenceList listToAddExtends = refClass.isInterface() == myExtendingClass.isInterface() || myExtendingClass instanceof PsiTypeParameter ? myExtendingClass.getExtendsList() : extendingImplementsList;
       final PsiClassType[] existingRefTypes = listToAddExtends.getReferencedTypes();
       for (PsiClassType referenceType : referenceTypes) {
         if (ArrayUtilRt.find(existingRefTypes, referenceType) > -1) continue;
diff --git a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
index 90372d7..210b8d3 100644
--- a/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/turnRefsToSuper/TurnRefsToSuperProcessor.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.turnRefsToSuper;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.project.Project;
@@ -52,7 +53,7 @@
 
   protected String getCommandName() {
     return RefactoringBundle.message("turn.refs.to.super.command",
-                                     UsageViewUtil.getDescriptiveName(myClass), UsageViewUtil.getDescriptiveName(mySuper));
+                                     DescriptiveNameUtil.getDescriptiveName(myClass), DescriptiveNameUtil.getDescriptiveName(mySuper));
   }
 
   @NotNull
diff --git a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
index c176555..9c723f4 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeCook/TypeCookDialog.java
@@ -15,6 +15,7 @@
  */
 package com.intellij.refactoring.typeCook;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.openapi.help.HelpManager;
 import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.text.StringUtil;
@@ -63,7 +64,7 @@
       PsiElement element = elements[i];
       name.append(StringUtil.capitalize(UsageViewUtil.getType(element)));
       name.append(" ");
-      name.append(UsageViewUtil.getDescriptiveName(element));
+      name.append(DescriptiveNameUtil.getDescriptiveName(element));
       if (i < elements.length - 1) {
         name.append("<br>");
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
index 67e6438..105c383 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeEvaluator.java
@@ -415,24 +415,25 @@
   public static PsiType substituteType(final PsiType migrationTtype, final PsiType originalType, final boolean isContraVariantPosition) {
     if ( originalType instanceof PsiClassType && migrationTtype instanceof PsiClassType) {
       final PsiClass originalClass = ((PsiClassType)originalType).resolve();
-      if (isContraVariantPosition && TypeConversionUtil.erasure(originalType).isAssignableFrom(TypeConversionUtil.erasure(migrationTtype))) {
-        final PsiClass psiClass = ((PsiClassType)migrationTtype).resolve();
-        final PsiSubstitutor substitutor = TypeConversionUtil.getClassSubstitutor(originalClass, psiClass, PsiSubstitutor.EMPTY);
-        if (substitutor != null) {
-          final PsiType psiType =
-              substituteType(migrationTtype, originalType, false, psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(originalClass, substitutor));
+      if (originalClass != null) {
+        if (isContraVariantPosition && TypeConversionUtil.erasure(originalType).isAssignableFrom(TypeConversionUtil.erasure(migrationTtype))) {
+          final PsiClass psiClass = ((PsiClassType)migrationTtype).resolve();
+          final PsiSubstitutor substitutor = psiClass != null ? TypeConversionUtil.getClassSubstitutor(originalClass, psiClass, PsiSubstitutor.EMPTY) : null;
+          if (substitutor != null) {
+            final PsiType psiType =
+                substituteType(migrationTtype, originalType, false, psiClass, JavaPsiFacade.getElementFactory(psiClass.getProject()).createType(originalClass, substitutor));
+            if (psiType != null) {
+              return psiType;
+            }
+          }
+        }
+        else if (!isContraVariantPosition && TypeConversionUtil.erasure(migrationTtype).isAssignableFrom(TypeConversionUtil.erasure(originalType))) {
+          final PsiType psiType = substituteType(migrationTtype, originalType, false, originalClass, JavaPsiFacade.getElementFactory(originalClass.getProject()).createType(originalClass, PsiSubstitutor.EMPTY));
           if (psiType != null) {
             return psiType;
           }
         }
       }
-      else if (!isContraVariantPosition && TypeConversionUtil.erasure(migrationTtype).isAssignableFrom(TypeConversionUtil.erasure(
-        originalType))) {
-        final PsiType psiType = substituteType(migrationTtype, originalType, false, originalClass, JavaPsiFacade.getElementFactory(originalClass.getProject()).createType(originalClass, PsiSubstitutor.EMPTY));
-        if (psiType != null) {
-          return psiType;
-        }
-      }
     }
     return migrationTtype;
   }
diff --git a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
index 7a0bdb6..2f85e7a 100644
--- a/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/typeMigration/TypeMigrationProcessor.java
@@ -26,7 +26,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiImplUtil;
 import com.intellij.psi.impl.source.tree.JavaElementType;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.refactoring.BaseRefactoringProcessor;
 import com.intellij.refactoring.typeMigration.ui.FailedConversionsDialog;
 import com.intellij.refactoring.typeMigration.ui.MigrationPanel;
@@ -76,7 +76,7 @@
     }
     return new PsiElement[]{root};
   }
-  
+
   public TypeMigrationProcessor(final Project project, final PsiElement[] roots, final TypeMigrationRules rules) {
     super(project);
     myRoot = roots;
@@ -106,7 +106,7 @@
                 result.add(element);
               }
             }
-            if (editor != null) RefactoringUtil.highlightAllOccurrences(project, PsiUtilBase.toPsiElementArray(result), editor);
+            if (editor != null) RefactoringUtil.highlightAllOccurrences(project, PsiUtilCore.toPsiElementArray(result), editor);
           }
         });
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java b/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
index f21c11a..7f13923 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/ConflictsUtil.java
@@ -20,13 +20,13 @@
  */
 package com.intellij.refactoring.util;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.source.resolve.FileContextUtil;
 import com.intellij.psi.search.searches.ClassInheritorsSearch;
 import com.intellij.psi.util.PsiFormatUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.usageView.UsageViewUtil;
 import com.intellij.util.Processor;
 import com.intellij.util.containers.MultiMap;
 import org.jetbrains.annotations.NotNull;
@@ -74,7 +74,7 @@
       }
       else { // method somewhere in base class
         if (JavaPsiFacade.getInstance(method.getProject()).getResolveHelper().isAccessible(method, aClass, null)) {
-          String className = CommonRefactoringUtil.htmlEmphasize(UsageViewUtil.getDescriptiveName(method.getContainingClass()));
+          String className = CommonRefactoringUtil.htmlEmphasize(DescriptiveNameUtil.getDescriptiveName(method.getContainingClass()));
           if (PsiUtil.getAccessLevel(prototype.getModifierList()) >= PsiUtil.getAccessLevel(method.getModifierList()) ) {
             boolean isMethodAbstract = method.hasModifierProperty(PsiModifier.ABSTRACT);
             boolean isMyMethodAbstract = refactoredMethod != null && refactoredMethod.hasModifierProperty(PsiModifier.ABSTRACT);
diff --git a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
index c02644f..527c030 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/InlineUtil.java
@@ -16,7 +16,7 @@
 package com.intellij.refactoring.util;
 
 import com.intellij.codeInsight.ChangeContextUtil;
-import com.intellij.codeInsight.daemon.impl.analysis.GenericsHighlightUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaGenericsUtil;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.util.Comparing;
@@ -58,7 +58,7 @@
     PsiType exprType = expr.getType();
     if (exprType != null && (!varType.equals(exprType) && (varType instanceof PsiPrimitiveType || exprType instanceof PsiPrimitiveType)
                              || !TypeConversionUtil.isAssignable(varType, exprType)
-                             || insertCastWhenUnchecked && GenericsHighlightUtil.isRawToGeneric(varType, exprType))) {
+                             || insertCastWhenUnchecked && JavaGenericsUtil.isRawToGeneric(varType, exprType))) {
       boolean matchedTypes = false;
       //try explicit type arguments
       final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
diff --git a/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java b/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
index 8e691a6..2b0163c 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/JavaRefactoringElementDescriptionProvider.java
@@ -15,10 +15,10 @@
  */
 package com.intellij.refactoring.util;
 
+import com.intellij.lang.findUsages.DescriptiveNameUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiFormatUtil;
 import com.intellij.refactoring.RefactoringBundle;
-import com.intellij.usageView.UsageViewUtil;
 import org.jetbrains.annotations.NotNull;
 
 public class JavaRefactoringElementDescriptionProvider implements ElementDescriptionProvider {
@@ -71,7 +71,8 @@
     if ((element instanceof PsiClass)) {
       //TODO : local & anonymous
       PsiClass psiClass = (PsiClass) element;
-      return RefactoringBundle.message("class.description", CommonRefactoringUtil.htmlEmphasize(UsageViewUtil.getDescriptiveName(psiClass)));
+      return RefactoringBundle.message("class.description", CommonRefactoringUtil.htmlEmphasize(
+        DescriptiveNameUtil.getDescriptiveName(psiClass)));
     }
     return null;
   }
diff --git a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
index 218607a..256c3a9 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/ParameterTablePanel.java
@@ -59,23 +59,6 @@
     return myVariableData;
   }
 
-  public static class VariableData {
-    public final PsiVariable variable;
-    public PsiType type;
-    public String name;
-    public boolean passAsParameter;
-
-    public VariableData(PsiVariable var) {
-      variable = var;
-      type = var.getType();
-    }
-
-    public VariableData(PsiVariable var, PsiType type) {
-      variable = var;
-      this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
-    }
-  }
-
   protected abstract void updateSignature();
 
   protected abstract void doEnterAction();
diff --git a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
index b30b63c..80a4a91 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/RefactoringUtil.java
@@ -18,6 +18,7 @@
 import com.intellij.codeInsight.ExpectedTypeInfo;
 import com.intellij.codeInsight.ExpectedTypesProvider;
 import com.intellij.codeInsight.daemon.impl.analysis.HighlightControlFlowUtil;
+import com.intellij.codeInsight.daemon.impl.analysis.JavaHighlightUtil;
 import com.intellij.codeInsight.highlighting.HighlightManager;
 import com.intellij.lang.java.JavaLanguage;
 import com.intellij.openapi.diagnostic.Logger;
@@ -822,21 +823,6 @@
     return buffer.toString();
   }
 
-  public static boolean isSuperOrThisCall(PsiStatement statement, boolean testForSuper, boolean testForThis) {
-    if (!(statement instanceof PsiExpressionStatement)) return false;
-    PsiExpression expression = ((PsiExpressionStatement)statement).getExpression();
-    if (!(expression instanceof PsiMethodCallExpression)) return false;
-    final PsiReferenceExpression methodExpression = ((PsiMethodCallExpression)expression).getMethodExpression();
-    if (testForSuper) {
-      if ("super".equals(methodExpression.getText())) return true;
-    }
-    if (testForThis) {
-      if ("this".equals(methodExpression.getText())) return true;
-    }
-
-    return false;
-  }
-
   public static void visitImplicitSuperConstructorUsages(PsiClass subClass,
                                                          final ImplicitConstructorUsageVisitor implicitConstructorUsageVistor,
                                                          PsiClass superClass) {
@@ -845,7 +831,7 @@
     if (constructors.length > 0) {
       for (PsiMethod constructor : constructors) {
         final PsiStatement[] statements = constructor.getBody().getStatements();
-        if (statements.length < 1 || !isSuperOrThisCall(statements[0], true, true)) {
+        if (statements.length < 1 || !JavaHighlightUtil.isSuperOrThisCall(statements[0], true, true)) {
           implicitConstructorUsageVistor.visitConstructor(constructor, baseDefaultConstructor);
         }
       }
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java
new file mode 100644
index 0000000..7c88fc1
--- /dev/null
+++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MatchUtil.java
@@ -0,0 +1,116 @@
+/*
+ * 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.refactoring.util.duplicates;
+
+import com.intellij.codeInsight.PsiEquivalenceUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
+import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.List;
+import java.util.Map;
+
+public class MatchUtil {
+  @Nullable
+  public static String getChangedSignature(Match match, final PsiMethod method, final boolean shouldBeStatic, String visibility) {
+    final PsiType returnType = match.getChangedReturnType(method);
+    if (!match.myChangedParams.isEmpty() || returnType != null) {
+      @NonNls StringBuilder buffer = new StringBuilder();
+      buffer.append(visibility);
+      if (buffer.length() > 0) {
+        buffer.append(" ");
+      }
+      if (shouldBeStatic) {
+        buffer.append("static ");
+      }
+      final PsiTypeParameterList typeParameterList = method.getTypeParameterList();
+      if (typeParameterList != null) {
+        buffer.append(typeParameterList.getText());
+        buffer.append(" ");
+      }
+
+      buffer.append(PsiFormatUtil.formatType(returnType != null ? returnType : method.getReturnType(), 0, PsiSubstitutor.EMPTY));
+      buffer.append(" ");
+      buffer.append(method.getName());
+      buffer.append("(");
+      int count = 0;
+      final String INDENT = "    ";
+      final List<ParameterInfoImpl> params = patchParams(match.myChangedParams, method);
+      for (ParameterInfoImpl param : params) {
+        String typeText = param.getTypeText();
+        if (count > 0) {
+          buffer.append(",");
+        }
+        buffer.append("\n");
+        buffer.append(INDENT);
+        buffer.append(typeText);
+        buffer.append(" ");
+        buffer.append(param.getName());
+        count++;
+      }
+
+      if (count > 0) {
+        buffer.append("\n");
+      }
+      buffer.append(")");
+      final PsiClassType[] exceptions = method.getThrowsList().getReferencedTypes();
+      if (exceptions.length > 0) {
+        buffer.append("\n");
+        buffer.append("throws\n");
+        for (PsiType exception : exceptions) {
+          buffer.append(INDENT);
+          buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY));
+          buffer.append("\n");
+        }
+      }
+      return buffer.toString();
+    }
+    return null;
+  }
+
+  public static void changeSignature(@NotNull Match match, @NotNull PsiMethod psiMethod) {
+    final PsiType expressionType = match.getChangedReturnType(psiMethod);
+    if (expressionType == null && match.myChangedParams.isEmpty()) return;
+    final List<ParameterInfoImpl> newParameters = patchParams(match.myChangedParams, psiMethod);
+    final ChangeSignatureProcessor csp = new ChangeSignatureProcessor(psiMethod.getProject(), psiMethod, false, null, psiMethod.getName(),
+                                                                      expressionType != null ? expressionType : psiMethod.getReturnType(),
+                                                                      newParameters.toArray(new ParameterInfoImpl[newParameters.size()]));
+
+    csp.run();
+  }
+
+  public static List<ParameterInfoImpl> patchParams(Map<PsiVariable, PsiType> changedParams, final PsiMethod psiMethod) {
+    final ArrayList<ParameterInfoImpl> newParameters = new ArrayList<ParameterInfoImpl>();
+    final PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters();
+    for (int i = 0; i < oldParameters.length; i++) {
+      final PsiParameter oldParameter = oldParameters[i];
+      PsiType type = oldParameter.getType();
+      for (PsiVariable variable : changedParams.keySet()) {
+        if (PsiEquivalenceUtil.areElementsEquivalent(variable, oldParameter)) {
+          type = changedParams.get(variable);
+          break;
+        }
+      }
+      newParameters.add(new ParameterInfoImpl(i, oldParameter.getName(), type));
+    }
+    return newParameters;
+  }
+}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
index 6476aa4..7686126 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
+++ b/java/java-impl/src/com/intellij/refactoring/util/duplicates/MethodDuplicatesMatchProvider.java
@@ -48,7 +48,7 @@
 
   @Override
   public PsiElement processMatch(Match match) throws IncorrectOperationException {
-    match.changeSignature(myMethod);
+    MatchUtil.changeSignature(match, myMethod);
     final PsiClass containingClass = myMethod.getContainingClass();
     if (isEssentialStaticContextAbsent(match)) {
       PsiUtil.setModifierProperty(myMethod, PsiModifier.STATIC, true);
@@ -159,7 +159,8 @@
     final PsiElement matchStart = match.getMatchStart();
     String visibility = VisibilityUtil.getPossibleVisibility(myMethod, matchStart);
     final boolean shouldBeStatic = isEssentialStaticContextAbsent(match);
-    final String signature = match.getChangedSignature(myMethod, myMethod.hasModifierProperty(PsiModifier.STATIC) || shouldBeStatic, visibility);
+    final String signature = MatchUtil
+      .getChangedSignature(match, myMethod, myMethod.hasModifierProperty(PsiModifier.STATIC) || shouldBeStatic, visibility);
     if (signature != null) {
       return RefactoringBundle.message("replace.this.code.fragment.and.change.signature", signature);
     }
diff --git a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
index 7e9b37f..b967928 100644
--- a/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
+++ b/java/java-impl/src/com/intellij/refactoring/wrapreturnvalue/WrapReturnValueProcessor.java
@@ -30,11 +30,11 @@
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.search.searches.OverridingMethodsSearch;
 import com.intellij.psi.search.searches.ReferencesSearch;
+import com.intellij.psi.util.PropertyUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.refactoring.MoveDestination;
 import com.intellij.refactoring.RefactorJBundle;
-import com.intellij.refactoring.psi.PropertyUtils;
 import com.intellij.refactoring.psi.TypeParametersVisitor;
 import com.intellij.refactoring.util.FixableUsageInfo;
 import com.intellij.refactoring.util.FixableUsagesRefactoringProcessor;
@@ -111,7 +111,7 @@
         return unboxedType.getCanonicalText() + "Value()";
       }
 
-      final PsiMethod getter = PropertyUtils.findGetterForField(myDelegateField);
+      final PsiMethod getter = PropertyUtil.findGetterForField(myDelegateField);
       return getter != null ? getter.getName() : "";
     }
     return "";
diff --git a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
index e9f0888..05207ff 100644
--- a/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
+++ b/java/java-impl/src/com/intellij/testIntegration/BaseGenerateTestSupportMethodAction.java
@@ -16,7 +16,7 @@
 package com.intellij.testIntegration;
 
 import com.intellij.codeInsight.CodeInsightActionHandler;
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.codeInsight.generation.GenerateMembersUtil;
 import com.intellij.codeInsight.generation.OverrideImplementUtil;
 import com.intellij.codeInsight.generation.PsiGenerationInfo;
@@ -172,7 +172,7 @@
       GenerateMembersUtil.insertMembersAtOffset(file, offset, Collections.singletonList(info));
 
       final PsiMethod member = info.getPsiMember();
-      return member != null ? CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(member) : null;
+      return member != null ? CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(member) : null;
     }
 
     private static int findOffsetToInsertMethodTo(Editor editor, PsiFile file) {
diff --git a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
index eae2183..b5323ad 100644
--- a/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
+++ b/java/java-impl/src/com/intellij/ui/JavaReferenceEditorUtil.java
@@ -43,11 +43,21 @@
   }
 
   @Nullable
-  public static Document createDocument(final String text, Project project, boolean isClassesAccepted) {
+  public static Document createDocument(final String text,
+                                        Project project,
+                                        boolean isClassesAccepted) {
+    return createDocument(text, project, isClassesAccepted, JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
+  }
+
+  @Nullable
+  public static Document createDocument(final String text,
+                                        Project project,
+                                        boolean isClassesAccepted, 
+                                        JavaCodeFragment.VisibilityChecker visibilityChecker) {
     final PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
     final JavaCodeFragmentFactory factory = JavaCodeFragmentFactory.getInstance(project);
     final JavaCodeFragment fragment = factory.createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
-    fragment.setVisibilityChecker(JavaCodeFragment.VisibilityChecker.EVERYTHING_VISIBLE);
+    fragment.setVisibilityChecker(visibilityChecker);
     return PsiDocumentManager.getInstance(project).getDocument(fragment);
   }
 
diff --git a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
index 718a8c2..e86cbb5 100644
--- a/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
+++ b/java/java-impl/src/com/intellij/ui/ReferenceEditorComboWithBrowseButton.java
@@ -43,7 +43,7 @@
                                               @NotNull final Project project,
                                               boolean toAcceptClasses,
                                               final JavaCodeFragment.VisibilityChecker visibilityChecker, final String recentsKey) {
-    super(new EditorComboBox(createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
+    super(new EditorComboBox(JavaReferenceEditorUtil.createDocument(StringUtil.isEmpty(text) ? "" : text, project, toAcceptClasses, visibilityChecker), project, StdFileTypes.JAVA),
           browseActionListener);
     final List<String> recentEntries = RecentsManager.getInstance(project).getRecentEntries(recentsKey);
     if (recentEntries != null) {
@@ -54,16 +54,6 @@
     }
   }
 
-  private static Document createDocument(final String text,
-                                         Project project,
-                                         boolean isClassesAccepted, 
-                                         final JavaCodeFragment.VisibilityChecker visibilityChecker) {
-    PsiPackage defaultPackage = JavaPsiFacade.getInstance(project).findPackage("");
-    final JavaCodeFragment fragment = JavaCodeFragmentFactory.getInstance(project).createReferenceCodeFragment(text, defaultPackage, true, isClassesAccepted);
-    fragment.setVisibilityChecker(visibilityChecker);
-    return PsiDocumentManager.getInstance(project).getDocument(fragment);
-  }
-
   public String getText(){
     return getChildComponent().getText().trim();
   }
diff --git a/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java b/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
index 4c51caf..2627fd2 100644
--- a/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
+++ b/java/java-impl/src/com/intellij/unscramble/UnscrambleDialog.java
@@ -213,6 +213,10 @@
     return new Action[]{createNormalizeTextAction(), getOKAction(), getCancelAction(), getHelpAction()};
   }
 
+  public JComponent getPreferredFocusedComponent() {
+    return getRootPane().getDefaultButton();
+  }
+
   private void createLogFileChooser() {
     myLogFile = new TextFieldWithHistory();
     JPanel panel = GuiUtils.constructFieldWithBrowseButton(myLogFile, new ActionListener() {
@@ -417,10 +421,6 @@
     return "#com.intellij.unscramble.UnscrambleDialog";
   }
 
-  public JComponent getPreferredFocusedComponent() {
-    return myStacktraceEditorPanel.getEditorComponent();
-  }
-
   @Nullable
   private static String getExceptionName(String unscrambledTrace) {
     @SuppressWarnings("IOResourceOpenedButNotSafelyClosed")
diff --git a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
index f13ae0f..5dd9726 100644
--- a/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
+++ b/java/java-indexing-api/src/com/intellij/psi/search/searches/MethodReferencesSearch.java
@@ -38,7 +38,7 @@
     private final SearchRequestCollector myOptimizer;
     private final boolean isSharedOptimizer;
 
-    public SearchParameters(PsiMethod method, SearchScope scope, boolean strictSignatureSearch, @Nullable SearchRequestCollector optimizer) {
+    public SearchParameters(@NotNull PsiMethod method, @NotNull SearchScope scope, boolean strictSignatureSearch, @Nullable SearchRequestCollector optimizer) {
       myMethod = method;
       myScope = scope;
       myStrictSignatureSearch = strictSignatureSearch;
@@ -46,10 +46,11 @@
       myOptimizer = optimizer != null ? optimizer : new SearchRequestCollector(new SearchSession());
     }
 
-    public SearchParameters(final PsiMethod aClass, SearchScope scope, final boolean strict) {
-      this(aClass, scope, strict, null);
+    public SearchParameters(@NotNull PsiMethod method, @NotNull SearchScope scope, final boolean strict) {
+      this(method, scope, strict, null);
     }
 
+    @NotNull
     public PsiMethod getMethod() {
       return myMethod;
     }
@@ -62,6 +63,7 @@
       return myOptimizer;
     }
 
+    @NotNull
     public SearchScope getScope() {
       return myScope;
     }
@@ -69,7 +71,7 @@
 
   private MethodReferencesSearch() {}
 
-  public static Query<PsiReference> search(final PsiMethod method, SearchScope scope, final boolean strictSignatureSearch) {
+  public static Query<PsiReference> search(@NotNull PsiMethod method, SearchScope scope, final boolean strictSignatureSearch) {
     return search(new SearchParameters(method, scope, strictSignatureSearch));
   }
 
diff --git a/java/java-indexing-impl/java-indexing-impl.iml b/java/java-indexing-impl/java-indexing-impl.iml
index 0379d94..bd58ec0 100644
--- a/java/java-indexing-impl/java-indexing-impl.iml
+++ b/java/java-indexing-impl/java-indexing-impl.iml
@@ -11,9 +11,9 @@
     <orderEntry type="module" module-name="java-psi-impl" exported="" />
     <orderEntry type="module" module-name="indexing-api" exported="" />
     <orderEntry type="module" module-name="indexing-impl" exported="" />
-    <orderEntry type="module" module-name="projectModel-api" />
+    <orderEntry type="module" module-name="projectModel-api" exported="" />
     <orderEntry type="module" module-name="projectModel-impl" />
-    <orderEntry type="module" module-name="java-indexing-api" />
+    <orderEntry type="module" module-name="java-indexing-api" exported="" />
   </component>
 </module>
 
diff --git a/java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
similarity index 91%
rename from java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
rename to java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
index f7edb1e..1fec41c 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
+++ b/java/java-indexing-impl/src/com/intellij/codeInsight/ConditionCheckManager.java
@@ -40,14 +40,14 @@
   @SuppressWarnings({"FieldCanBeLocal", "UnusedDeclaration"}) private State state;
   private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheckManager");
 
-  private List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
-  private List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myIsNullCheckMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myIsNotNullCheckMethods = new ArrayList<ConditionChecker>();
 
-  private List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
-  private List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertIsNullMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertIsNotNullMethods = new ArrayList<ConditionChecker>();
 
-  private List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
-  private List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertTrueMethods = new ArrayList<ConditionChecker>();
+  private final List<ConditionChecker> myAssertFalseMethods = new ArrayList<ConditionChecker>();
 
   public static ConditionCheckManager getInstance(Project project) {
     return ServiceManager.getService(project, ConditionCheckManager.class);
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
index 2aad613..600bfc0 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearchHelper.java
@@ -1,5 +1,8 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ReadActionProcessor;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.TextRange;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
@@ -12,6 +15,7 @@
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.util.PairProcessor;
 import com.intellij.util.Processor;
+import org.jetbrains.annotations.NotNull;
 
 /**
  * @author max
@@ -19,31 +23,30 @@
 public class ConstructorReferencesSearchHelper {
   private final PsiManager myManager;
 
-  public ConstructorReferencesSearchHelper(final PsiManager manager) {
+  public ConstructorReferencesSearchHelper(@NotNull PsiManager manager) {
     myManager = manager;
   }
 
-  public boolean processConstructorReferences(final Processor<PsiReference> processor,
-                                              final PsiMethod constructor,
-                                              final SearchScope searchScope,
+  public boolean processConstructorReferences(@NotNull final Processor<PsiReference> processor,
+                                              @NotNull final PsiMethod constructor,
+                                              @NotNull final PsiClass containingClass,
+                                              @NotNull final SearchScope searchScope,
                                               boolean ignoreAccessScope,
-                                              final boolean isStrictSignatureSearch, SearchRequestCollector collector) {
-    PsiClass aClass = constructor.getContainingClass();
-    if (aClass == null) {
-      return true;
-    }
-
-    if (aClass.isEnum()) {
-      for (PsiField field : aClass.getFields()) {
-        if (field instanceof PsiEnumConstant) {
-          PsiReference reference = field.getReference();
-          if (reference != null && reference.isReferenceTo(constructor)) {
-            if (!processor.process(reference)) {
-              return false;
-            }
-          }
-        }
+                                              final boolean isStrictSignatureSearch,
+                                              @NotNull SearchRequestCollector collector) {
+    final boolean[] constructorCanBeCalledImplicitly = new boolean[1];
+    final boolean[] isEnum = new boolean[1];
+    final boolean[] isUnder18 = new boolean[1];
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        constructorCanBeCalledImplicitly[0] = constructor.getParameterList().getParametersCount() == 0;
+        isEnum[0] = containingClass.isEnum();
+        isUnder18[0] = PsiUtil.getLanguageLevel(containingClass).isAtLeast(LanguageLevel.JDK_1_8);
       }
+    });
+
+    if (isEnum[0]) {
+      if (!processEnumReferences(processor, constructor, containingClass)) return false;
     }
 
     // search usages like "new XXX(..)"
@@ -63,7 +66,7 @@
               }
             }
             else {
-              if (myManager.areElementsEquivalent(constructor.getContainingClass(), constructor1.getContainingClass())) {
+              if (myManager.areElementsEquivalent(containingClass, constructor1.getContainingClass())) {
                 return processor.process(reference);
               }
             }
@@ -73,30 +76,18 @@
       }
     };
 
-    ReferencesSearch.searchOptimized(aClass, searchScope, ignoreAccessScope, collector, true, processor1);
-    if (PsiUtil.getLanguageLevel(aClass).isAtLeast(LanguageLevel.JDK_1_8)) {
-      ReferencesSearch.search(aClass).forEach(new Processor<PsiReference>() {
-        @Override
-        public boolean process(PsiReference reference) {
-          final PsiElement element = reference.getElement();
-          if (element != null) {
-            final PsiElement parent = element.getParent();
-            if (parent instanceof PsiMethodReferenceExpression &&
-                ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
-              if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
-                processor.process((PsiReference)parent);
-              }
-            }
-          }
-          return true;
-        }
-      });
+    ReferencesSearch.searchOptimized(containingClass, searchScope, ignoreAccessScope, collector, true, processor1);
+    if (isUnder18[0]) {
+      if (!process18MethodPointers(processor, constructor, containingClass)) return false;
     }
 
-    final boolean constructorCanBeCalledImplicitly = constructor.getParameterList().getParametersCount() == 0;
     // search usages like "this(..)"
-    if (!processSuperOrThis(processor, aClass, constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
-                            PsiKeyword.THIS)) {
+    if (!ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        return processSuperOrThis(containingClass, constructor, constructorCanBeCalledImplicitly[0], searchScope, isStrictSignatureSearch,
+                                  PsiKeyword.THIS, processor);
+      }
+    })) {
       return false;
     }
 
@@ -104,22 +95,69 @@
     Processor<PsiClass> processor2 = new Processor<PsiClass>() {
       @Override
       public boolean process(PsiClass inheritor) {
-        return processSuperOrThis(processor, (PsiClass)inheritor.getNavigationElement(), constructor, constructorCanBeCalledImplicitly, searchScope, isStrictSignatureSearch,
-                                  PsiKeyword.SUPER);
+        final PsiElement navigationElement = inheritor.getNavigationElement();
+        if (navigationElement instanceof PsiClass) {
+          return processSuperOrThis((PsiClass)navigationElement, constructor, constructorCanBeCalledImplicitly[0], searchScope,
+                                    isStrictSignatureSearch, PsiKeyword.SUPER, processor);
+        }
+        return true;
       }
     };
 
-    return ClassInheritorsSearch.search(aClass, searchScope, false).forEach(processor2);
+    return ClassInheritorsSearch.search(containingClass, searchScope, false).forEach(processor2);
   }
 
-  private boolean processSuperOrThis(final Processor<PsiReference> processor,
-                                                             final PsiClass inheritor,
-                                                             final PsiMethod constructor, final boolean constructorCanBeCalledImplicitly, final SearchScope searchScope,
-                                                             final boolean isStrictSignatureSearch,
-                                                             final String superOrThisKeyword) {
+  private static boolean processEnumReferences(@NotNull final Processor<PsiReference> processor,
+                                               @NotNull final PsiMethod constructor,
+                                               @NotNull final PsiClass aClass) {
+    return ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        for (PsiField field : aClass.getFields()) {
+          if (field instanceof PsiEnumConstant) {
+            PsiReference reference = field.getReference();
+            if (reference != null && reference.isReferenceTo(constructor)) {
+              if (!processor.process(reference)) {
+                return false;
+              }
+            }
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  private static boolean process18MethodPointers(@NotNull final Processor<PsiReference> processor,
+                                                 @NotNull final PsiMethod constructor,
+                                                 @NotNull PsiClass aClass) {
+    return ReferencesSearch.search(aClass).forEach(new ReadActionProcessor<PsiReference>() {
+      @Override
+      public boolean processInReadAction(PsiReference reference) {
+        final PsiElement element = reference.getElement();
+        if (element != null) {
+          final PsiElement parent = element.getParent();
+          if (parent instanceof PsiMethodReferenceExpression &&
+              ((PsiMethodReferenceExpression)parent).getReferenceNameElement() instanceof PsiKeyword) {
+            if (((PsiMethodReferenceExpression)parent).isReferenceTo(constructor)) {
+              if (!processor.process((PsiReference)parent)) return false;
+            }
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  private boolean processSuperOrThis(@NotNull PsiClass inheritor,
+                                     @NotNull PsiMethod constructor,
+                                     final boolean constructorCanBeCalledImplicitly,
+                                     @NotNull SearchScope searchScope,
+                                     final boolean isStrictSignatureSearch,
+                                     @NotNull String superOrThisKeyword,
+                                     @NotNull Processor<PsiReference> processor) {
     PsiMethod[] constructors = inheritor.getConstructors();
     if (constructors.length == 0 && constructorCanBeCalledImplicitly) {
-      processImplicitConstructorCall(inheritor, processor, constructor, inheritor);
+      if (!processImplicitConstructorCall(inheritor, processor, constructor, inheritor)) return false;
     }
     for (PsiMethod method : constructors) {
       PsiCodeBlock body = method.getBody();
@@ -134,7 +172,7 @@
           if (expr instanceof PsiMethodCallExpression) {
             PsiReferenceExpression refExpr = ((PsiMethodCallExpression)expr).getMethodExpression();
             if (PsiSearchScopeUtil.isInScope(searchScope, refExpr)) {
-              if (refExpr.getText().equals(superOrThisKeyword)) {
+              if (refExpr.textMatches(superOrThisKeyword)) {
                 PsiElement referencedElement = refExpr.resolve();
                 if (referencedElement instanceof PsiMethod) {
                   PsiMethod constructor1 = (PsiMethod)referencedElement;
@@ -151,43 +189,48 @@
         }
       }
       if (constructorCanBeCalledImplicitly) {
-        processImplicitConstructorCall(method, processor, constructor, inheritor);
+        if (!processImplicitConstructorCall(method, processor, constructor, inheritor)) return false;
       }
     }
 
     return true;
   }
 
-  private void processImplicitConstructorCall(final PsiMember usage,
-                                              final Processor<PsiReference> processor,
-                                              final PsiMethod constructor,
-                                              final PsiClass containingClass) {
-    if (containingClass instanceof PsiAnonymousClass) return;
-    PsiClass superClass = containingClass.getSuperClass();
-    if (myManager.areElementsEquivalent(constructor.getContainingClass(), superClass)) {
-      processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
-        @Override
-        public PsiElement getElement() {
-          return usage;
-        }
-
-        @Override
-        public TextRange getRangeInElement() {
-          if (usage instanceof PsiClass) {
-            PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
-            if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          else if (usage instanceof PsiField) {
-            PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
-            return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          else if (usage instanceof PsiMethod) {
-            PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
-            if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
-          }
-          return super.getRangeInElement();
-        }
-      });
+  private boolean processImplicitConstructorCall(@NotNull final PsiMember usage,
+                                                 @NotNull final Processor<PsiReference> processor,
+                                                 @NotNull final PsiMethod constructor,
+                                                 @NotNull final PsiClass containingClass) {
+    if (containingClass instanceof PsiAnonymousClass) return true;
+    boolean same = ApplicationManager.getApplication().runReadAction(new Computable<Boolean>() {
+      public Boolean compute() {
+        return myManager.areElementsEquivalent(constructor.getContainingClass(), containingClass.getSuperClass());
+      }
+    });
+    if (!same) {
+      return true;
     }
+    return processor.process(new LightMemberReference(myManager, usage, PsiSubstitutor.EMPTY) {
+      @Override
+      public PsiElement getElement() {
+        return usage;
+      }
+
+      @Override
+      public TextRange getRangeInElement() {
+        if (usage instanceof PsiClass) {
+          PsiIdentifier identifier = ((PsiClass)usage).getNameIdentifier();
+          if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        else if (usage instanceof PsiField) {
+          PsiIdentifier identifier = ((PsiField)usage).getNameIdentifier();
+          return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        else if (usage instanceof PsiMethod) {
+          PsiIdentifier identifier = ((PsiMethod)usage).getNameIdentifier();
+          if (identifier != null) return TextRange.from(identifier.getStartOffsetInParent(), identifier.getTextLength());
+        }
+        return super.getRangeInElement();
+      }
+    });
   }
 }
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
index 933a748..5bc07cb 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/ConstructorReferencesSearcher.java
@@ -1,9 +1,9 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.psi.PsiElement;
-import com.intellij.psi.PsiMethod;
-import com.intellij.psi.PsiReference;
+import com.intellij.openapi.util.Computable;
+import com.intellij.psi.*;
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.util.Processor;
 import org.jetbrains.annotations.NotNull;
@@ -12,16 +12,26 @@
  * @author max
  */
 public class ConstructorReferencesSearcher extends QueryExecutorBase<PsiReference, ReferencesSearch.SearchParameters> {
-  public ConstructorReferencesSearcher() {
-    super(true);
-  }
-
   @Override
   public void processQuery(@NotNull ReferencesSearch.SearchParameters p, @NotNull Processor<PsiReference> consumer) {
     final PsiElement element = p.getElementToSearch();
-    if (element instanceof PsiMethod && ((PsiMethod)element).isConstructor()) {
-      new ConstructorReferencesSearchHelper(element.getManager())
-        .processConstructorReferences(consumer, (PsiMethod)p.getElementToSearch(), p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
+    if (!(element instanceof PsiMethod)) {
+      return;
     }
+    final PsiMethod method = (PsiMethod)element;
+    final PsiManager[] manager = new PsiManager[1];
+    PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+      public PsiClass compute() {
+        if (!method.isConstructor()) return null;
+        PsiClass aClass = method.getContainingClass();
+        manager[0] = aClass == null ? null : aClass.getManager();
+        return aClass;
+      }
+    });
+    if (aClass == null) {
+      return;
+    }
+    new ConstructorReferencesSearchHelper(manager[0])
+      .processConstructorReferences(consumer, method, aClass, p.getScope(), p.isIgnoreAccessScope(), true, p.getOptimizer());
   }
 }
diff --git a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
index 49bd3f3..ec298ce 100644
--- a/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
+++ b/java/java-indexing-impl/src/com/intellij/psi/impl/search/MethodUsagesSearcher.java
@@ -1,7 +1,8 @@
 package com.intellij.psi.impl.search;
 
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.application.QueryExecutorBase;
-import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Computable;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.search.SearchRequestCollector;
@@ -17,66 +18,77 @@
  * @author max
  */
 public class MethodUsagesSearcher extends QueryExecutorBase<PsiReference, MethodReferencesSearch.SearchParameters> {
-  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.search.MethodUsagesSearcher");
-  public MethodUsagesSearcher() {
-    super(true);
-  }
-
   @Override
   public void processQuery(@NotNull MethodReferencesSearch.SearchParameters p, @NotNull final Processor<PsiReference> consumer) {
     final PsiMethod method = p.getMethod();
+    final boolean[] isConstructor = new boolean[1];
+    final PsiManager[] psiManager = new PsiManager[1];
+    final String[] methodName = new String[1];
+    final boolean[] isValueAnnotation = new boolean[1];
+    final boolean[] needStrictSignatureSearch = new boolean[1];
+    final boolean strictSignatureSearch = p.isStrictSignatureSearch();
+
+    final PsiClass aClass = ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+      public PsiClass compute() {
+        PsiClass aClass = method.getContainingClass();
+        if (aClass == null) return null;
+        isConstructor[0] = method.isConstructor();
+        psiManager[0] = aClass.getManager();
+        methodName[0] = method.getName();
+        isValueAnnotation[0] = PsiUtil.isAnnotationMethod(method) &&
+                    PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(methodName[0]) &&
+                    method.getParameterList().getParametersCount() == 0;
+        needStrictSignatureSearch[0] = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
+                                                                 || aClass.hasModifierProperty(PsiModifier.FINAL)
+                                                                 || method.hasModifierProperty(PsiModifier.STATIC)
+                                                                 || method.hasModifierProperty(PsiModifier.FINAL)
+                                                                 || method.hasModifierProperty(PsiModifier.PRIVATE));
+        return aClass;
+      }
+    });
+    if (aClass == null) return;
+
     final SearchRequestCollector collector = p.getOptimizer();
 
     final SearchScope searchScope = p.getScope();
 
-    final PsiManager psiManager = method.getManager();
-
-    final PsiClass aClass = method.getContainingClass();
-    if (aClass == null) return;
-
-    final boolean strictSignatureSearch = p.isStrictSignatureSearch();
-
-    if (method.isConstructor()) {
-      new ConstructorReferencesSearchHelper(psiManager).
-        processConstructorReferences(consumer, method, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
+    if (isConstructor[0]) {
+      new ConstructorReferencesSearchHelper(psiManager[0]).
+        processConstructorReferences(consumer, method, aClass, searchScope, !strictSignatureSearch, strictSignatureSearch, collector);
     }
 
-    if (PsiUtil.isAnnotationMethod(method) &&
-        PsiAnnotation.DEFAULT_REFERENCED_METHOD_NAME.equals(method.getName()) &&
-        method.getParameterList().getParametersCount() == 0) {
-      ReferencesSearch.search(aClass, p.getScope()).forEach(PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer( consumer));
+    if (isValueAnnotation[0]) {
+      Processor<PsiReference> refProcessor = PsiAnnotationMethodReferencesSearcher.createImplicitDefaultAnnotationMethodConsumer(consumer);
+      ReferencesSearch.search(aClass, searchScope).forEach(refProcessor);
     }
 
-    boolean needStrictSignatureSearch = strictSignatureSearch && (aClass instanceof PsiAnonymousClass
-                                                             || aClass.hasModifierProperty(PsiModifier.FINAL)
-                                                             || method.hasModifierProperty(PsiModifier.STATIC)
-                                                             || method.hasModifierProperty(PsiModifier.FINAL)
-                                                             || method.hasModifierProperty(PsiModifier.PRIVATE));
-    if (needStrictSignatureSearch) {
+    if (needStrictSignatureSearch[0]) {
       ReferencesSearch.searchOptimized(method, searchScope, false, collector, consumer);
       return;
     }
 
-    final String textToSearch = method.getName();
-    if (StringUtil.isEmpty(textToSearch)) {
+    if (StringUtil.isEmpty(methodName[0])) {
       return;
     }
-    final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(textToSearch, false);
 
-    SearchScope accessScope = methods[0].getUseScope();
-    for (int i = 1; i < methods.length; i++) {
-      PsiMethod method1 = methods[i];
-      accessScope = accessScope.union(method1.getUseScope());
-    }
+    ApplicationManager.getApplication().runReadAction(new Runnable() {
+      public void run() {
+        final PsiMethod[] methods = strictSignatureSearch ? new PsiMethod[]{method} : aClass.findMethodsByName(methodName[0], false);
+        SearchScope accessScope = methods[0].getUseScope();
+        for (int i = 1; i < methods.length; i++) {
+          PsiMethod method1 = methods[i];
+          accessScope = accessScope.union(method1.getUseScope());
+        }
 
-    final SearchScope restrictedByAccess = searchScope.intersectWith(accessScope);
+        SearchScope restrictedByAccessScope = searchScope.intersectWith(accessScope);
 
-    short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
-    collector.searchWord(textToSearch, restrictedByAccess, searchContext, true,
-                         new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
+        short searchContext = UsageSearchContext.IN_CODE | UsageSearchContext.IN_COMMENTS | UsageSearchContext.IN_FOREIGN_LANGUAGES;
+        collector.searchWord(methodName[0], restrictedByAccessScope, searchContext, true,
+                             new MethodTextOccurrenceProcessor(aClass, strictSignatureSearch, methods));
 
-    SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccess, collector);
-
+        SimpleAccessorReferenceSearcher.addPropertyAccessUsages(method, restrictedByAccessScope, collector);
+      }
+    });
   }
 
 }
diff --git a/java/java-psi-api/java-psi-api.iml b/java/java-psi-api/java-psi-api.iml
index 4256838..caff682 100644
--- a/java/java-psi-api/java-psi-api.iml
+++ b/java/java-psi-api/java-psi-api.iml
@@ -8,7 +8,6 @@
     <orderEntry type="inheritedJdk" />
     <orderEntry type="sourceFolder" forTests="false" />
     <orderEntry type="module" module-name="core-api" exported="" />
-    <orderEntry type="module" module-name="projectModel-api" />
   </component>
 </module>
 
diff --git a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
index 9774133..e980c0a 100644
--- a/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
+++ b/java/java-psi-api/src/com/intellij/pom/java/LanguageLevel.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -17,6 +17,8 @@
 
 import com.intellij.core.JavaCoreBundle;
 import com.intellij.openapi.util.Key;
+import org.jetbrains.annotations.Nls;
+import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 /**
@@ -35,38 +37,22 @@
 
   private final String myPresentableText;
 
-  private LanguageLevel(final String presentableText) {
+  LanguageLevel(@NotNull @Nls String presentableText) {
     myPresentableText = presentableText;
   }
 
-  /** @deprecated (to remove in IDEA 13) */
-  @SuppressWarnings("UnusedDeclaration")
-  public int getIndex() {
-    return ordinal() + 3;  // solely for backward compatibility
-  }
-
-  /** @deprecated (to remove in IDEA 13) */
-  @SuppressWarnings("UnusedDeclaration")
-  public boolean hasAssertKeyword() {
-    return isAtLeast(JDK_1_4);
-  }
-
-  /** @deprecated use {@linkplain com.intellij.psi.util.PsiUtil#isLanguageLevel5OrHigher(com.intellij.psi.PsiElement)} (to remove in IDEA 13) */
-  @SuppressWarnings("UnusedDeclaration")
-  public boolean hasEnumKeywordAndAutoboxing() {
-    return isAtLeast(JDK_1_5);
-  }
-
+  @NotNull
+  @Nls
   public String getPresentableText() {
     return myPresentableText;
   }
 
-  public boolean isAtLeast(final LanguageLevel level) {
+  public boolean isAtLeast(@NotNull LanguageLevel level) {
     return compareTo(level) >= 0;
   }
 
   @Nullable
-  public static LanguageLevel parse(final String value) {
+  public static LanguageLevel parse(@Nullable String value) {
     if ("1.3".equals(value)) return JDK_1_3;
     if ("1.4".equals(value)) return JDK_1_4;
     if ("1.5".equals(value)) return JDK_1_5;
diff --git a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
index f2a6236..7c25697 100644
--- a/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/GenericsUtil.java
@@ -16,6 +16,7 @@
 package com.intellij.psi;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.Pair;
 import com.intellij.psi.search.GlobalSearchScope;
@@ -47,6 +48,7 @@
     if (TypeConversionUtil.isPrimitiveAndNotNull(type1) || TypeConversionUtil.isPrimitiveAndNotNull(type2)) return null;
     if (TypeConversionUtil.isNullType(type1)) return type2;
     if (TypeConversionUtil.isNullType(type2)) return type1;
+    if (Comparing.equal(type1, type2)) return type1;
     return getLeastUpperBound(type1, type2, new LinkedHashSet<Pair<PsiType, PsiType>>(), manager);
   }
 
diff --git a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
index d669624..ab97463 100644
--- a/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/LambdaUtil.java
@@ -789,6 +789,18 @@
     return null;
   }
 
+  public static boolean isValidQualifier4InterfaceStaticMethodCall(@NotNull PsiMethod method, @NotNull PsiReferenceExpression methodReferenceExpression) {
+    if (PsiUtil.isLanguageLevel8OrHigher(methodReferenceExpression)) {
+      final PsiExpression qualifierExpression = methodReferenceExpression.getQualifierExpression();
+      final PsiClass containingClass = method.getContainingClass();
+      if (containingClass != null && containingClass.isInterface() && method.hasModifierProperty(PsiModifier.STATIC)) {
+        return qualifierExpression == null && PsiTreeUtil.isAncestor(containingClass, methodReferenceExpression, true)||
+               qualifierExpression instanceof PsiReferenceExpression && ((PsiReferenceExpression)qualifierExpression).resolve() == containingClass;
+      }
+    }
+    return true;
+  }
+  
   static class TypeParamsChecker extends PsiTypeVisitor<Boolean> {
     private PsiMethod myMethod;
     private final PsiClass myClass;
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
index 85fae45..6fe40d8 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiCapturedWildcardType.java
@@ -99,7 +99,7 @@
     }
     else {
       return bound instanceof PsiCapturedWildcardType
-             ? ((PsiCapturedWildcardType)bound).getUpperBound()
+             ? PsiWildcardType.createSuper(myContext.getManager(), ((PsiCapturedWildcardType)bound).getUpperBound())
              : PsiType.getJavaLangObject(myContext.getManager(), getResolveScope());
     }
   }
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
index a0eaeae..f32eb81 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiJavaCodeReferenceElement.java
@@ -23,7 +23,7 @@
  * Represents a reference found in Java code (either an identifier or a sequence of identifiers
  * separated by periods, optionally with generic type arguments).
  */
-public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualifiedReference {
+public interface PsiJavaCodeReferenceElement extends PsiJavaReference, PsiQualifiedReferenceElement {
   /**
    * The empty array of PSI Java code references which can be reused to avoid unnecessary allocations.
    */
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
index b051604..c5b282c 100644
--- a/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/PsiMethodReferenceUtil.java
@@ -19,6 +19,7 @@
 import com.intellij.openapi.project.Project;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.util.*;
+import com.intellij.util.Function;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -165,7 +166,12 @@
           if (interfaceReturnType == PsiType.VOID) return true;
           final PsiParameter[] parameters = method.getParameterList().getParameters();
           if (resolve == JavaPsiFacade.getElementFactory(resolve.getProject()).getArrayClass(PsiUtil.getLanguageLevel(resolve))) {
-            if (parameters.length != 1 || parameters[0].getType() != PsiType.INT) return false;
+            if (!arrayCompatibleSignature(parameters, new Function<PsiParameter[], PsiType>() {
+              @Override
+              public PsiType fun(PsiParameter[] parameters) {
+                return resolveResult.getSubstitutor().substitute(parameters[0].getType());
+              }
+            })) return false;
             final PsiTypeParameter[] typeParameters = ((PsiClass)resolve).getTypeParameters();
             if (typeParameters.length == 1) {
               final PsiType arrayComponentType = result.getSubstitutor().substitute(typeParameters[0]);
@@ -281,7 +287,12 @@
 
 
   public static boolean onArrayType(PsiClass containingClass, MethodSignature signature) {
-    if (signature.getParameterTypes().length == 1 && signature.getParameterTypes()[0] == PsiType.INT) {
+    if (arrayCompatibleSignature(signature.getParameterTypes(), new Function<PsiType[], PsiType>() {
+      @Override
+      public PsiType fun(PsiType[] types) {
+        return types[0];
+      }
+    })) {
       if (containingClass != null) {
         final Project project = containingClass.getProject();
         final LanguageLevel level = PsiUtil.getLanguageLevel(containingClass);
@@ -291,6 +302,14 @@
     return false;
   }
 
+  private static <T> boolean arrayCompatibleSignature(T[] paramTypes, Function<T[], PsiType> fun) {
+    if (paramTypes.length == 1) {
+      final PsiType paramType = fun.fun(paramTypes);
+      if (paramType != null && TypeConversionUtil.isAssignable(PsiType.INT, paramType)) return true;
+    }
+    return false;
+  }
+
   private static PsiType getExpandedType(PsiType type, @NotNull PsiElement typeElement) {
     if (type instanceof PsiArrayType) {
       type = JavaPsiFacade.getElementFactory(typeElement.getProject()).getArrayClassType(((PsiArrayType)type).getComponentType(),
diff --git a/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java b/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java
new file mode 100644
index 0000000..3aa87c0
--- /dev/null
+++ b/java/java-psi-api/src/com/intellij/psi/PsiTemplateStatement.java
@@ -0,0 +1,19 @@
+/*
+ * 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.psi;
+
+public interface PsiTemplateStatement extends PsiStatement {
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointer.java b/java/java-psi-api/src/com/intellij/psi/SmartTypePointer.java
similarity index 100%
rename from java/openapi/src/com/intellij/psi/SmartTypePointer.java
rename to java/java-psi-api/src/com/intellij/psi/SmartTypePointer.java
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java b/java/java-psi-api/src/com/intellij/psi/SmartTypePointerManager.java
similarity index 100%
rename from java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
rename to java/java-psi-api/src/com/intellij/psi/SmartTypePointerManager.java
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
index 6452f52..9bb742f 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PropertyUtil.java
@@ -626,4 +626,256 @@
     }
     return null;
   }
+
+  public static PsiMethod findSetterForField(PsiField field) {
+      final PsiClass containingClass = field.getContainingClass();
+      final Project project = field.getProject();
+      final String propertyName = suggestPropertyName(project, field);
+      final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+      return findPropertySetter(containingClass, propertyName, isStatic, true);
+  }
+
+  public static PsiMethod findGetterForField(PsiField field) {
+      final PsiClass containingClass = field.getContainingClass();
+      final Project project = field.getProject();
+      final String propertyName = suggestPropertyName(project, field);
+      final boolean isStatic = field.hasModifierProperty(PsiModifier.STATIC);
+      return findPropertyGetter(containingClass, propertyName, isStatic, true);
+  }
+
+  /**
+ * If the name of the method looks like a getter and the body consists of a single return statement,
+ * returns the returned expression. Otherwise, returns null.
+ *
+ * @param method the method to check
+ * @return the return value, or null if it doesn't match the condotions.
+ */
+@Nullable
+public static PsiExpression getGetterReturnExpression(PsiMethod method) {
+  return method != null && hasGetterSignature(method) ? getSingleReturnValue(method) : null;
+}
+
+  private static boolean hasGetterSignature(@NotNull PsiMethod method) {
+  return isSimplePropertyGetter(method) && !method.hasModifierProperty(PsiModifier.SYNCHRONIZED);
+}
+
+  @Nullable
+public static PsiExpression getSingleReturnValue(@NotNull PsiMethod method) {
+  final PsiCodeBlock body = method.getBody();
+  if (body == null) {
+    return null;
+  }
+  final PsiStatement[] statements = body.getStatements();
+  final PsiStatement statement = statements.length != 1 ? null : statements[0];
+  return statement instanceof PsiReturnStatement ? ((PsiReturnStatement)statement).getReturnValue() : null;
+}
+
+  @Nullable
+public static PsiField getFieldOfGetter(PsiMethod method) {
+  PsiField field = getSimplyReturnedField(method, getGetterReturnExpression(method));
+  if (field != null) {
+    final PsiType returnType = method.getReturnType();
+    if (returnType != null && field.getType().equalsToText(returnType.getCanonicalText())) {
+      return field;
+    }
+  }
+  return null;
+}
+
+  @Nullable
+public static PsiField getSimplyReturnedField(PsiMethod method, @Nullable PsiExpression value) {
+  if (!(value instanceof PsiReferenceExpression)) {
+    return null;
+  }
+
+  final PsiReferenceExpression reference = (PsiReferenceExpression)value;
+  if (hasSubstantialQualifier(reference)) {
+    return null;
+  }
+
+  final PsiElement referent = reference.resolve();
+  if (!(referent instanceof PsiField)) {
+    return null;
+  }
+
+  final PsiField field = (PsiField)referent;
+  return InheritanceUtil.isInheritorOrSelf(method.getContainingClass(), field.getContainingClass(), true) ? field : null;
+}
+
+  private static boolean hasSubstantialQualifier(PsiReferenceExpression reference) {
+  final PsiExpression qualifier = reference.getQualifierExpression();
+  if (qualifier == null) return false;
+
+  if (qualifier instanceof PsiThisExpression || qualifier instanceof PsiSuperExpression) {
+    return false;
+  }
+
+  if (qualifier instanceof PsiReferenceExpression) {
+    return !(((PsiReferenceExpression)qualifier).resolve() instanceof PsiClass);
+  }
+  return true;
+}
+
+  public static boolean isSimpleGetter(PsiMethod method) {
+  return getFieldOfGetter(method) != null;
+}
+
+  @Nullable
+public static PsiField getFieldOfSetter(PsiMethod method) {
+  if (method == null) {
+    return null;
+  }
+  final PsiParameterList parameterList = method.getParameterList();
+  if (parameterList.getParametersCount() != 1) {
+    return null;
+  }
+  @NonNls final String name = method.getName();
+  if (!name.startsWith("set")) {
+    return null;
+  }
+  if (method.hasModifierProperty(PsiModifier.SYNCHRONIZED)) {
+    return null;
+  }
+  final PsiCodeBlock body = method.getBody();
+  if (body == null) {
+    return null;
+  }
+  final PsiStatement[] statements = body.getStatements();
+  if (statements.length != 1) {
+    return null;
+  }
+  final PsiStatement statement = statements[0];
+  if (!(statement instanceof PsiExpressionStatement)) {
+    return null;
+  }
+  final PsiExpressionStatement possibleAssignmentStatement = (PsiExpressionStatement)statement;
+  final PsiExpression possibleAssignment = possibleAssignmentStatement.getExpression();
+  if (!(possibleAssignment instanceof PsiAssignmentExpression)) {
+    return null;
+  }
+  final PsiAssignmentExpression assignment = (PsiAssignmentExpression)possibleAssignment;
+  if (!JavaTokenType.EQ.equals(assignment.getOperationTokenType())) {
+    return null;
+  }
+  final PsiExpression lhs = assignment.getLExpression();
+  if (!(lhs instanceof PsiReferenceExpression)) {
+    return null;
+  }
+  final PsiReferenceExpression reference = (PsiReferenceExpression)lhs;
+  final PsiExpression qualifier = reference.getQualifierExpression();
+  if (qualifier instanceof PsiReferenceExpression) {
+    final PsiReferenceExpression referenceExpression = (PsiReferenceExpression)qualifier;
+    final PsiElement target = referenceExpression.resolve();
+    if (!(target instanceof PsiClass)) {
+      return null;
+    }
+  }
+  else if (qualifier != null && !(qualifier instanceof PsiThisExpression) && !(qualifier instanceof PsiSuperExpression)) {
+    return null;
+  }
+  final PsiElement referent = reference.resolve();
+  if (referent == null) {
+    return null;
+  }
+  if (!(referent instanceof PsiField)) {
+    return null;
+  }
+  final PsiField field = (PsiField)referent;
+  final PsiClass fieldContainingClass = field.getContainingClass();
+  final PsiClass methodContainingClass = method.getContainingClass();
+  if (!InheritanceUtil.isInheritorOrSelf(methodContainingClass, fieldContainingClass, true)) {
+    return null;
+  }
+  final PsiExpression rhs = assignment.getRExpression();
+  if (!(rhs instanceof PsiReferenceExpression)) {
+    return null;
+  }
+  final PsiReferenceExpression rReference = (PsiReferenceExpression)rhs;
+  final PsiExpression rQualifier = rReference.getQualifierExpression();
+  if (rQualifier != null) {
+    return null;
+  }
+  final PsiElement rReferent = rReference.resolve();
+  if (rReferent == null) {
+    return null;
+  }
+  if (!(rReferent instanceof PsiParameter)) {
+    return null;
+  }
+  final PsiType fieldType = field.getType();
+  final PsiType parameterType = ((PsiVariable)rReferent).getType();
+  if (fieldType.equalsToText(parameterType.getCanonicalText())) {
+    return field;
+  }
+  else {
+    return null;
+  }
+}
+
+  public static boolean isSimpleSetter(PsiMethod method) {
+  return getFieldOfSetter(method) != null;
+}
+
+  @Nullable
+public static PsiMethod getReversePropertyMethod(PsiMethod propertyMethod) {
+  if (propertyMethod == null) {
+    return null;
+  }
+  final PsiClass aClass = propertyMethod.getContainingClass();
+  if (aClass == null) {
+    return null;
+  }
+  final String methodName = propertyMethod.getName();
+  final String prefix;
+  if (methodName.startsWith("get")) {
+    prefix = "get";
+  }
+  else if (methodName.startsWith("is")) {
+    prefix = "is";
+  }
+  else if (methodName.startsWith("set")) {
+    prefix = "set";
+  }
+  else {
+    return null;
+  }
+  final String name = methodName.substring(prefix.length());
+  final PsiField field;
+  if (prefix.equals("set")) {
+    field = getFieldOfSetter(propertyMethod);
+  }
+  else {
+    field = getFieldOfGetter(propertyMethod);
+  }
+  if (field == null) {
+    return null;
+  }
+  if (prefix.equals("set")) {
+    final PsiMethod result = findPropertyMethod(aClass, "get", name, field);
+    if (result != null) {
+      return result;
+    }
+    return findPropertyMethod(aClass, "is", name, field);
+  }
+  else {
+    return findPropertyMethod(aClass, "set", name, field);
+  }
+}
+
+  private static PsiMethod findPropertyMethod(@NotNull PsiClass aClass, @NotNull String prefix, @NotNull String propertyName, @NotNull PsiField field1) {
+  final PsiMethod[] methods = aClass.findMethodsByName(prefix + propertyName, true);
+  for (PsiMethod method : methods) {
+    final PsiField field2;
+    if (prefix.equals("set")) {
+      field2 = getFieldOfSetter(method);
+    }
+    else {
+      field2 = getFieldOfGetter(method);
+    }
+    if (field1.equals(field2)) {
+      return method;
+    }
+  }
+  return null;
+}
 }
diff --git a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
index b0f7d45..386490d 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/PsiUtil.java
@@ -467,7 +467,7 @@
     if (args.length < parms.length - 1) return ApplicabilityLevel.NOT_APPLICABLE;
 
     final PsiClass containingClass = method.getContainingClass();
-    final boolean isRaw = containingClass != null && isRawSubstitutor(containingClass, substitutorForMethod);
+    final boolean isRaw = containingClass != null && isRawSubstitutor(method, substitutorForMethod) && isRawSubstitutor(containingClass, substitutorForMethod);
     if (!areFirstArgumentsApplicable(args, parms, languageLevel, substitutorForMethod, isRaw)) return ApplicabilityLevel.NOT_APPLICABLE;
     if (args.length == parms.length) {
       if (parms.length == 0) return ApplicabilityLevel.FIXED_ARITY;
@@ -839,21 +839,29 @@
 
   @NotNull
   public static LanguageLevel getLanguageLevel(@NotNull PsiElement element) {
-    if (element instanceof PsiDirectory) return JavaDirectoryService.getInstance().getLanguageLevel((PsiDirectory)element);
-    final PsiFile file = element.getContainingFile();
-    if (file == null) {
-      LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(element.getProject());
-      return instance == null ? LanguageLevel.HIGHEST : instance.getLanguageLevel();
+    if (element instanceof PsiDirectory) {
+      return JavaDirectoryService.getInstance().getLanguageLevel((PsiDirectory)element);
     }
 
-    if (!(file instanceof PsiJavaFile)) {
-      final PsiElement context = file.getContext();
-      if (context != null) return getLanguageLevel(context);
-      LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(file.getProject());
-      return instance == null ? LanguageLevel.HIGHEST : instance.getLanguageLevel();
+    PsiFile file = element.getContainingFile();
+    if (file instanceof PsiJavaFile) {
+      return ((PsiJavaFile)file).getLanguageLevel();
     }
 
-    return ((PsiJavaFile)file).getLanguageLevel();
+    if (file != null) {
+      PsiElement context = file.getContext();
+      if (context != null) {
+        return getLanguageLevel(context);
+      }
+    }
+
+    return getLanguageLevel(element.getProject());
+  }
+
+  @NotNull
+  public static LanguageLevel getLanguageLevel(@NotNull Project project) {
+    LanguageLevelProjectExtension instance = LanguageLevelProjectExtension.getInstance(project);
+    return instance != null ? instance.getLanguageLevel() : LanguageLevel.HIGHEST;
   }
 
   public static boolean isInstantiatable(@NotNull PsiClass clazz) {
diff --git a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
index df1be58..7ad51b2 100644
--- a/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
+++ b/java/java-psi-api/src/com/intellij/psi/util/TypesDistinctProver.java
@@ -146,7 +146,7 @@
         if (superBoundClass instanceof PsiTypeParameter) return false;
         return !InheritanceUtil.isInheritorOrSelf(superBoundClass, extendsBoundClass, true);
       }
-      return true;
+      return provablyDistinct(extendsBound, superBound);
     }
 
     if (!type1.isBounded() || !type2.isBounded()) {
diff --git a/java/openapi/src/com/intellij/util/VisibilityUtil.java b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
similarity index 92%
rename from java/openapi/src/com/intellij/util/VisibilityUtil.java
rename to java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
index ed44304..373e5be 100644
--- a/java/openapi/src/com/intellij/util/VisibilityUtil.java
+++ b/java/java-psi-api/src/com/intellij/util/VisibilityUtil.java
@@ -19,7 +19,7 @@
  * User: dsl
  * Date: 07.06.2002
  * Time: 18:48:01
- * To change template for new class use 
+ * To change template for new class use
  * Code Style | Class Templates options (Tools | IDE Options).
  */
 package com.intellij.util;
@@ -28,7 +28,6 @@
 import com.intellij.psi.util.InheritanceUtil;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.usageView.UsageInfo;
 import org.jetbrains.annotations.Nls;
 import org.jetbrains.annotations.NonNls;
 
@@ -46,7 +45,7 @@
   }
 
   public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
-    return ArrayUtil.find(visibilityModifiers, v2) - ArrayUtil.find(visibilityModifiers, v1);
+    return ArrayUtilRt.find(visibilityModifiers, v2) - ArrayUtilRt.find(visibilityModifiers, v1);
   }
 
   @PsiModifier.ModifierConstant
@@ -123,11 +122,10 @@
     return PsiBundle.visibilityPresentation(modifier);
   }
 
-  public static void fixVisibility(UsageInfo[] usageInfos, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
+  public static void fixVisibility(PsiElement[] elements, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
     if (newVisibility == null) return;
     if (ESCALATE_VISIBILITY.equals(newVisibility)) {
-      for (UsageInfo info : usageInfos) {
-        final PsiElement element = info.getElement();
+      for (PsiElement element : elements) {
         if (element != null) {
           escalateVisibility(member, element);
         }
diff --git a/java/java-psi-impl/java-psi-impl.iml b/java/java-psi-impl/java-psi-impl.iml
index 8fa9e62..a53ad4d 100644
--- a/java/java-psi-impl/java-psi-impl.iml
+++ b/java/java-psi-impl/java-psi-impl.iml
@@ -11,8 +11,7 @@
     <orderEntry type="module" module-name="core-impl" exported="" />
     <orderEntry type="module" module-name="resources-en" />
     <orderEntry type="library" name="asm4" level="project" />
-    <orderEntry type="module" module-name="openapi" />
-    <orderEntry type="module" module-name="external-system-api" />
+    <orderEntry type="module" module-name="indexing-api" />
   </component>
 </module>
 
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
index 4b3be84..1045dcd 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/BaseExternalAnnotationsManager.java
@@ -18,8 +18,10 @@
 import com.intellij.lang.PsiBuilder;
 import com.intellij.lang.java.parser.JavaParser;
 import com.intellij.lang.java.parser.JavaParserUtil;
+import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.diagnostic.Logger;
 import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.project.Project;
 import com.intellij.openapi.util.Comparing;
 import com.intellij.openapi.util.Condition;
 import com.intellij.openapi.util.JDOMUtil;
@@ -43,6 +45,7 @@
 import org.jetbrains.annotations.Nullable;
 
 import java.io.IOException;
+import java.io.StringWriter;
 import java.util.*;
 import java.util.concurrent.ConcurrentMap;
 
@@ -184,84 +187,104 @@
   private final ConcurrentMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>> annotationFileToDataAndModStamp = new ConcurrentSoftHashMap<PsiFile, Pair<MostlySingularMultiMap<String, AnnotationData>, Long>>();
 
   @NotNull
-  private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull PsiFile file) {
+  private MostlySingularMultiMap<String, AnnotationData> getDataFromFile(@NotNull final PsiFile file) {
     Pair<MostlySingularMultiMap<String, AnnotationData>, Long> cached = annotationFileToDataAndModStamp.get(file);
-    if (cached != null && cached.getSecond() == file.getModificationStamp()) {
+    final long fileModificationStamp = file.getModificationStamp();
+    if (cached != null && cached.getSecond() == fileModificationStamp) {
       return cached.getFirst();
     }
     MostlySingularMultiMap<String, AnnotationData> data = new MostlySingularMultiMap<String, AnnotationData>();
     try {
       Document document = JDOMUtil.loadDocument(escapeAttributes(file.getText()));
       Element rootElement = document.getRootElement();
-      if (rootElement != null) {
-        boolean sorted = true;
-        boolean modified = false;
-        String prevItemName = null;
         //noinspection unchecked
-        for (Element element : (List<Element>) rootElement.getChildren("item")) {
-          String externalName = element.getAttributeValue("name");
-          if (externalName == null) {
-            element.detach();
-            modified = true;
-            continue;
-          }
-          if (prevItemName != null && prevItemName.compareTo(externalName) > 0) {
-            sorted = false;
-          }
-          prevItemName = externalName;
-
-          //noinspection unchecked
-          for (Element annotationElement : (List<Element>) element.getChildren("annotation")) {
-            String annotationFQN = annotationElement.getAttributeValue("name");
-            if (StringUtil.isEmpty(annotationFQN)) continue;
-            annotationFQN = intern(annotationFQN);
-            //noinspection unchecked
-            List<Element> children = (List<Element>)annotationElement.getChildren();
-            StringBuilder buf = new StringBuilder(children.size() * "name=value,".length()); // just guess
-            for (Element annotationParameter : children) {
-              if (buf.length() != 0) {
-                buf.append(",");
-              }
-              String nameValue = annotationParameter.getAttributeValue("name");
-              if (nameValue != null) {
-                buf.append(nameValue);
-                buf.append("=");
-              }
-              buf.append(annotationParameter.getAttributeValue("val"));
-            }
-            String annotationParameters = buf.length() == 0 ? "" : intern(buf.toString());
-            for (AnnotationData existingData : data.get(externalName)) {
-              if (existingData.annotationClassFqName.equals(annotationFQN)) {
-                LOG.error("Duplicate annotation '" + annotationFQN+"' for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl());
-              }
-            }
-            AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, annotationParameters, file.getVirtualFile()));
-
-            data.add(externalName, annData);
-          }
-        }
-        if (!sorted) {
+      List<Element> itemElements = rootElement == null ? Collections.<Element>emptyList() : (List<Element>)rootElement.getChildren("item");
+      boolean sorted = true;
+      boolean modified = false;
+      String prevItemName = null;
+      for (Element element : itemElements) {
+        String externalName = element.getAttributeValue("name");
+        if (externalName == null) {
+          element.detach();
           modified = true;
-          List<Element> items = new ArrayList<Element>(rootElement.getChildren("item"));
-          rootElement.removeChildren("item");
-          Collections.sort(items, new Comparator<Element>() {
-            @Override
-            public int compare(Element item1, Element item2) {
-              String externalName1 = item1.getAttributeValue("name");
-              String externalName2 = item2.getAttributeValue("name");
-              return externalName1.compareTo(externalName2);
+          continue;
+        }
+        if (prevItemName != null && prevItemName.compareTo(externalName) > 0) {
+          sorted = false;
+        }
+        prevItemName = externalName;
+
+        //noinspection unchecked
+        for (Element annotationElement : (List<Element>) element.getChildren("annotation")) {
+          String annotationFQN = annotationElement.getAttributeValue("name");
+          if (StringUtil.isEmpty(annotationFQN)) continue;
+          annotationFQN = intern(annotationFQN);
+          //noinspection unchecked
+          List<Element> children = (List<Element>)annotationElement.getChildren();
+          StringBuilder buf = new StringBuilder(children.size() * "name=value,".length()); // just guess
+          for (Element annotationParameter : children) {
+            if (buf.length() != 0) {
+              buf.append(",");
             }
-          });
-          for (Element item : items) {
-            rootElement.addContent(item);
+            String nameValue = annotationParameter.getAttributeValue("name");
+            if (nameValue != null) {
+              buf.append(nameValue);
+              buf.append("=");
+            }
+            buf.append(annotationParameter.getAttributeValue("val"));
           }
+          String annotationParameters = buf.length() == 0 ? "" : intern(buf.toString());
+          for (AnnotationData existingData : data.get(externalName)) {
+            if (existingData.annotationClassFqName.equals(annotationFQN)) {
+              duplicateError(file, externalName, "Duplicate annotation '" + annotationFQN + "' ");
+            }
+          }
+          AnnotationData annData = internAnnotationData(new AnnotationData(annotationFQN, annotationParameters, file.getVirtualFile()));
+
+          data.add(externalName, annData);
         }
-        VirtualFile virtualFile = file.getVirtualFile();
-        if (modified && virtualFile.isInLocalFileSystem() && virtualFile.isWritable()) {
-          String lineSeparator = FileDocumentManager.getInstance().getLineSeparator(virtualFile, file.getProject());
-          JDOMUtil.writeDocument(document, virtualFile.getPath(), lineSeparator);
+      }
+      if (!sorted) {
+        modified = true;
+        List<Element> items = new ArrayList<Element>(rootElement.getChildren("item"));
+        rootElement.removeChildren("item");
+        Collections.sort(items, new Comparator<Element>() {
+          @Override
+          public int compare(Element item1, Element item2) {
+            String externalName1 = item1.getAttributeValue("name");
+            String externalName2 = item2.getAttributeValue("name");
+            return externalName1.compareTo(externalName2);
+          }
+        });
+        for (Element item : items) {
+          rootElement.addContent(item);
         }
       }
+      final VirtualFile virtualFile = file.getVirtualFile();
+      if (modified && virtualFile.isInLocalFileSystem() && virtualFile.isWritable()) {
+        final Project project = file.getProject();
+        final FileDocumentManager fileDocumentManager = FileDocumentManager.getInstance();
+        final StringWriter string = new StringWriter(file.getTextLength());
+        JDOMUtil.writeDocument(document, string, "\n");
+        ApplicationManager.getApplication().invokeLater(new Runnable() {
+          @Override
+          public void run() {
+            if (file.getModificationStamp() == fileModificationStamp && !fileDocumentManager.isFileModified(virtualFile)) {
+              // modify .xml in write action to avoid conflicts and torn reads
+              ApplicationManager.getApplication().runWriteAction(new Runnable() {
+                @Override
+                public void run() {
+                  com.intellij.openapi.editor.Document editorDoc = PsiDocumentManager.getInstance(project).getDocument(file);
+                  if (editorDoc != null) {
+                    editorDoc.setText(string.toString());
+                    fileDocumentManager.saveDocument(editorDoc);
+                  }
+                }
+              });
+            }
+          }
+        }, project.getDisposed());
+      }
     }
     catch (IOException e) {
       LOG.error(e);
@@ -279,6 +302,10 @@
     return data;
   }
 
+  protected void duplicateError(@NotNull PsiFile file, @NotNull String externalName, @NotNull String text) {
+    LOG.error(text + "; for signature: '" + externalName + "' in the file " + file.getVirtualFile().getPresentableUrl());
+  }
+
   @NotNull
   private String intern(@NotNull String annotationFQN) {
     synchronized (charTable) {
@@ -315,7 +342,7 @@
     return result;
   }
 
-  private static void addAnnotations(@NotNull List<AnnotationData> result,
+  private void addAnnotations(@NotNull List<AnnotationData> result,
                                      @NotNull String externalName,
                                      @NotNull PsiFile file,
                                      @NotNull MostlySingularMultiMap<String, AnnotationData> fileData) {
@@ -324,7 +351,7 @@
       if (result.contains(ad)) {
         // there can be compatible annotations in different files
         if (Comparing.equal(ad.virtualFile, file.getVirtualFile())) {
-          LOG.error("Duplicate signature: '" + externalName + "'; in  " + file.getVirtualFile());
+          duplicateError(file, externalName, "Duplicate signature");
         }
       }
       else {
diff --git a/java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java b/java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
similarity index 96%
rename from java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
index de3871d..22769dd 100644
--- a/java/java-impl/src/com/intellij/codeInsight/ConditionChecker.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/ConditionChecker.java
@@ -56,7 +56,7 @@
  *         Creation Date: 8/14/12
  */
 public class ConditionChecker implements Serializable {
-  private final @NotNull Type myConditionCheckType;
+  @NotNull private final Type myConditionCheckType;
 
   public enum Type {
     IS_NULL_METHOD("IsNull Method"),
@@ -77,9 +77,9 @@
     }
   }
 
-  private final @NotNull String myClassName;
-  private final @NotNull String myMethodName;
-  private final @NotNull List<String> myParameterClassList;
+  @NotNull private final String myClassName;
+  @NotNull private final String myMethodName;
+  @NotNull private final List<String> myParameterClassList;
   private final int myCheckedParameterIndex;
   private final String myFullName;
 
@@ -217,8 +217,8 @@
 
   static class FromConfigBuilder extends Builder {
     private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromConfigBuilder");
-    private final @NotNull String serializedRepresentation;
-    private final @NotNull Type type;
+    @NotNull private final String serializedRepresentation;
+    @NotNull private final Type type;
 
     FromConfigBuilder(@NotNull String serializedRepresentation, @NotNull Type type) {
       this.serializedRepresentation = serializedRepresentation;
@@ -265,7 +265,7 @@
           throw new IllegalArgumentException(
             "Name should contain 1+ parameter (between opening and closing parenthesis).  " + serializedRepresentation);
         }
-        else if (allParametersSubString.contains("*") && allParametersSubString.indexOf("*") == allParametersSubString.lastIndexOf("*")) {
+        if (allParametersSubString.contains("*") && allParametersSubString.indexOf("*") == allParametersSubString.lastIndexOf("*")) {
           throw new IllegalArgumentException("Selected Parameter should be surrounded by asterisks.  " + serializedRepresentation);
         }
 
@@ -303,9 +303,9 @@
 
   public static class FromPsiBuilder extends Builder {
     private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.ConditionCheck.FromPsiBuilder");
-    private final @NotNull PsiMethod psiMethod;
-    private final @NotNull PsiParameter psiParameter;
-    private final @NotNull Type type;
+    @NotNull private final PsiMethod psiMethod;
+    @NotNull private final PsiParameter psiParameter;
+    @NotNull private final Type type;
 
     public FromPsiBuilder(@NotNull PsiMethod psiMethod, @NotNull PsiParameter psiParameter, @NotNull Type type) {
       this.psiMethod = psiMethod;
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java
new file mode 100644
index 0000000..7308203
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/JavaPsiEquivalenceUtil.java
@@ -0,0 +1,47 @@
+/*
+ * 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.codeInsight;
+
+import com.intellij.psi.*;
+import com.intellij.psi.impl.source.PsiDiamondTypeElementImpl;
+
+import java.util.Comparator;
+
+public class JavaPsiEquivalenceUtil {
+  public static boolean areExpressionsEquivalent(PsiExpression expr1, PsiExpression expr2) {
+    return PsiEquivalenceUtil.areElementsEquivalent(expr1, expr2, new Comparator<PsiElement>() {
+      @Override
+      public int compare(PsiElement o1, PsiElement o2) {
+        if (o1 instanceof PsiParameter && o2 instanceof PsiParameter && ((PsiParameter)o1).getDeclarationScope() instanceof PsiMethod) {
+          return ((PsiParameter)o1).getName().compareTo(((PsiParameter)o2).getName());
+        }
+        return 1;
+      }
+    }, new Comparator<PsiElement>() {
+        @Override
+        public int compare(PsiElement o1, PsiElement o2) {
+          if (!o1.textMatches(o2)) return 1;
+
+          if (o1 instanceof PsiDiamondTypeElementImpl && o2 instanceof PsiDiamondTypeElementImpl) {
+            final PsiDiamondType.DiamondInferenceResult thisInferenceResult = new PsiDiamondTypeImpl(o1.getManager(), (PsiTypeElement)o1).resolveInferredTypes();
+            final PsiDiamondType.DiamondInferenceResult otherInferenceResult = new PsiDiamondTypeImpl(o2.getManager(), (PsiTypeElement)o2).resolveInferredTypes();
+            return thisInferenceResult.equals(otherInferenceResult) ? 0 : 1;
+          }
+          return 0;
+        }
+      }, null, false);
+  }
+}
diff --git a/java/java-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java b/java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/TestFrameworksImpl.java
diff --git a/java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java b/java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
similarity index 100%
rename from java/java-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
rename to java/java-psi-impl/src/com/intellij/codeInsight/daemon/impl/analysis/HighlightMessageUtil.java
diff --git a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
index b34be36..608d539 100644
--- a/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
+++ b/java/java-psi-impl/src/com/intellij/codeInsight/folding/impl/JavaFoldingBuilderBase.java
@@ -625,11 +625,12 @@
   }
 
   private void addCodeBlockFolds(PsiElement scope, final List<FoldingDescriptor> foldElements,
-                                 final @NotNull Set<PsiElement> processedComments, final Document document, final boolean quick)
-  {
+                                 final @NotNull Set<PsiElement> processedComments, final Document document, final boolean quick) {
+    final boolean dumb = DumbService.isDumb(scope.getProject());
     scope.accept(new JavaRecursiveElementWalkingVisitor() {
-      @Override public void visitClass(PsiClass aClass) {
-        if (!addClosureFolding(aClass, document, foldElements, processedComments, quick)) {
+      @Override
+      public void visitClass(PsiClass aClass) {
+        if (dumb || !addClosureFolding(aClass, document, foldElements, processedComments, quick)) {
           addToFold(foldElements, aClass, document, true);
           addElementsToFold(foldElements, aClass, document, false, quick);
         }
@@ -637,14 +638,18 @@
 
       @Override
       public void visitMethodCallExpression(PsiMethodCallExpression expression) {
-        addMethodGenericParametersFolding(expression, foldElements, document, quick);
+        if (!dumb) {
+          addMethodGenericParametersFolding(expression, foldElements, document, quick);
+        }
 
         super.visitMethodCallExpression(expression);
       }
 
       @Override
       public void visitNewExpression(PsiNewExpression expression) {
-        addGenericParametersFolding(expression, foldElements, document, quick);
+        if (!dumb) {
+          addGenericParametersFolding(expression, foldElements, document, quick);
+        }
 
         super.visitNewExpression(expression);
       }
@@ -659,7 +664,7 @@
 
   private boolean addClosureFolding(final PsiClass aClass, final Document document, final List<FoldingDescriptor> foldElements,
                                     @NotNull Set<PsiElement> processedComments, final boolean quick) {
-    if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas() || DumbService.isDumb(aClass.getProject())) {
+    if (!JavaCodeFoldingSettings.getInstance().isCollapseLambdas()) {
       return false;
     }
 
diff --git a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
index 1177603..c315644 100644
--- a/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/ControlFlowUtil.java
@@ -405,6 +405,14 @@
       if (parent instanceof PsiClass) {
         final PsiClass clss = (PsiClass)parent;
         if (PsiTreeUtil.isAncestor(targetClassMember, clss, false)) return false;
+        PsiClass containingClass = PsiTreeUtil.getParentOfType(ref, PsiClass.class);
+        while (containingClass != null) {
+          if (containingClass.isInheritor(clss, true) &&
+              PsiTreeUtil.isAncestor(targetClassMember, containingClass, false)) {
+            return false;
+          }
+          containingClass = containingClass.getContainingClass();
+        }
       }
     }
 
diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
similarity index 99%
rename from java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
rename to java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
index 658164e..cfe3620 100644
--- a/java/java-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/controlFlow/DefUseUtil.java
@@ -20,7 +20,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.psi.util.PsiUtilBase;
+import com.intellij.psi.util.PsiUtilCore;
 import com.intellij.util.containers.IntArrayList;
 import com.intellij.util.containers.Queue;
 import gnu.trove.THashSet;
@@ -435,7 +435,7 @@
           }
         }
         new Inner ().traverse (elem);
-        return PsiUtilBase.toPsiElementArray(res);
+        return PsiUtilCore.toPsiElementArray(res);
       }
       return PsiElement.EMPTY_ARRAY;
     }
diff --git a/java/java-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java b/java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
similarity index 100%
rename from java/java-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
rename to java/java-psi-impl/src/com/intellij/psi/controlFlow/LocalsControlFlowPolicy.java
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
index 517bd7e..11ee141 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/ElementPresentationUtil.java
@@ -140,9 +140,9 @@
       if (TestFrameworks.getInstance().isTestClass(aClass)) {
         return CLASS_KIND_JUNIT_TEST;
       }
-    }
-    if (PsiClassUtil.isRunnableClass(aClass, false) && PsiMethodUtil.findMainMethod(aClass) != null) {
-      return CLASS_KIND_RUNNABLE;
+      if (PsiClassUtil.isRunnableClass(aClass, false) && PsiMethodUtil.findMainMethod(aClass) != null) {
+        return CLASS_KIND_RUNNABLE;
+      }
     }
     return CLASS_KIND_CLASS;
   }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
index c16225b..f80a099 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/JavaPsiFacadeImpl.java
@@ -36,6 +36,7 @@
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.PsiModificationTracker;
 import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.reference.SoftReference;
 import com.intellij.util.ConcurrencyUtil;
 import com.intellij.util.Processor;
 import com.intellij.util.SmartList;
@@ -58,11 +59,10 @@
   private PsiElementFinder[] myElementFinders; //benign data race
   private final PsiNameHelper myNameHelper;
   private final PsiConstantEvaluationHelper myConstantEvaluationHelper;
-  private final ConcurrentMap<String, PsiPackage> myPackageCache = new ConcurrentHashMap<String, PsiPackage>();
+  private volatile SoftReference<ConcurrentMap<String, PsiPackage>> myPackageCache;
   private final Project myProject;
   private final JavaFileManager myFileManager;
 
-
   public JavaPsiFacadeImpl(Project project,
                            PsiManagerImpl psiManager,
                            JavaFileManager javaFileManager,
@@ -83,7 +83,7 @@
           final long now = modificationTracker.getJavaStructureModificationCount();
           if (lastTimeSeen != now) {
             lastTimeSeen = now;
-            myPackageCache.clear();
+            myPackageCache = null;
           }
         }
       });
@@ -177,7 +177,13 @@
 
   @Override
   public PsiPackage findPackage(@NotNull String qualifiedName) {
-    PsiPackage aPackage = myPackageCache.get(qualifiedName);
+    SoftReference<ConcurrentMap<String, PsiPackage>> ref = myPackageCache;
+    ConcurrentMap<String, PsiPackage> cache = ref == null ? null : ref.get();
+    if (cache == null) {
+      myPackageCache = new SoftReference<ConcurrentMap<String, PsiPackage>>(cache = new ConcurrentHashMap<String, PsiPackage>());
+    }
+    
+    PsiPackage aPackage = cache.get(qualifiedName);
     if (aPackage != null) {
       return aPackage;
     }
@@ -185,7 +191,7 @@
     for (PsiElementFinder finder : filteredFinders()) {
       aPackage = finder.findPackage(qualifiedName);
       if (aPackage != null) {
-        return ConcurrencyUtil.cacheOrGet(myPackageCache, qualifiedName, aPackage);
+        return ConcurrencyUtil.cacheOrGet(cache, qualifiedName, aPackage);
       }
     }
 
diff --git a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
similarity index 98%
rename from java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
rename to java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
index 7d11223..8539b55 100644
--- a/java/java-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiDiamondTypeUtil.java
@@ -39,7 +39,7 @@
 
   public static boolean canCollapseToDiamond(final PsiNewExpression expression,
                                              final PsiNewExpression context,
-                                             final @Nullable PsiType expectedType) {
+                                             @Nullable final PsiType expectedType) {
     return canCollapseToDiamond(expression, context, expectedType, false);
   }
 
@@ -50,7 +50,7 @@
 
   private static boolean canCollapseToDiamond(final PsiNewExpression expression,
                                              final PsiNewExpression context,
-                                             final @Nullable PsiType expectedType,
+                                             @Nullable final PsiType expectedType,
                                              boolean skipDiamonds) {
     if (PsiUtil.getLanguageLevel(context).isAtLeast(LanguageLevel.JDK_1_7)) {
       final PsiJavaCodeReferenceElement classReference = expression.getClassOrAnonymousClassReference();
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
index 62df787..90f63f6 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/PsiSubstitutorImpl.java
@@ -432,7 +432,7 @@
   public PsiSubstitutor put(@NotNull PsiTypeParameter typeParameter, PsiType mapping) {
     PsiSubstitutorImpl ret = clone();
     if (mapping != null && !mapping.isValid()) {
-      LOG.error("Invalid type in substitutor: " + mapping);
+      LOG.error("Invalid type in substitutor: " + mapping + "; " + mapping.getClass());
     }
     ret.mySubstitutionMap.put(typeParameter, mapping);
     return ret;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
index d9d3b06..2adc6f1 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/cache/TypeInfo.java
@@ -65,8 +65,10 @@
       "null",
       "short",
       "void",
-      CommonClassNames.JAVA_LANG_OBJECT_SHORT, CommonClassNames.JAVA_LANG_OBJECT,
-      CommonClassNames.JAVA_LANG_STRING_SHORT, CommonClassNames.JAVA_LANG_STRING
+      CommonClassNames.JAVA_LANG_OBJECT_SHORT,
+      CommonClassNames.JAVA_LANG_OBJECT,
+      CommonClassNames.JAVA_LANG_STRING_SHORT,
+      CommonClassNames.JAVA_LANG_STRING
     };
 
     ourFrequentTypeIndex = new TObjectIntHashMap<String>();
@@ -273,11 +275,11 @@
       buf.append("...");
     }
 
-    return buf.toString();
+    return internFrequentType(buf.toString());
   }
 
   @NotNull
-  private static String internFrequentType(@NotNull String type) {
+  public static String internFrequentType(@NotNull String type) {
     int frequentIndex = ourFrequentTypeIndex.get(type);
     return frequentIndex == 0 ? type : ourIndexFrequentType[frequentIndex];
   }
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 118af69..466a53c 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-2012 JetBrains s.r.o.
+ * 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.
@@ -23,19 +23,25 @@
 import com.intellij.psi.stubs.PsiFileStub;
 import com.intellij.psi.stubs.StubElement;
 import com.intellij.util.cls.ClsFormatException;
+import com.intellij.util.indexing.FileContent;
 
 /**
  * @author max
  */
 public class ClassFileStubBuilder implements BinaryFileStubBuilder {
+  public static final int STUB_VERSION = JavaFileElementType.STUB_VERSION + 6;
+
   @Override
   public boolean acceptsFile(final VirtualFile file) {
     return true;
   }
 
   @Override
-  public StubElement buildStubTree(final VirtualFile file, final byte[] content, final Project project) {
+  public StubElement buildStubTree(FileContent fileContent) {
     try {
+      VirtualFile file = fileContent.getFile();
+      Project project = fileContent.getProject();
+      byte[] content = fileContent.getContent();
       final ClsStubBuilderFactory[] factories = Extensions.getExtensions(ClsStubBuilderFactory.EP_NAME);
       for (ClsStubBuilderFactory factory : factories) {
         if (!factory.isInnerClass(file) && factory.canBeProcessed(file, content)) {
@@ -52,6 +58,6 @@
 
   @Override
   public int getStubVersion() {
-    return JavaFileElementType.STUB_VERSION + 6;
+    return STUB_VERSION;
   }
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
index c0d9ca7..3cdc7df 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsAnnotationImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -15,6 +15,8 @@
  */
 package com.intellij.psi.impl.compiled;
 
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.pom.Navigatable;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiImplUtil;
@@ -33,16 +35,32 @@
  * @author ven
  */
 public class ClsAnnotationImpl extends ClsRepositoryPsiElement<PsiAnnotationStub> implements PsiAnnotation, Navigatable {
-  private ClsJavaCodeReferenceElementImpl myReferenceElement;
-  private ClsAnnotationParameterListImpl myParameterList;
+  private final NotNullLazyValue<ClsJavaCodeReferenceElementImpl> myReferenceElement;
+  private final NotNullLazyValue<ClsAnnotationParameterListImpl> myParameterList;
 
   public ClsAnnotationImpl(final PsiAnnotationStub stub) {
     super(stub);
+    myReferenceElement = new AtomicNotNullLazyValue<ClsJavaCodeReferenceElementImpl>() {
+      @NotNull
+      @Override
+      protected ClsJavaCodeReferenceElementImpl compute() {
+        String text = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiJavaCodeReferenceElement.class).getText();
+        return new ClsJavaCodeReferenceElementImpl(ClsAnnotationImpl.this, text);
+      }
+    };
+    myParameterList = new AtomicNotNullLazyValue<ClsAnnotationParameterListImpl>() {
+      @NotNull
+      @Override
+      protected ClsAnnotationParameterListImpl compute() {
+        PsiAnnotationParameterList paramList = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiAnnotationParameterList.class);
+        return new ClsAnnotationParameterListImpl(ClsAnnotationImpl.this, paramList.getAttributes());
+      }
+    };
   }
 
   @Override
   public void appendMirrorText(int indentLevel, @NotNull StringBuilder buffer) {
-    buffer.append("@").append(getReferenceElement().getCanonicalText());
+    buffer.append("@").append(myReferenceElement.getValue().getCanonicalText());
     appendText(getParameterList(), indentLevel, buffer);
   }
 
@@ -57,7 +75,7 @@
   @Override
   @NotNull
   public PsiElement[] getChildren() {
-    return new PsiElement[]{getReferenceElement(), getParameterList()};
+    return new PsiElement[]{myReferenceElement.getValue(), getParameterList()};
   }
 
   @Override
@@ -73,25 +91,18 @@
   @Override
   @NotNull
   public PsiAnnotationParameterList getParameterList() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myParameterList == null) {
-        PsiAnnotationParameterList paramList = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiAnnotationParameterList.class);
-        myParameterList = new ClsAnnotationParameterListImpl(this, paramList.getAttributes());
-      }
-      return myParameterList;
-    }
+    return myParameterList.getValue();
   }
 
   @Override
   @Nullable
   public String getQualifiedName() {
-    if (getReferenceElement() == null) return null;
-    return getReferenceElement().getCanonicalText();
+    return myReferenceElement.getValue().getCanonicalText();
   }
 
   @Override
   public PsiJavaCodeReferenceElement getNameReferenceElement() {
-    return getReferenceElement();
+    return myReferenceElement.getValue();
   }
 
   @Override
@@ -122,17 +133,6 @@
     return MetaRegistry.getMetaBase(this);
   }
 
-  private ClsJavaCodeReferenceElementImpl getReferenceElement() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myReferenceElement == null) {
-        String text = PsiTreeUtil.getRequiredChildOfType(getStub().getPsiElement(), PsiJavaCodeReferenceElement.class).getText();
-        myReferenceElement = new ClsJavaCodeReferenceElementImpl(this, text);
-      }
-
-      return myReferenceElement;
-    }
-  }
-
   @Override
   public PsiAnnotationOwner getOwner() {
     return (PsiAnnotationOwner)getParent();//todo
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
index 060ed38..5f55a5b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsElementImpl.java
@@ -42,7 +42,6 @@
 public abstract class ClsElementImpl extends PsiElementBase implements PsiCompiledElement {
   public static final Key<PsiCompiledElement> COMPILED_ELEMENT = Key.create("COMPILED_ELEMENT");
 
-  protected static final Object LAZY_BUILT_LOCK = new String("lazy cls tree initialization lock");
   protected static final String CAN_NOT_MODIFY_MESSAGE = JavaCoreBundle.message("psi.error.attempt.to.edit.class.file");
 
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsElementImpl");
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
index 55d35bd..0a3091f 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFieldImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -18,7 +18,7 @@
 import com.intellij.navigation.ItemPresentation;
 import com.intellij.navigation.ItemPresentationProviders;
 import com.intellij.openapi.extensions.Extensions;
-import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.*;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.*;
 import com.intellij.psi.impl.cache.TypeInfo;
@@ -33,17 +33,36 @@
 import gnu.trove.THashSet;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 import javax.swing.*;
 import java.util.Set;
 
 public class ClsFieldImpl extends ClsMemberImpl<PsiFieldStub> implements PsiField, PsiVariableEx, ClsModifierListOwner {
-  private PsiTypeElement myType = null;
-  private PsiExpression myInitializer = null;
-  private boolean myInitializerInitialized = false;
+  private final NotNullLazyValue<PsiTypeElement> myType;
+  private final NullableLazyValue<PsiExpression> myInitializer;
 
   public ClsFieldImpl(@NotNull PsiFieldStub stub) {
     super(stub);
+    myType = new AtomicNotNullLazyValue<PsiTypeElement>() {
+      @NotNull
+      @Override
+      protected PsiTypeElement compute() {
+        PsiFieldStub stub = getStub();
+        String typeText = TypeInfo.createTypeText(stub.getType(false));
+        assert typeText != null : stub;
+        return new ClsTypeElementImpl(ClsFieldImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+      }
+    };
+    myInitializer = new VolatileNullableLazyValue<PsiExpression>() {
+      @Nullable
+      @Override
+      protected PsiExpression compute() {
+        String initializerText = getStub().getInitializerText();
+        return initializerText != null && !Comparing.equal(PsiFieldStub.INITIALIZER_TOO_LONG, initializerText) ?
+               ClsParsingUtil.createExpressionFromText(initializerText, getManager(), ClsFieldImpl.this) : null;
+      }
+    };
   }
 
   @Override
@@ -66,15 +85,7 @@
   @Override
   @NotNull
   public PsiTypeElement getTypeElement() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myType == null) {
-        PsiFieldStub stub = getStub();
-        String typeText = TypeInfo.createTypeText(stub.getType(false));
-        assert typeText != null : stub;
-        myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
-      }
-      return myType;
-    }
+    return myType.getValue();
   }
 
   @Override
@@ -89,17 +100,7 @@
 
   @Override
   public PsiExpression getInitializer() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (!myInitializerInitialized) {
-        myInitializerInitialized = true;
-        String initializerText = getStub().getInitializerText();
-        if (initializerText != null && !Comparing.equal(PsiFieldStub.INITIALIZER_TOO_LONG, initializerText)) {
-          myInitializer = ClsParsingUtil.createExpressionFromText(initializerText, getManager(), this);
-        }
-      }
-
-      return myInitializer;
-    }
+    return myInitializer.getValue();
   }
 
   @Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
index 1920043..0565534 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsFileImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -31,7 +31,10 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.*;
-import com.intellij.psi.impl.*;
+import com.intellij.psi.impl.JavaPsiImplementationHelper;
+import com.intellij.psi.impl.PsiFileEx;
+import com.intellij.psi.impl.PsiManagerEx;
+import com.intellij.psi.impl.PsiManagerImpl;
 import com.intellij.psi.impl.java.stubs.PsiClassStub;
 import com.intellij.psi.impl.java.stubs.impl.PsiJavaFileStubImpl;
 import com.intellij.psi.impl.source.PsiFileImpl;
@@ -42,22 +45,27 @@
 import com.intellij.psi.impl.source.tree.TreeElement;
 import com.intellij.psi.search.PsiElementProcessor;
 import com.intellij.psi.stubs.*;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.reference.SoftReference;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
 
-import java.lang.ref.SoftReference;
-import java.util.*;
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+import java.util.Set;
 
-public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub> implements PsiJavaFile, PsiFileWithStubSupport, PsiFileEx,
-                                                                                            Queryable, PsiClassOwnerEx, PsiCompiledFile {
+import static com.intellij.reference.SoftReference.dereference;
+
+public class ClsFileImpl extends ClsRepositoryPsiElement<PsiClassHolderFileStub>
+                         implements PsiJavaFile, PsiFileWithStubSupport, PsiFileEx, Queryable, PsiClassOwnerEx, PsiCompiledFile {
   private static final Logger LOG = Logger.getInstance("#com.intellij.psi.impl.compiled.ClsFileImpl");
 
-  /** YOU absolutely MUST NOT hold PsiLock under the MIRROR_LOCK */
-  private static final MirrorLock MIRROR_LOCK = new MirrorLock();
-  private static class MirrorLock {}
+  /** NOTE: you absolutely MUST NOT hold PsiLock under the mirror lock */
+  private final Object myMirrorLock = new Object();
+  private final Object myStubLock = new Object();
 
   private final PsiManagerImpl myManager;
   private final boolean myIsForDecompiling;
@@ -73,7 +81,7 @@
     myManager = manager;
     myIsForDecompiling = forDecompiling;
     myViewProvider = viewProvider;
-    JavaElementType.CLASS.getIndex(); // Initialize java stubs...
+    JavaElementType.CLASS.getIndex();  // initialize Java stubs
   }
 
   public ClsFileImpl(PsiManagerImpl manager, FileViewProvider viewProvider) {
@@ -207,8 +215,7 @@
   @Override
   @NotNull
   public LanguageLevel getLanguageLevel() {
-    final List stubs = getStub().getChildrenStubs();
-    return stubs.size() > 0 ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST;
+    return LanguageLevel.HIGHEST;  // library classes should inherit language level from modules where they are referenced
   }
 
   @Override
@@ -270,43 +277,45 @@
 
   @Override
   public PsiElement getMirror() {
-    String mirrorText = null;
-    VirtualFile file = null;
-    if (myMirrorFileElement == null) {
-      file = getVirtualFile();
-      // avoid decompiling under MIRROR_LOCK as decompiling can need other locks
-      // (e.g. nice parameter names in mirror need resolve and FQN stub index lock) and stub indices (under own lock) need to access stub
-      // tree with MIRROR_LOCK, see IDEA-98468
-      mirrorText = decompile(getManager(), file);
-    }
+    TreeElement mirrorTreeElement = myMirrorFileElement;
+    if (mirrorTreeElement == null) {
+      synchronized (myMirrorLock) {
+        mirrorTreeElement = myMirrorFileElement;
+        if (mirrorTreeElement == null) {
+          VirtualFile file = getVirtualFile();
+          String mirrorText = decompile(getManager(), file);
 
-    synchronized (MIRROR_LOCK) {
-      if (myMirrorFileElement == null) {
-        String ext = JavaFileType.INSTANCE.getDefaultExtension();
-        PsiClass[] classes = getClasses();
-        String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + "." + ext;
-        PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject());
-        PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false);
-        TreeElement mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror);
+          String ext = JavaFileType.INSTANCE.getDefaultExtension();
+          PsiClass[] classes = getClasses();
+          String fileName = (classes.length > 0 ? classes[0].getName() : file.getNameWithoutExtension()) + "." + ext;
+          PsiFileFactory factory = PsiFileFactory.getInstance(getManager().getProject());
+          PsiFile mirror = factory.createFileFromText(fileName, JavaLanguage.INSTANCE, mirrorText, false, false);
+          mirror.putUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY, getSourceLanguageLevel());
+          mirrorTreeElement = SourceTreeToPsiMap.psiToTreeNotNull(mirror);
 
-        //IMPORTANT: do not take lock too early - FileDocumentManager.getInstance().saveToString() can run write action...
-        final NonCancelableSection section = ProgressIndicatorProvider.startNonCancelableSectionIfSupported();
-        try {
-          setMirror(mirrorTreeElement);
-        }
-        catch (InvalidMirrorException e) {
-          // todo[r.sh] use logging API once available (to attach .class file)
-          LOG.error(file.getPath(), e);
-        }
-        finally {
-          section.done();
-        }
+          // IMPORTANT: do not take lock too early - FileDocumentManager.saveToString() can run write action
+          NonCancelableSection section = ProgressIndicatorProvider.startNonCancelableSectionIfSupported();
+          try {
+            setMirror(mirrorTreeElement);
+          }
+          catch (InvalidMirrorException e) {
+            LOG.error(file.getPath(), e);
+          }
+          finally {
+            section.done();
+          }
 
-        myMirrorFileElement = mirrorTreeElement;
+          myMirrorFileElement = mirrorTreeElement;
+        }
       }
-
-      return myMirrorFileElement.getPsi();
     }
+    return mirrorTreeElement.getPsi();
+  }
+
+  @NotNull
+  public LanguageLevel getSourceLanguageLevel() {
+    final List stubs = getStub().getChildrenStubs();
+    return stubs.size() > 0 ? ((PsiClassStub<?>)stubs.get(0)).getLanguageLevel() : LanguageLevel.HIGHEST;
   }
 
   @Override
@@ -398,58 +407,30 @@
     return (PsiClassHolderFileStub)getStubTree().getRoot();
   }
 
-  private final Object lock = new Object();
-
   @Override
   @NotNull
   public StubTree getStubTree() {
     ApplicationManager.getApplication().assertReadAccessAllowed();
 
-    final StubTree derefd = derefStub();
-    if (derefd != null) return derefd;
+    StubTree stubTree = dereference(myStub);
+    if (stubTree != null) return stubTree;
 
-    StubTree stubHolder = (StubTree)StubTreeLoader.getInstance().readOrBuild(getProject(), getVirtualFile(), this);
-    if (stubHolder == null) {
-      // Must be corrupted .class file
-      LOG.info("Class file is corrupted: " + getVirtualFile().getPresentableUrl());
+    synchronized (myStubLock) {
+      stubTree = dereference(myStub);
+      if (stubTree != null) return stubTree;
 
-      StubTree emptyTree = new StubTree(new PsiJavaFileStubImpl("corrupted.classfiles", true));
-      setStubTree(emptyTree);
-      resetMirror();
-      return emptyTree;
+      stubTree = (StubTree)StubTreeLoader.getInstance().readOrBuild(getProject(), getVirtualFile(), this);
+      if (stubTree == null) {
+        LOG.warn("Class file is corrupted: " + getVirtualFile().getPresentableUrl());
+        stubTree = new StubTree(new PsiJavaFileStubImpl("corrupted.classfiles", true));
+      }
+
+      myStub = new SoftReference<StubTree>(stubTree);
+      //noinspection unchecked
+      ((PsiFileStubImpl)stubTree.getRoot()).setPsi(this);
     }
 
-    synchronized (lock) {
-      final StubTree derefdOnLock = derefStub();
-      if (derefdOnLock != null) return derefdOnLock;
-
-      setStubTree(stubHolder);
-    }
-
-    resetMirror();
-    return stubHolder;
-  }
-
-  private void setStubTree(StubTree tree) {
-    synchronized (lock) {
-      myStub = new SoftReference<StubTree>(tree);
-      ((PsiFileStubImpl)tree.getRoot()).setPsi(this);
-    }
-  }
-
-  private void resetMirror() {
-    ClsPackageStatementImpl clsPackageStatement = new ClsPackageStatementImpl(this);
-    synchronized (MIRROR_LOCK) {
-      myMirrorFileElement = null;
-      myPackageStatement = clsPackageStatement;
-    }
-  }
-
-  @Nullable
-  private StubTree derefStub() {
-    synchronized (lock) {
-      return myStub != null ? myStub.get() : null;
-    }
+    return stubTree;
   }
 
   @Override
@@ -464,18 +445,21 @@
 
   @Override
   public void onContentReload() {
-    SoftReference<StubTree> stub = myStub;
-    StubTree stubHolder = stub == null ? null : stub.get();
-    if (stubHolder != null) {
-      ((StubBase<?>)stubHolder.getRoot()).setPsi(null);
-    }
-    myStub = null;
-
     ApplicationManager.getApplication().assertWriteAccessAllowed();
 
-    synchronized (MIRROR_LOCK) {
+    synchronized (myStubLock) {
+      StubTree stubTree = dereference(myStub);
+      myStub = null;
+      if (stubTree != null) {
+        //noinspection unchecked
+        ((PsiFileStubImpl)stubTree.getRoot()).setPsi(null);
+      }
+    }
+
+    ClsPackageStatementImpl packageStatement = new ClsPackageStatementImpl(this);
+    synchronized (myMirrorLock) {
       myMirrorFileElement = null;
-      myPackageStatement = null;
+      myPackageStatement = packageStatement;
     }
   }
 
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
index c69391d..7c2e8e0 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsJavaCodeReferenceElementImpl.java
@@ -20,6 +20,7 @@
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiSubstitutorImpl;
+import com.intellij.psi.impl.cache.TypeInfo;
 import com.intellij.psi.impl.source.resolve.ResolveCache;
 import com.intellij.psi.impl.source.tree.JavaElementType;
 import com.intellij.psi.impl.source.tree.TreeElement;
@@ -45,8 +46,10 @@
   public ClsJavaCodeReferenceElementImpl(PsiElement parent, String canonicalText) {
     myParent = parent;
 
-    myCanonicalText = canonicalText;
-    myQualifiedName = PsiNameHelper.getQualifiedClassName(myCanonicalText, false);
+    String canonical = TypeInfo.internFrequentType(canonicalText);
+    myCanonicalText = canonical;
+    String qName = TypeInfo.internFrequentType(PsiNameHelper.getQualifiedClassName(myCanonicalText, false));
+    myQualifiedName = qName.equals(canonical) ? canonical : qName;
 
     String[] classParameters = PsiNameHelper.getClassParametersText(canonicalText);
     myRefParameterList = classParameters.length == 0 ? null : new ClsReferenceParameterListImpl(this, classParameters);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
index e59d910..c5f072c 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMemberImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -15,6 +15,8 @@
  */
 package com.intellij.psi.impl.compiled;
 
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.psi.PsiDocCommentOwner;
 import com.intellij.psi.PsiElement;
 import com.intellij.psi.PsiIdentifier;
@@ -25,38 +27,37 @@
 import com.intellij.util.IncorrectOperationException;
 import org.jetbrains.annotations.NotNull;
 
-public abstract class ClsMemberImpl<T extends NamedStub>
-  extends ClsRepositoryPsiElement<T>
-  implements PsiDocCommentOwner, PsiNameIdentifierOwner {
-
-  private PsiDocComment myDocComment;
-  private PsiIdentifier myNameIdentifier;
+public abstract class ClsMemberImpl<T extends NamedStub> extends ClsRepositoryPsiElement<T> implements PsiDocCommentOwner, PsiNameIdentifierOwner {
+  private final NotNullLazyValue<PsiDocComment> myDocComment;
+  private final NotNullLazyValue<PsiIdentifier> myNameIdentifier;
 
   protected ClsMemberImpl(T stub) {
     super(stub);
+    myDocComment = !isDeprecated() ? null : new AtomicNotNullLazyValue<PsiDocComment>() {
+      @NotNull
+      @Override
+      protected PsiDocComment compute() {
+        return new ClsDocCommentImpl(ClsMemberImpl.this);
+      }
+    };
+    myNameIdentifier = new AtomicNotNullLazyValue<PsiIdentifier>() {
+      @NotNull
+      @Override
+      protected PsiIdentifier compute() {
+        return new ClsIdentifierImpl(ClsMemberImpl.this, getName());
+      }
+    };
   }
 
   @Override
   public PsiDocComment getDocComment() {
-    if (!isDeprecated()) return null;
-
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myDocComment == null) {
-        myDocComment = new ClsDocCommentImpl(this);
-      }
-      return myDocComment;
-    }
+    return myDocComment != null ? myDocComment.getValue() : null;
   }
 
   @Override
   @NotNull
   public PsiIdentifier getNameIdentifier() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myNameIdentifier == null) {
-        myNameIdentifier = new ClsIdentifierImpl(this, getName());
-      }
-      return myNameIdentifier;
-    }
+    return myNameIdentifier.getValue();
   }
 
   @Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
index deb912d..ac0ccfb 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsMethodImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -18,6 +18,8 @@
 import com.intellij.navigation.ItemPresentation;
 import com.intellij.navigation.ItemPresentationProviders;
 import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.openapi.util.text.StringUtil;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.ElementPresentationUtil;
@@ -44,11 +46,31 @@
 import java.util.List;
 
 public class ClsMethodImpl extends ClsMemberImpl<PsiMethodStub> implements PsiAnnotationMethod {
-  private PsiTypeElement myReturnType = null;
-  private PsiAnnotationMemberValue myDefaultValue = null;
+  private final NotNullLazyValue<PsiTypeElement> myReturnType;
+  private final NotNullLazyValue<PsiAnnotationMemberValue> myDefaultValue;
 
   public ClsMethodImpl(final PsiMethodStub stub) {
     super(stub);
+
+    myReturnType = isConstructor() ? null : new AtomicNotNullLazyValue<PsiTypeElement>() {
+      @NotNull
+      @Override
+      protected PsiTypeElement compute() {
+        PsiMethodStub stub = getStub();
+        String typeText = TypeInfo.createTypeText(stub.getReturnTypeText(false));
+        assert typeText != null : stub;
+        return new ClsTypeElementImpl(ClsMethodImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+      }
+    };
+
+    final String text = getStub().getDefaultValueText();
+    myDefaultValue = StringUtil.isEmptyOrSpaces(text) ? null : new AtomicNotNullLazyValue<PsiAnnotationMemberValue>() {
+      @NotNull
+      @Override
+      protected PsiAnnotationMemberValue compute() {
+        return ClsParsingUtil.createMemberValueFromText(text, getManager(), ClsMethodImpl.this);
+      }
+    };
   }
 
   @Override
@@ -106,17 +128,7 @@
 
   @Override
   public PsiTypeElement getReturnTypeElement() {
-    if (isConstructor()) return null;
-
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myReturnType == null) {
-        PsiMethodStub stub = getStub();
-        String typeText = TypeInfo.createTypeText(stub.getReturnTypeText(false));
-        assert typeText != null : stub;
-        myReturnType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
-      }
-      return myReturnType;
-    }
+    return myReturnType != null ? myReturnType.getValue() : null;
   }
 
   @Override
@@ -165,14 +177,7 @@
 
   @Override
   public PsiAnnotationMemberValue getDefaultValue() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myDefaultValue == null) {
-        final String text = getStub().getDefaultValueText();
-        if (text == null || StringUtil.isEmpty(text)) return null;
-        myDefaultValue = ClsParsingUtil.createMemberValueFromText(text, getManager(), this);
-      }
-      return myDefaultValue;
-    }
+    return myDefaultValue != null ? myDefaultValue.getValue() : null;
   }
 
   @Override
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
index 553a5fe..e75c320 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParameterImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -16,6 +16,8 @@
 package com.intellij.psi.impl.compiled;
 
 import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.VariableKind;
@@ -32,18 +34,27 @@
 import com.intellij.ui.RowIcon;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.PlatformIcons;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 
 import javax.swing.*;
 
 public class ClsParameterImpl extends ClsRepositoryPsiElement<PsiParameterStub> implements PsiParameter {
-  private PsiTypeElement myType = null;
-  private String myName;
-  private volatile String myMirrorName = null;
+  private final NotNullLazyValue<PsiTypeElement> myType;
+  private volatile String myName;
+  private volatile String myMirrorName;
 
   public ClsParameterImpl(@NotNull PsiParameterStub stub) {
     super(stub);
+    myType = new AtomicNotNullLazyValue<PsiTypeElement>() {
+      @NotNull
+      @Override
+      protected PsiTypeElement compute() {
+        PsiParameterStub stub = getStub();
+        String typeText = TypeInfo.createTypeText(stub.getType(false));
+        assert typeText != null : stub;
+        return new ClsTypeElementImpl(ClsParameterImpl.this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
+      }
+    };
   }
 
   @Override
@@ -53,24 +64,27 @@
 
   @Override
   public String getName() {
-    if (myName == null) {
+    String name = myName;
+    if (name == null) {
       if (DumbService.getInstance(getProject()).isDumb()) {
         return null;
       }
 
       ClsMethodImpl method = (ClsMethodImpl)getDeclarationScope();
       PsiMethod sourceMethod = method.getSourceMirrorMethod();
-      if (sourceMethod == null) {
-        final PsiParameterStubImpl parameterStub = (PsiParameterStubImpl) getStub();
-        if (!parameterStub.isAutoGeneratedName()) {
-          return parameterStub.getName();
-        }
-        return null;
+      if (sourceMethod != null) {
+        assert sourceMethod != method : method;
+        myName = name = sourceMethod.getParameterList().getParameters()[getIndex()].getName();
       }
-      assert sourceMethod != method;
-      myName = sourceMethod.getParameterList().getParameters()[getIndex()].getName();
+
+      if (name == null) {
+        PsiParameterStubImpl parameterStub = (PsiParameterStubImpl)getStub();
+        if (!parameterStub.isAutoGeneratedName()) {
+          name = parameterStub.getName();
+        }
+      }
     }
-    return myName;
+    return name;
   }
 
   @Override
@@ -81,15 +95,7 @@
   @Override
   @NotNull
   public PsiTypeElement getTypeElement() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myType == null) {
-        PsiParameterStub stub = getStub();
-        String typeText = TypeInfo.createTypeText(stub.getType(false));
-        assert typeText != null : stub;
-        myType = new ClsTypeElementImpl(this, typeText, ClsTypeElementImpl.VARIANCE_NONE);
-      }
-      return myType;
-    }
+    return myType.getValue();
   }
 
   @Override
@@ -144,12 +150,11 @@
   private String getMirrorName() {
     String mirrorName = myMirrorName;
     if (mirrorName == null) {
-      // avoid calculation of nice parameter name under lock as we might need indices for coolness
-      // and latter might produce deadlock, see IDEA-99248
-      mirrorName = calcNiceParameterName();
-      synchronized (LAZY_BUILT_LOCK) {
-        if (myMirrorName == null) {
-          myMirrorName = mirrorName;
+      // parameter name may depend on a name of a previous one in a same parameter list
+      synchronized (getParent()) {
+        mirrorName = myMirrorName;
+        if (mirrorName == null) {
+          myMirrorName = mirrorName = calcNiceParameterName();
         }
       }
     }
@@ -157,63 +162,40 @@
   }
 
   private String calcNiceParameterName() {
-    @NonNls String name;
+    String name = null;
 
-    final PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub();
+    PsiParameterStubImpl stub = (PsiParameterStubImpl)getStub();
     if (!stub.isAutoGeneratedName() || DumbService.getInstance(getProject()).isDumb()) {
       name = stub.getName();
     }
-    else {
+
+    if (name == null) {
       JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(getProject());
       String[] nameSuggestions = codeStyleManager.suggestVariableName(VariableKind.PARAMETER, null, null, getType()).names;
 
       name = "p";
-      if (nameSuggestions.length > 0) {
+      if (nameSuggestions.length > 0 && nameSuggestions[0] != null) {
         name = nameSuggestions[0];
       }
 
-      PsiParameter[] parameters = ((PsiParameterList) getParent()).getParameters();
+      String base = name;
+      int n = 0;
       AttemptsLoop:
       while (true) {
-        for (PsiParameter parameter : parameters) {
+        for (PsiParameter parameter : ((PsiParameterList)getParent()).getParameters()) {
           if (parameter == this) break AttemptsLoop;
-          String name1 = ((ClsParameterImpl) parameter).getMirrorName();
-          if (name.equals(name1)) {
-            name = nextName(name);
+          String prevName = ((ClsParameterImpl)parameter).getMirrorName();
+          if (name.equals(prevName)) {
+            name = base + (++n);
             continue AttemptsLoop;
           }
         }
       }
     }
 
-    assert name != null : stub;
     return name;
   }
 
-  private static String nextName(String name) {
-    int count = 0;
-    while (true) {
-      if (count == name.length()) break;
-      char c = name.charAt(name.length() - count - 1);
-      if ('0' <= c && c <= '9') {
-        count++;
-      }
-      else {
-        break;
-      }
-    }
-
-    try {
-      int n = count > 0 ? Integer.parseInt(name.substring(name.length() - count)) : 0;
-      n++;
-      return name.substring(0, name.length() - count) + n;
-    }
-    catch (NumberFormatException e) {
-      assert false : e.getMessage();
-      return null;
-    }
-  }
-
   @Override
   public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
     setMirrorCheckingType(element, null);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
index e3a27d8..39c1829 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsParsingUtil.java
@@ -126,20 +126,20 @@
     if (expr instanceof PsiLiteralExpression) {
       return new ClsLiteralExpressionImpl(parent, expr.getText(), expr.getType(), ((PsiLiteralExpression)expr).getValue());
     }
-    else if (expr instanceof PsiPrefixExpression) {
+    if (expr instanceof PsiPrefixExpression) {
       final PsiPrefixExpression prefixExpr = (PsiPrefixExpression)expr;
       final ClsJavaTokenImpl operation = new ClsJavaTokenImpl(null, prefixExpr.getOperationTokenType(), prefixExpr.getOperationSign().getText());
       final ClsLiteralExpressionImpl literal = (ClsLiteralExpressionImpl) psiToClsExpression(prefixExpr.getOperand(), null);
       return new ClsPrefixExpressionImpl(parent, operation, literal);
     }
-    else if (expr instanceof PsiClassObjectAccessExpression) {
+    if (expr instanceof PsiClassObjectAccessExpression) {
       final String canonicalClassText = ((PsiClassObjectAccessExpression)expr).getOperand().getType().getCanonicalText();
       return new ClsClassObjectAccessExpressionImpl(parent, canonicalClassText);
     }
-    else if (expr instanceof PsiReferenceExpression) {
+    if (expr instanceof PsiReferenceExpression) {
       return new ClsReferenceExpressionImpl(parent, (PsiReferenceExpression)expr);
     }
-    else if (expr instanceof PsiBinaryExpression) {
+    if (expr instanceof PsiBinaryExpression) {
       final PsiBinaryExpression binaryExpr = (PsiBinaryExpression)expr;
       final PsiExpression lOperand = psiToClsExpression(binaryExpr.getLOperand(), null);
       final ClsJavaTokenImpl operation = new ClsJavaTokenImpl(null, binaryExpr.getOperationTokenType(), binaryExpr.getOperationSign().getText());
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
index 88ec13c..f3193f9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsReferenceListImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -15,40 +15,44 @@
  */
 package com.intellij.psi.impl.compiled;
 
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.java.stubs.PsiClassReferenceListStub;
 import com.intellij.psi.impl.source.SourceTreeToPsiMap;
 import com.intellij.psi.impl.source.tree.TreeElement;
 import org.jetbrains.annotations.NotNull;
 
-@SuppressWarnings({"HardCodedStringLiteral"})
 public class ClsReferenceListImpl extends ClsRepositoryPsiElement<PsiClassReferenceListStub> implements PsiReferenceList {
   private static final ClsJavaCodeReferenceElementImpl[] EMPTY_REFS_ARRAY = new ClsJavaCodeReferenceElementImpl[0];
 
-  private ClsJavaCodeReferenceElementImpl[] myRefs;
+  private final NotNullLazyValue<ClsJavaCodeReferenceElementImpl[]> myRefs;
 
   public ClsReferenceListImpl(@NotNull PsiClassReferenceListStub stub) {
     super(stub);
+    myRefs = new AtomicNotNullLazyValue<ClsJavaCodeReferenceElementImpl[]>() {
+      @NotNull
+      @Override
+      protected ClsJavaCodeReferenceElementImpl[] compute() {
+        String[] strings = getStub().getReferencedNames();
+        if (strings.length > 0) {
+          ClsJavaCodeReferenceElementImpl[] refs = new ClsJavaCodeReferenceElementImpl[strings.length];
+          for (int i = 0; i < strings.length; i++) {
+            refs[i] = new ClsJavaCodeReferenceElementImpl(ClsReferenceListImpl.this, strings[i]);
+          }
+          return refs;
+        }
+        else {
+          return EMPTY_REFS_ARRAY;
+        }
+      }
+    };
   }
 
   @Override
   @NotNull
   public PsiJavaCodeReferenceElement[] getReferenceElements() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (myRefs == null) {
-        final String[] strings = getStub().getReferencedNames();
-        if (strings.length > 0) {
-          myRefs = new ClsJavaCodeReferenceElementImpl[strings.length];
-          for (int i = 0; i < strings.length; i++) {
-            myRefs[i] = new ClsJavaCodeReferenceElementImpl(this, strings[i]);
-          }
-        }
-        else {
-          myRefs = EMPTY_REFS_ARRAY;
-        }
-      }
-      return myRefs;
-    }
+    return myRefs.getValue();
   }
 
   @Override
@@ -76,13 +80,13 @@
       switch (role) {
         case EXTENDS_BOUNDS_LIST:
         case EXTENDS_LIST:
-          buffer.append("extends ");
+          buffer.append(PsiKeyword.EXTENDS).append(' ');
           break;
         case IMPLEMENTS_LIST:
-          buffer.append("implements ");
+          buffer.append(PsiKeyword.IMPLEMENTS).append(' ');
           break;
         case THROWS_LIST:
-          buffer.append("throws ");
+          buffer.append(PsiKeyword.THROWS).append(' ');
           break;
       }
       for (int i = 0; i < names.length; i++) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
index f8b821b..2fded2d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/compiled/ClsTypeElementImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -15,40 +15,59 @@
  */
 package com.intellij.psi.impl.compiled;
 
+import com.intellij.openapi.util.AtomicNotNullLazyValue;
+import com.intellij.openapi.util.NotNullLazyValue;
+import com.intellij.openapi.util.NullableLazyValue;
+import com.intellij.openapi.util.VolatileNullableLazyValue;
 import com.intellij.psi.*;
 import com.intellij.psi.impl.PsiImplUtil;
+import com.intellij.psi.impl.cache.TypeInfo;
 import com.intellij.psi.impl.source.PsiClassReferenceType;
 import com.intellij.psi.impl.source.tree.JavaElementType;
 import com.intellij.psi.impl.source.tree.TreeElement;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 public class ClsTypeElementImpl extends ClsElementImpl implements PsiTypeElement {
-  static final char VARIANCE_NONE = '\0';
-  static final char VARIANCE_EXTENDS = '+';
-  static final char VARIANCE_SUPER = '-';
-  static final char VARIANCE_INVARIANT = '*';
-  @NonNls private static final String VARIANCE_EXTENDS_PREFIX = "? extends ";
-  @NonNls private static final String VARIANCE_SUPER_PREFIX = "? super ";
+  @NonNls static final char VARIANCE_NONE = '\0';
+  @NonNls static final char VARIANCE_EXTENDS = '+';
+  @NonNls static final char VARIANCE_SUPER = '-';
+  @NonNls static final char VARIANCE_INVARIANT = '*';
+  @NonNls static final String VARIANCE_EXTENDS_PREFIX = "? extends ";
+  @NonNls static final String VARIANCE_SUPER_PREFIX = "? super ";
 
   private final PsiElement myParent;
   private final String myTypeText;
-  private volatile ClsElementImpl myChild = null;
-  private boolean myChildSet = false;
-  private volatile PsiType myCachedType;
   private final char myVariance;
+  private final NullableLazyValue<ClsElementImpl> myChild;
+  private final NotNullLazyValue<PsiType> myCachedType;
 
   public ClsTypeElementImpl(@NotNull PsiElement parent, @NotNull String typeText, char variance) {
     myParent = parent;
-    myTypeText = typeText;
+    myTypeText = TypeInfo.internFrequentType(typeText);
     myVariance = variance;
+    myChild = new VolatileNullableLazyValue<ClsElementImpl>() {
+      @Nullable
+      @Override
+      protected ClsElementImpl compute() {
+        return calculateChild();
+      }
+    };
+    myCachedType = new AtomicNotNullLazyValue<PsiType>() {
+      @NotNull
+      @Override
+      protected PsiType compute() {
+        return calculateType();
+      }
+    };
   }
 
   @Override
   @NotNull
   public PsiElement[] getChildren() {
-    loadChild();
-    return myChild != null ? new PsiElement[]{myChild} : PsiElement.EMPTY_ARRAY;
+    ClsElementImpl child = myChild.getValue();
+    return child != null ? new PsiElement[]{child} : PsiElement.EMPTY_ARRAY;
   }
 
   @Override
@@ -91,33 +110,12 @@
   public void setMirror(@NotNull TreeElement element) throws InvalidMirrorException {
     setMirrorCheckingType(element, JavaElementType.TYPE);
 
-    loadChild();
-
-    if (myChild != null) {
-      myChild.setMirror(element.getFirstChildNode());
+    ClsElementImpl child = myChild.getValue();
+    if (child != null) {
+      child.setMirror(element.getFirstChildNode());
     }
   }
 
-  private void loadChild() {
-    if (isPrimitive()) {
-      synchronized (LAZY_BUILT_LOCK) {
-        myChildSet = true;
-      }
-      return;
-    }
-
-    if (isArray() || isVarArgs()) {
-      createComponentTypeChild();
-    }
-    else {
-      createClassReferenceChild();
-    }
-  }
-
-  private boolean isPrimitive() {
-    return JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText) != null;
-  }
-
   private boolean isArray() {
     return myTypeText.endsWith("[]");
   }
@@ -129,14 +127,7 @@
   @Override
   @NotNull
   public PsiType getType() {
-    if (myCachedType == null) {
-      synchronized (LAZY_BUILT_LOCK) {
-        if (myCachedType == null) {
-          myCachedType = calculateType();
-        }
-      }
-    }
-    return myCachedType;
+    return myCachedType.getValue();
   }
 
   @Override
@@ -154,82 +145,66 @@
     return getType();
   }
 
+  private ClsElementImpl calculateChild() {
+    if (JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText) != null) {
+      return null;
+    }
+    else if (isArray()) {
+      return myVariance == VARIANCE_NONE
+             ? new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 2), myVariance)
+             : new ClsTypeElementImpl(this, myTypeText, VARIANCE_NONE);
+    }
+    else if (isVarArgs()) {
+      return new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 3), myVariance);
+    }
+    else {
+      return myVariance != VARIANCE_INVARIANT ? new ClsJavaCodeReferenceElementImpl(this, myTypeText) : null;
+    }
+  }
+
   private PsiType calculateType() {
     PsiType result = JavaPsiFacade.getInstance(getProject()).getElementFactory().createPrimitiveType(myTypeText);
     if (result != null) return result;
 
-    if (isArray()) {
-      createComponentTypeChild();
-      if (myVariance == VARIANCE_NONE) return ((PsiTypeElement)myChild).getType().createArrayType();
+    ClsElementImpl childElement = myChild.getValue();
+    if (childElement instanceof ClsTypeElementImpl) {
+      if (isArray()) {
+        switch (myVariance) {
+          case VARIANCE_NONE:
+            return ((PsiTypeElement)childElement).getType().createArrayType();
+          case VARIANCE_EXTENDS:
+            return PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)childElement).getType());
+          case VARIANCE_SUPER:
+            return PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)childElement).getType());
+          default:
+            assert false : myVariance;
+            return null;
+        }
+      }
+      else {
+        assert isVarArgs() : this;
+        return new PsiEllipsisType(((PsiTypeElement)childElement).getType());
+      }
+    }
+    else if (childElement instanceof ClsJavaCodeReferenceElementImpl) {
+      PsiClassReferenceType psiClassReferenceType = new PsiClassReferenceType((PsiJavaCodeReferenceElement)childElement, null);
       switch (myVariance) {
+        case VARIANCE_NONE:
+          return psiClassReferenceType;
         case VARIANCE_EXTENDS:
-          return PsiWildcardType.createExtends(getManager(), ((PsiTypeElement)myChild).getType());
+          return PsiWildcardType.createExtends(getManager(), psiClassReferenceType);
         case VARIANCE_SUPER:
-          return PsiWildcardType.createSuper(getManager(), ((PsiTypeElement)myChild).getType());
+          return PsiWildcardType.createSuper(getManager(), psiClassReferenceType);
+        case VARIANCE_INVARIANT:
+          return PsiWildcardType.createUnbounded(getManager());
         default:
           assert false : myVariance;
           return null;
       }
     }
-    else if (isVarArgs()) {
-      createComponentTypeChild();
-      return new PsiEllipsisType(((PsiTypeElement)myChild).getType());
-    }
-
-    createClassReferenceChild();
-    final PsiClassReferenceType psiClassReferenceType;
-    if (myVariance != VARIANCE_INVARIANT) {
-      psiClassReferenceType = new PsiClassReferenceType((PsiJavaCodeReferenceElement)myChild, null);
-    }
     else {
-      psiClassReferenceType = null;
-    }
-
-    switch (myVariance) {
-      case VARIANCE_NONE:
-        return psiClassReferenceType;
-      case VARIANCE_EXTENDS:
-        return PsiWildcardType.createExtends(getManager(), psiClassReferenceType);
-      case VARIANCE_SUPER:
-        return PsiWildcardType.createSuper(getManager(), psiClassReferenceType);
-      case VARIANCE_INVARIANT:
-        return PsiWildcardType.createUnbounded(getManager());
-      default:
-        assert false : myVariance;
-        return null;
-    }
-  }
-
-  private void createClassReferenceChild() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (!myChildSet) {
-        if (myVariance != VARIANCE_INVARIANT) {
-          myChild = new ClsJavaCodeReferenceElementImpl(this, myTypeText);
-        }
-        myChildSet = true;
-      }
-    }
-  }
-
-  private void createComponentTypeChild() {
-    synchronized (LAZY_BUILT_LOCK) {
-      if (!myChildSet) {
-        if (isArray()) {
-          if (myVariance == VARIANCE_NONE) {
-            myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 2), myVariance);
-          }
-          else {
-            myChild = new ClsTypeElementImpl(this, myTypeText, VARIANCE_NONE);
-          }
-        }
-        else if (isVarArgs()) {
-          myChild = new ClsTypeElementImpl(this, myTypeText.substring(0, myTypeText.length() - 3), myVariance);
-        }
-        else {
-          assert false : myTypeText;
-        }
-        myChildSet = true;
-      }
+      assert childElement == null : this;
+      return PsiWildcardType.createUnbounded(getManager());
     }
   }
 
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
index 9693582..20ab202 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/file/PsiPackageImpl.java
@@ -31,20 +31,23 @@
 import com.intellij.psi.scope.PsiScopeProcessor;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.psi.util.*;
+import com.intellij.reference.SoftReference;
 import com.intellij.util.CommonProcessors;
 import com.intellij.util.containers.ContainerUtil;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
-import java.util.*;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Set;
 
 public class PsiPackageImpl extends PsiPackageBase implements PsiPackage, Queryable {
   public static boolean DEBUG = false;
   private volatile CachedValue<PsiModifierList> myAnnotationList;
   private volatile CachedValue<Collection<PsiDirectory>> myDirectories;
-  private volatile Set<String> myPublicClassNamesCache;
-  private final Object myPublicClassNamesCacheLock = new Object();
+  private volatile SoftReference<Set<String>> myPublicClassNamesCache;
 
   public PsiPackageImpl(PsiManager manager, String qualifiedName) {
     super(manager, qualifiedName);
@@ -100,9 +103,7 @@
 
   @Override
   public boolean isValid() {
-    final CommonProcessors.FindFirstProcessor<PsiDirectory> processor = new CommonProcessors.FindFirstProcessor<PsiDirectory>();
-    getFacade().processPackageDirectories(this, allScope(), processor);
-    return processor.getFoundValue() != null || PsiPackageImplementationHelper.getInstance().packagePrefixExists(this);
+    return PsiPackageImplementationHelper.getInstance().packagePrefixExists(this) || !getAllDirectories().isEmpty();
   }
 
   @Override
@@ -161,14 +162,14 @@
   }
 
   private Set<String> getClassNamesCache() {
-    if (myPublicClassNamesCache == null) {
-      Set<String> classNames = getFacade().getClassNames(this, allScope());
-      synchronized (myPublicClassNamesCacheLock) {
-        myPublicClassNamesCache = classNames;
-      }
+    SoftReference<Set<String>> ref = myPublicClassNamesCache;
+    Set<String> cache = ref == null ? null : ref.get();
+    if (cache == null) {
+      cache = getFacade().getClassNames(this, allScope());
+      myPublicClassNamesCache = new SoftReference<Set<String>>(cache);
     }
 
-    return myPublicClassNamesCache;
+    return cache;
   }
 
   @NotNull
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
index 95888e0..8d60006 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/JavaClassElementType.java
@@ -18,6 +18,7 @@
 import com.intellij.lang.ASTNode;
 import com.intellij.lang.LighterAST;
 import com.intellij.lang.LighterASTNode;
+import com.intellij.pom.java.LanguageLevel;
 import com.intellij.psi.JavaTokenType;
 import com.intellij.psi.PsiClass;
 import com.intellij.psi.PsiNameHelper;
@@ -152,6 +153,7 @@
     if (!stub.isAnonymous()) {
       dataStream.writeName(stub.getName());
       dataStream.writeName(stub.getQualifiedName());
+      dataStream.writeByte(stub.getLanguageLevel().ordinal());
       dataStream.writeName(stub.getSourceFileName());
     }
     else {
@@ -163,16 +165,17 @@
   @Override
   public PsiClassStub deserialize(@NotNull final StubInputStream dataStream, final StubElement parentStub) throws IOException {
     byte flags = dataStream.readByte();
-
-    final boolean isAnonymous = PsiClassStubImpl.isAnonymous(flags);
-    final boolean isEnumConst = PsiClassStubImpl.isEnumConstInitializer(flags);
-    final JavaClassElementType type = typeForClass(isAnonymous, isEnumConst);
+    boolean isAnonymous = PsiClassStubImpl.isAnonymous(flags);
+    boolean isEnumConst = PsiClassStubImpl.isEnumConstInitializer(flags);
+    JavaClassElementType type = typeForClass(isAnonymous, isEnumConst);
 
     if (!isAnonymous) {
       StringRef name = dataStream.readName();
       StringRef qname = dataStream.readName();
-      final StringRef sourceFileName = dataStream.readName();
-      final PsiClassStubImpl classStub = new PsiClassStubImpl(type, parentStub, qname, name, null, flags);
+      int languageLevelId = dataStream.readByte();
+      StringRef sourceFileName = dataStream.readName();
+      PsiClassStubImpl classStub = new PsiClassStubImpl(type, parentStub, qname, name, null, flags);
+      classStub.setLanguageLevel(LanguageLevel.values()[languageLevelId]);
       classStub.setSourceFileName(sourceFileName);
       return classStub;
     }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
index 38009e7..b1e530e 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/java/stubs/impl/PsiClassStubImpl.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2012 JetBrains s.r.o.
+ * 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.
@@ -133,7 +133,7 @@
 
   @Override
   public LanguageLevel getLanguageLevel() {
-    return myLanguageLevel != null ? myLanguageLevel : LanguageLevel.HIGHEST; // TODO!!!
+    return myLanguageLevel != null ? myLanguageLevel : LanguageLevel.HIGHEST;
   }
 
   @Override
@@ -185,8 +185,7 @@
   @SuppressWarnings({"HardCodedStringLiteral"})
   public String toString() {
     StringBuilder builder = new StringBuilder();
-    builder.
-        append("PsiClassStub[");
+    builder.append("PsiClassStub[");
 
     if (isInterface()) {
       builder.append("interface ");
@@ -216,15 +215,12 @@
       builder.append("deprecatedA ");
     }
 
-    builder.
-        append("name=").append(getName()).
-        append(" fqn=").append(getQualifiedName());
+    builder.append("name=").append(getName()).append(" fqn=").append(getQualifiedName());
 
     if (getBaseClassReferenceText() != null) {
       builder.append(" baseref=").append(getBaseClassReferenceText());
     }
 
-
     if (isAnonymousInQualifiedNew()) {
       builder.append(" inqualifnew");
     }
diff --git a/java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
similarity index 100%
rename from java/java-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
rename to java/java-psi-impl/src/com/intellij/psi/impl/smartPointers/SmartTypePointerManagerImpl.java
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
index f62ca49..f9244e2 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/JavaFileElementType.java
@@ -38,7 +38,7 @@
  * @author max
  */
 public class JavaFileElementType extends ILightStubFileElementType<PsiJavaFileStub> {
-  public static final int STUB_VERSION = 16;
+  public static final int STUB_VERSION = 17;
 
   public JavaFileElementType() {
     super("java.FILE", JavaLanguage.INSTANCE);
@@ -92,8 +92,7 @@
   }
 
   @Override
-  public void serialize(@NotNull final PsiJavaFileStub stub, @NotNull final StubOutputStream dataStream)
-      throws IOException {
+  public void serialize(@NotNull final PsiJavaFileStub stub, @NotNull final StubOutputStream dataStream) throws IOException {
     dataStream.writeBoolean(stub.isCompiled());
     dataStream.writeName(stub.getPackageName());
   }
@@ -107,6 +106,5 @@
   }
 
   @Override
-  public void indexStub(@NotNull final PsiJavaFileStub stub, @NotNull final IndexSink sink) {
-  }
+  public void indexStub(@NotNull final PsiJavaFileStub stub, @NotNull final IndexSink sink) { }
 }
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
index 6b88ae6..e71bf63 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/PsiJavaFileBaseImpl.java
@@ -445,19 +445,22 @@
   }
 
   private LanguageLevel getLanguageLevelInner() {
-    if (myOriginalFile instanceof PsiJavaFile) return ((PsiJavaFile)myOriginalFile).getLanguageLevel();
-    final LanguageLevel forcedLanguageLevel = getUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY);
-    if (forcedLanguageLevel != null) return forcedLanguageLevel;
-    VirtualFile virtualFile = getVirtualFile();
-
-    if (virtualFile == null) {
-      virtualFile = getUserData(IndexingDataKeys.VIRTUAL_FILE);
+    if (myOriginalFile instanceof PsiJavaFile) {
+      return ((PsiJavaFile)myOriginalFile).getLanguageLevel();
     }
 
+    LanguageLevel forcedLanguageLevel = getUserData(PsiUtil.FILE_LANGUAGE_LEVEL_KEY);
+    if (forcedLanguageLevel != null) return forcedLanguageLevel;
+
+    VirtualFile virtualFile = getVirtualFile();
+    if (virtualFile == null) virtualFile = getUserData(IndexingDataKeys.VIRTUAL_FILE);
+
     final Project project = getProject();
     if (virtualFile == null) {
       final PsiFile originalFile = getOriginalFile();
-      if (originalFile instanceof PsiJavaFile && originalFile != this) return ((PsiJavaFile)originalFile).getLanguageLevel();
+      if (originalFile instanceof PsiJavaFile && originalFile != this) {
+        return ((PsiJavaFile)originalFile).getLanguageLevel();
+      }
       return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
     }
 
@@ -471,7 +474,8 @@
     if (classesLanguageLevel != null) {
       return classesLanguageLevel;
     }
-    return LanguageLevelProjectExtension.getInstance(project).getLanguageLevel();
+
+    return PsiUtil.getLanguageLevel(project);
   }
 
   private static class MyCacheBuilder implements CachedValueProvider<MostlySingularMultiMap<String, SymbolCollectingProcessor.ResultWithContext>> {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
index 38466a5..1adf3a5 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/javadoc/PsiInlineDocTagImpl.java
@@ -38,7 +38,7 @@
   private static final TokenSet TAG_VALUE_BIT_SET = TokenSet.create(
     DOC_TAG_VALUE_ELEMENT, DOC_METHOD_OR_FIELD_REF);
   private static final TokenSet VALUE_BIT_SET = TokenSet.orSet(TAG_VALUE_BIT_SET, TokenSet.create(
-    JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, WHITE_SPACE, DOC_COMMENT_BAD_CHARACTER));
+    JAVA_CODE_REFERENCE, DOC_TAG_VALUE_TOKEN, DOC_COMMENT_DATA, DOC_INLINE_TAG, DOC_REFERENCE_HOLDER, DOC_COMMENT_BAD_CHARACTER));
 
   public PsiInlineDocTagImpl() {
     super(DOC_INLINE_TAG);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
index 9fc420f..981739b 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/JavaResolveUtil.java
@@ -128,6 +128,12 @@
         PsiClass topMemberClass = getTopLevelClass(memberClass, accessObjectClass);
         PsiClass topAccessClass = getTopLevelClass(accessObjectClass, memberClass);
         if (!manager.areElementsEquivalent(topMemberClass, topAccessClass)) return false;
+        if (accessObjectClass instanceof PsiAnonymousClass && accessObjectClass.isInheritor(memberClass, true)) {
+          if (place instanceof PsiMethodCallExpression && 
+              ((PsiMethodCallExpression)place).getMethodExpression().getQualifierExpression() instanceof PsiThisExpression) {
+            return false;
+          }
+        }
       }
 
       if (fileResolveScope == null) {
@@ -183,7 +189,7 @@
     PsiClass lastClass = null;
     Boolean isAtLeast17 = null;
     for (PsiElement placeParent = place; placeParent != null; placeParent = placeParent.getContext()) {
-      if (placeParent instanceof PsiClass) {
+      if (placeParent instanceof PsiClass && !(placeParent instanceof PsiAnonymousClass)) {
         final boolean isTypeParameter = placeParent instanceof PsiTypeParameter;
         if (isTypeParameter && isAtLeast17 == null) {
           isAtLeast17 = JavaVersionService.getInstance().isAtLeast(place, JavaSdkVersion.JDK_1_7);
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
index ee65e92..3509fd9 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/ProcessCandidateParameterTypeInferencePolicy.java
@@ -56,6 +56,7 @@
       final JavaResolveResult[] results = getResults(contextCall, i);
       final PsiType innerReturnType = owner.getReturnType();
       for (final JavaResolveResult result : results) {
+        if (result == null) continue;
         final PsiSubstitutor substitutor = getSubstitutor(contextCall, expressions, i, result);
         final Pair<PsiType, ConstraintType> constraint = inferConstraint(typeParameter, innerMethodCall, i, innerReturnType, result, substitutor);
         if (constraint != null) return constraint;
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
index c9fbfbf..c22269d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/resolve/PsiResolveHelperImpl.java
@@ -398,6 +398,9 @@
               final ConstraintType currentConstraintType = currentConstraint.getSecond();
               if (currentConstraintType == ConstraintType.EQUALS) {
                 substitutionFromBounds = currentSubstitution;
+                if (currentSubstitution == null) {
+                  constraints[i] = FAILED_INFERENCE;
+                }
                 break OtherParameters;
               }
               else if (currentConstraintType == ConstraintType.SUPERTYPE) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
index e092c9e..109d32d 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiMethodReferenceExpressionImpl.java
@@ -45,12 +45,14 @@
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
 import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.SmartList;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
 import java.util.ArrayList;
+import java.util.Arrays;
 import java.util.List;
 import java.util.Map;
 
@@ -356,12 +358,21 @@
                                                                  PsiSubstitutor substitutor,
                                                                  LanguageLevel languageLevel) {
       if (signature == null) return PsiSubstitutor.EMPTY;
-      final PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
-      final PsiType[] rightTypes = signature.getParameterTypes();
-      if (types.length < rightTypes.length) {
-        return getSubstitutor(rightTypes[0]);
-      } else if (types.length > rightTypes.length) {
-        return getSubstitutor(types[0]);
+      PsiType[] types = method.getSignature(PsiUtil.isRawSubstitutor(method, substitutor) ? PsiSubstitutor.EMPTY : substitutor).getParameterTypes();
+      PsiType[] rightTypes = signature.getParameterTypes();
+      if (!method.isVarArgs() || types.length == 0) {
+        if (types.length < rightTypes.length) {
+          return getSubstitutor(rightTypes[0]);
+        } else if (types.length > rightTypes.length) {
+          return getSubstitutor(types[0]);
+        }
+      } else {
+        if (rightTypes.length != types.length || rightTypes[rightTypes.length - 1].getArrayDimensions() != types[types.length-1].getArrayDimensions()) {
+          types[types.length - 1] = ((PsiArrayType)types[types.length - 1]).getComponentType();
+          int min = Math.min(types.length, rightTypes.length);
+          types = Arrays.copyOf(types, min);
+          rightTypes = Arrays.copyOf(rightTypes, min);
+        }
       }
 
       for (int i = 0; i < rightTypes.length; i++) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
index 2e84a19..b93bf2a 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiReferenceExpressionImpl.java
@@ -25,10 +25,8 @@
 import com.intellij.psi.*;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleSettingsFacade;
-import com.intellij.psi.filters.AndFilter;
-import com.intellij.psi.filters.ConstructorFilter;
-import com.intellij.psi.filters.NotFilter;
-import com.intellij.psi.filters.OrFilter;
+import com.intellij.psi.filters.*;
+import com.intellij.psi.filters.element.ModifierFilter;
 import com.intellij.psi.impl.CheckUtil;
 import com.intellij.psi.impl.PsiImplUtil;
 import com.intellij.psi.impl.PsiManagerEx;
@@ -440,7 +438,7 @@
     // optimization: methodCallExpression should resolve to a method
     if (parentIsMethodCall != resolvingToMethod) return false;
 
-    return super.isReferenceTo(element);
+    return element.getManager().areElementsEquivalent(element, advancedResolve(true).getElement());
   }
 
   @Override
@@ -450,7 +448,17 @@
     if (isQualified()) {
       filter.addFilter(ElementClassFilter.PACKAGE_FILTER);
     }
-    filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter())));
+    filter.addFilter(new AndFilter(ElementClassFilter.METHOD, new NotFilter(new ConstructorFilter()), new ElementFilter() {
+      @Override
+      public boolean isAcceptable(Object element, @Nullable PsiElement context) {
+        return LambdaUtil.isValidQualifier4InterfaceStaticMethodCall((PsiMethod)element, PsiReferenceExpressionImpl.this);
+      }
+
+      @Override
+      public boolean isClassAcceptable(Class hintClass) {
+        return true;
+      }
+    }));
     filter.addFilter(ElementClassFilter.VARIABLE);
 
     FilterScopeProcessor filterProcessor = new FilterScopeProcessor<CandidateInfo>(filter, processor) {
diff --git a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
index ff7c042..2a8a620 100644
--- a/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
+++ b/java/java-psi-impl/src/com/intellij/psi/impl/source/tree/java/PsiThisExpressionImpl.java
@@ -42,9 +42,8 @@
   public PsiType getType() {
     PsiJavaCodeReferenceElement qualifier = getQualifier();
     if (qualifier != null){
-      PsiClass qualifierResolve = (PsiClass)qualifier.resolve();
-      if (qualifierResolve != null) return new PsiImmediateClassType(qualifierResolve, PsiSubstitutor.EMPTY);
-
+      PsiElement qualifierResolve = qualifier.resolve();
+      if (qualifierResolve instanceof PsiClass) return new PsiImmediateClassType((PsiClass)qualifierResolve, PsiSubstitutor.EMPTY);
       return new PsiClassReferenceType(qualifier, null);
     }
     for(PsiElement scope = getContext(); scope != null; scope = scope.getContext()){
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
index cf75c7e..f4b8aea 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/conflictResolvers/JavaMethodsConflictResolver.java
@@ -16,6 +16,7 @@
 package com.intellij.psi.scope.conflictResolvers;
 
 import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.progress.ProgressManager;
 import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.projectRoots.JavaVersionService;
 import com.intellij.openapi.util.Comparing;
@@ -106,6 +107,7 @@
       if (parameterType instanceof PsiLambdaExpressionType) {
         final PsiLambdaExpression lambdaExpression = ((PsiLambdaExpressionType)parameterType).getExpression();
         for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext(); ) {
+          ProgressManager.checkCanceled();
           final CandidateInfo conflict = iterator.next();
           final PsiMethod method = (PsiMethod)conflict.getElement();
           if (method != null) {
@@ -145,6 +147,7 @@
       for (int i = 1; i < conflictsCount; i++) {
         final CandidateInfo method = newConflictsArray[i];
         for (int j = 0; j < i; j++) {
+          ProgressManager.checkCanceled();
           final CandidateInfo conflict = newConflictsArray[j];
           assert conflict != method;
           switch (isMoreSpecific(method, conflict, applicabilityLevel)) {
@@ -169,6 +172,7 @@
     int[] checkLevels = new int[conflictsCount];
     int index = 0;
     for (final CandidateInfo conflict : conflicts) {
+      ProgressManager.checkCanceled();
       final MethodCandidateInfo method = (MethodCandidateInfo)conflict;
       final int level = checkAccessible ? getCheckAccessLevel(method) : getCheckStaticLevel(method);
       checkLevels[index++] = level;
@@ -189,12 +193,14 @@
     Map<MethodSignature, CandidateInfo> signatures = new HashMap<MethodSignature, CandidateInfo>();
     nextConflict:
     for (int i=0; i<conflicts.size();i++) {
+      ProgressManager.checkCanceled();
       CandidateInfo info = conflicts.get(i);
       PsiMethod method = (PsiMethod)info.getElement();
       assert method != null;
 
       if (!method.hasModifierProperty(PsiModifier.STATIC)) {
         for (int k=i-1; k>=0; k--) {
+          ProgressManager.checkCanceled();
           PsiMethod existingMethod = (PsiMethod)conflicts.get(k).getElement();
           if (PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
             conflicts.remove(i);
@@ -240,7 +246,7 @@
         i--;
         continue;
       }
-      else if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
+      if (!existingTypeParamAgree && infoTypeParamAgree && !PsiSuperMethodImplUtil.isSuperMethodSmart(existingMethod, method)) {
         signatures.put(signature, info);
         int index = conflicts.indexOf(existing);
         conflicts.remove(index);
@@ -315,6 +321,7 @@
     boolean atLeastOneMatch = false;
     TIntArrayList unmatchedIndices = null;
     for (int i = 0; i < conflicts.size(); i++) {
+      ProgressManager.checkCanceled();
       CandidateInfo info = conflicts.get(i);
       if (ignoreIfStaticsProblem && !info.isStaticsScopeCorrect()) return true;
       if (!(info instanceof MethodCandidateInfo)) continue;
@@ -350,6 +357,7 @@
     @MethodCandidateInfo.ApplicabilityLevelConstant int maxApplicabilityLevel = 0;
     boolean toFilter = false;
     for (CandidateInfo conflict : conflicts) {
+      ProgressManager.checkCanceled();
       final @MethodCandidateInfo.ApplicabilityLevelConstant int level = preferVarargs((MethodCandidateInfo)conflict);
       if (maxApplicabilityLevel > 0 && maxApplicabilityLevel != level) {
         toFilter = true;
@@ -361,6 +369,7 @@
 
     if (toFilter) {
       for (Iterator<CandidateInfo> iterator = conflicts.iterator(); iterator.hasNext();) {
+        ProgressManager.checkCanceled();
         CandidateInfo info = iterator.next();
         final int level = preferVarargs(info);
         if (level < maxApplicabilityLevel) {
@@ -464,10 +473,11 @@
     PsiType[] types1 = new PsiType[max];
     PsiType[] types2 = new PsiType[max];
     for (int i = 0; i < max; i++) {
+      ProgressManager.checkCanceled();
       PsiType type1 = params1.length > 0 ? params1[Math.min(i, params1.length - 1)].getType() : null;
       PsiType type2 = params2.length > 0 ? params2[Math.min(i, params2.length - 1)].getType() : null;
       if (applicabilityLevel == MethodCandidateInfo.ApplicabilityLevel.VARARGS) {
-        if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType && 
+        if (type1 instanceof PsiEllipsisType && type2 instanceof PsiEllipsisType &&
             (!JavaVersionService.getInstance().isAtLeast(class1, JavaSdkVersion.JDK_1_7) || ((PsiArrayType)type1).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT) || ((PsiArrayType)type2).getComponentType().equalsToText(CommonClassNames.JAVA_LANG_OBJECT))) {
           type1 = ((PsiEllipsisType)type1).toArrayType();
           type2 = ((PsiEllipsisType)type2).toArrayType();
@@ -484,6 +494,7 @@
 
     int[] boxingHappened = new int[2];
     for (int i = 0; i < types1.length; i++) {
+      ProgressManager.checkCanceled();
       PsiType type1 = classSubstitutor1.substitute(types1[i]);
       PsiType type2 = classSubstitutor2.substitute(types2[i]);
       PsiType argType = i < myActualParameterTypes.length ? myActualParameterTypes[i] : null;
@@ -496,6 +507,7 @@
 
     Specifics isMoreSpecific = null;
     for (int i = 0; i < types1.length; i++) {
+      ProgressManager.checkCanceled();
       Specifics specifics = checkSubstitutorSpecific(method1, method2, classSubstitutor1, classSubstitutor2, types1[i], types2[i]);
       if (specifics == null) {
         PsiSubstitutor methodSubstitutor1 = PsiSubstitutor.EMPTY;
@@ -581,10 +593,10 @@
     if (aClass1 instanceof PsiTypeParameter && aClass2 instanceof PsiTypeParameter) {
       return checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, (PsiTypeParameter)aClass1, (PsiTypeParameter)aClass2);
     }
-    if (aClass1 instanceof PsiTypeParameter) {
+    if (aClass1 instanceof PsiTypeParameter && aClass2 != null) {
       return chooseHigherDimension(type1, type2);
     }
-    else if (aClass2 instanceof PsiTypeParameter) {
+    else if (aClass2 instanceof PsiTypeParameter && aClass1 != null) {
       return chooseHigherDimension(type2, type1);
     }
 
@@ -599,15 +611,11 @@
       if (!raw1 && raw2) return Specifics.FIRST;
       if (raw1 && !raw2) return Specifics.SECOND;
 
-      final Specifics substArraySpecifics = chooseHigherDimension(t1, t2);
-      if (substArraySpecifics != null) {
-        return substArraySpecifics;
-      }
-      else {
-        final PsiTypeParameter p1 = map1.keySet().iterator().next();
-        final PsiTypeParameter p2 = map2.keySet().iterator().next();
-        return checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
-      }
+      final PsiTypeParameter p1 = map1.keySet().iterator().next();
+      final PsiTypeParameter p2 = map2.keySet().iterator().next();
+      final Specifics specifics = checkTypeParams(method1, method2, classSubstitutor1, classSubstitutor2, type1, type2, p1, p2);
+      if (specifics != null) return specifics;
+      return chooseHigherDimension(t1, t2);
     }
     return null;
   }
@@ -635,6 +643,7 @@
                                            PsiTypeParameter p2) {
     final Map<PsiClass, PsiClassType> resolved1 = new HashMap<PsiClass, PsiClassType>();
     for (PsiClassType referenceElement : p1.getExtendsList().getReferencedTypes()) {
+      ProgressManager.checkCanceled();
       final PsiClass aClass = referenceElement.resolve();
       if (aClass != null) {
         resolved1.put(aClass, referenceElement);
@@ -643,6 +652,7 @@
 
     final Map<PsiClass, PsiClassType> resolved2 = new HashMap<PsiClass, PsiClassType>();
     for (PsiClassType referenceElement : p2.getExtendsList().getReferencedTypes()) {
+      ProgressManager.checkCanceled();
       final PsiClass aClass = referenceElement.resolve();
       if (aClass != null) {
         resolved2.put(aClass, referenceElement);
@@ -660,7 +670,7 @@
                                TypeConversionUtil.erasure(PsiSubstitutor.EMPTY.substitute(p2)), method1, method2);
     if (specifics != null) {
       return specifics;
-    } else {               
+    } else {
       final PsiType ctype1 = classSubstitutor1.substitute(type1);
       final PsiType ctype2 = classSubstitutor2.substitute(type2);
       return checkSubtyping(ctype1, ctype2, method1, method2);
@@ -676,6 +686,7 @@
         PsiClass psiClass = iterator.next();
         final PsiClassType baseType = resolved1.get(psiClass);
         for (PsiClassType childType : resolved2.values()) {
+          ProgressManager.checkCanceled();
           if (TypeConversionUtil.isAssignable(baseType, childType, false)) {
             iterator.remove();
             break;
@@ -694,6 +705,7 @@
                                                     final PsiResolveHelper resolveHelper) {
     PsiSubstitutor substitutor = resolveHelper.inferTypeArguments(typeParameters, types1, types2, PsiUtil.getLanguageLevel(myArgumentsList));
     for (PsiTypeParameter typeParameter : typeParameters) {
+      ProgressManager.checkCanceled();
       LOG.assertTrue(typeParameter != null);
       if (!substitutor.getSubstitutionMap().containsKey(typeParameter)) {
         substitutor = substitutor.put(typeParameter, TypeConversionUtil.typeParameterErasure(typeParameter));
@@ -707,6 +719,7 @@
     if (JavaVersionService.getInstance().isAtLeast(myArgumentsList, JavaSdkVersion.JDK_1_7)) return;
     CandidateInfo objectVararg = null;
     for (CandidateInfo conflict : conflicts) {
+      ProgressManager.checkCanceled();
       final PsiMethod method = (PsiMethod)conflict.getElement();
       final int parametersCount = method.getParameterList().getParametersCount();
       if (method.isVarArgs() && parametersCount - 1 == argumentsCount) {
@@ -721,6 +734,7 @@
 
     if (objectVararg != null) {
       for (CandidateInfo conflict : conflicts) {
+        ProgressManager.checkCanceled();
         PsiMethod method = (PsiMethod)conflict.getElement();
         if (method != objectVararg && method != null && method.isVarArgs()) {
           final int paramsCount = method.getParameterList().getParametersCount();
diff --git a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
index 3cf132e..46036ea 100644
--- a/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
+++ b/java/java-psi-impl/src/com/intellij/psi/scope/util/PsiScopesUtil.java
@@ -310,6 +310,18 @@
 
         if (referenceName instanceof PsiIdentifier && qualifier instanceof PsiExpression) {
           PsiType type = ((PsiExpression)qualifier).getType();
+          if (type != null && qualifier instanceof PsiReferenceExpression) {
+            final PsiElement resolve = ((PsiReferenceExpression)qualifier).resolve();
+            if (resolve instanceof PsiVariable && ((PsiVariable)resolve).hasModifierProperty(PsiModifier.FINAL)) {
+              final PsiExpression initializer = ((PsiVariable)resolve).getInitializer();
+              if (initializer instanceof PsiNewExpression) {
+                final PsiAnonymousClass anonymousClass = ((PsiNewExpression)initializer).getAnonymousClass();
+                if (anonymousClass != null && type.equals(anonymousClass.getBaseClassType())) {
+                  type = initializer.getType();
+                }
+              }
+            }
+          }
           if (type == null) {
             if (qualifier instanceof PsiJavaCodeReferenceElement) {
               final JavaResolveResult result = ((PsiJavaCodeReferenceElement)qualifier).advancedResolve(false);
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
similarity index 86%
rename from java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
rename to java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
index 441f908..369613c 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/InputVariables.java
@@ -30,7 +30,7 @@
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.TypeConversionUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
 import com.intellij.util.ArrayUtil;
 import org.jetbrains.annotations.Nullable;
@@ -38,7 +38,7 @@
 import java.util.*;
 
 public class InputVariables {
-  private final List<ParameterTablePanel.VariableData> myInputVariables;
+  private final List<VariableData> myInputVariables;
 
   private List<? extends PsiVariable> myInitialParameters;
   private final Project myProject;
@@ -62,20 +62,20 @@
   /**
    * copy use only
    */
-  public InputVariables(List<ParameterTablePanel.VariableData> inputVariables,
+  public InputVariables(List<VariableData> inputVariables,
                         Project project,
                         LocalSearchScope scope) {
     myProject = project;
     myScope = scope;
-    myInputVariables = new ArrayList<ParameterTablePanel.VariableData>(inputVariables);
+    myInputVariables = new ArrayList<VariableData>(inputVariables);
   }
 
   public boolean isFoldable() {
     return myFolding.isFoldable();
   }
 
-  public ArrayList<ParameterTablePanel.VariableData> wrapInputVariables(final List<? extends PsiVariable> inputVariables) {
-    final ArrayList<ParameterTablePanel.VariableData> inputData = new ArrayList<ParameterTablePanel.VariableData>(inputVariables.size());
+  public ArrayList<VariableData> wrapInputVariables(final List<? extends PsiVariable> inputVariables) {
+    final ArrayList<VariableData> inputData = new ArrayList<VariableData>(inputVariables.size());
     for (PsiVariable var : inputVariables) {
       String name = var.getName();
       if (!(var instanceof PsiParameter)) {
@@ -117,7 +117,7 @@
         }
       }
 
-      ParameterTablePanel.VariableData data = new ParameterTablePanel.VariableData(var, type);
+      VariableData data = new VariableData(var, type);
       data.name = name;
       data.passAsParameter = true;
       inputData.add(data);
@@ -127,9 +127,9 @@
 
 
     if (myFoldingAvailable) {
-      final Set<ParameterTablePanel.VariableData> toDelete = new HashSet<ParameterTablePanel.VariableData>();
+      final Set<VariableData> toDelete = new HashSet<VariableData>();
       for (int i = inputData.size() - 1; i >=0; i--) {
-        final ParameterTablePanel.VariableData data = inputData.get(i);
+        final VariableData data = inputData.get(i);
         if (myFolding.isParameterSafeToDelete(data, myScope)) {
           toDelete.add(data);
         }
@@ -189,7 +189,7 @@
     return currentType;
   }
 
-  public List<ParameterTablePanel.VariableData> getInputVariables() {
+  public List<VariableData> getInputVariables() {
     return myInputVariables;
   }
 
@@ -197,15 +197,15 @@
     if (!myFoldingAvailable) return expression;
 
     boolean update = elements[0] == expression;
-    for (ParameterTablePanel.VariableData inputVariable : myInputVariables) {
+    for (VariableData inputVariable : myInputVariables) {
       myFolding.foldParameterUsagesInBody(inputVariable, elements, myScope);
     }
     return update ? (PsiExpression)elements[0] : expression;
   }
 
   public boolean toDeclareInsideBody(PsiVariable variable) {
-    final ArrayList<ParameterTablePanel.VariableData> knownVars = new ArrayList<ParameterTablePanel.VariableData>(myInputVariables);
-    for (ParameterTablePanel.VariableData data : knownVars) {
+    final ArrayList<VariableData> knownVars = new ArrayList<VariableData>(myInputVariables);
+    for (VariableData data : knownVars) {
       if (data.variable.equals(variable)) {
         return false;
       }
@@ -214,7 +214,7 @@
   }
 
   public boolean contains(PsiVariable variable) {
-    for (ParameterTablePanel.VariableData data : myInputVariables) {
+    for (VariableData data : myInputVariables) {
       if (data.variable.equals(variable)) return true;
     }
     return false;
@@ -227,8 +227,8 @@
                                               int endOffset) {
     final LocalSearchScope scope = new LocalSearchScope(codeFragment);
     Variables:
-    for (Iterator<ParameterTablePanel.VariableData> iterator = myInputVariables.iterator(); iterator.hasNext();) {
-      final ParameterTablePanel.VariableData data = iterator.next();
+    for (Iterator<VariableData> iterator = myInputVariables.iterator(); iterator.hasNext();) {
+      final VariableData data = iterator.next();
       for (PsiReference ref : ReferencesSearch.search(data.variable, scope)) {
         PsiElement element = ref.getElement();
         int elementOffset = controlFlow.getStartOffset(element);
@@ -257,7 +257,7 @@
   }
 
 
-  public void appendCallArguments(ParameterTablePanel.VariableData data, StringBuilder buffer) {
+  public void appendCallArguments(VariableData data, StringBuilder buffer) {
     if (myFoldingAvailable) {
       buffer.append(myFolding.getGeneratedCallArgument(data));
     } else {
@@ -277,7 +277,7 @@
   }
 
   public void annotateWithParameter(PsiJavaCodeReferenceElement reference) {
-    for (ParameterTablePanel.VariableData data : myInputVariables) {
+    for (VariableData data : myInputVariables) {
       final PsiElement element = reference.resolve();
       if (data.variable.equals(element)) {
         PsiType type = data.variable.getType();
diff --git a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
similarity index 93%
rename from java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
rename to java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
index a6fed17..eac9b18 100644
--- a/java/java-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/extractMethod/ParametersFolder.java
@@ -31,7 +31,7 @@
 import com.intellij.psi.search.searches.ReferencesSearch;
 import com.intellij.psi.util.PsiTreeUtil;
 import com.intellij.psi.util.PsiUtil;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.refactoring.util.duplicates.DuplicatesFinder;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
@@ -54,7 +54,7 @@
     myDeleted.clear();
   }
 
-  public boolean isParameterSafeToDelete(@NotNull ParameterTablePanel.VariableData data, @NotNull LocalSearchScope scope) {
+  public boolean isParameterSafeToDelete(@NotNull VariableData data, @NotNull LocalSearchScope scope) {
     Next:
     for (PsiReference reference : ReferencesSearch.search(data.variable, scope)) {
       PsiElement expression = reference.getElement();
@@ -82,7 +82,7 @@
     return false;
   }
 
-  public void foldParameterUsagesInBody(@NotNull ParameterTablePanel.VariableData data, PsiElement[] elements, SearchScope scope) {
+  public void foldParameterUsagesInBody(@NotNull VariableData data, PsiElement[] elements, SearchScope scope) {
     if (myDeleted.contains(data.variable)) return;
     final PsiExpression psiExpression = myExpressions.get(data.variable);
     if (psiExpression == null) return;
@@ -108,7 +108,7 @@
     }
   }
 
-  public boolean isParameterFoldable(@NotNull ParameterTablePanel.VariableData data,
+  public boolean isParameterFoldable(@NotNull VariableData data,
                                      @NotNull LocalSearchScope scope,
                                      @NotNull final List<? extends PsiVariable> inputVariables) {
     final List<PsiExpression> mentionedInExpressions = getMentionedExpressions(data.variable, scope, inputVariables);
@@ -164,8 +164,8 @@
     }
     return false;
   }
-  
-  private void setUniqueName(ParameterTablePanel.VariableData data) {
+
+  private void setUniqueName(VariableData data) {
     int idx = 1;
     while (myUsedNames.contains(data.name)) {
       data.name += idx;
@@ -173,7 +173,7 @@
     myUsedNames.add(data.name);
   }
 
-  private static Set<PsiVariable> findUsedVariables(ParameterTablePanel.VariableData data, final List<? extends PsiVariable> inputVariables,
+  private static Set<PsiVariable> findUsedVariables(VariableData data, final List<? extends PsiVariable> inputVariables,
                                              PsiExpression expression) {
     final Set<PsiVariable> found = new HashSet<PsiVariable>();
     expression.accept(new JavaRecursiveElementVisitor() {
@@ -275,11 +275,11 @@
   }
 
   @NotNull
-  public String getGeneratedCallArgument(@NotNull ParameterTablePanel.VariableData data) {
+  public String getGeneratedCallArgument(@NotNull VariableData data) {
     return myExpressions.containsKey(data.variable) ? myExpressions.get(data.variable).getText() : data.variable.getName();
   }
 
-  public boolean annotateWithParameter(@NotNull ParameterTablePanel.VariableData data, @NotNull PsiElement element) {
+  public boolean annotateWithParameter(@NotNull VariableData data, @NotNull PsiElement element) {
     final PsiExpression psiExpression = myExpressions.get(data.variable);
     if (psiExpression != null) {
       final PsiExpression expression = findEquivalent(psiExpression, element);
diff --git a/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java b/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
new file mode 100644
index 0000000..0fd6cc0
--- /dev/null
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/VariableData.java
@@ -0,0 +1,38 @@
+/*
+ * 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.refactoring.util;
+
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+import com.intellij.psi.SmartTypePointerManager;
+import org.jetbrains.annotations.NotNull;
+
+public class VariableData {
+  public final PsiVariable variable;
+  public PsiType type;
+  public String name;
+  public boolean passAsParameter;
+
+  public VariableData(@NotNull PsiVariable var) {
+    variable = var;
+    type = var.getType();
+  }
+
+  public VariableData(@NotNull PsiVariable var, @NotNull PsiType type) {
+    variable = var;
+    this.type = SmartTypePointerManager.getInstance(var.getProject()).createSmartTypePointer(type).getType();
+  }
+}
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/BreakReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ConditionalReturnStatementValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ContinueReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
similarity index 99%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
index b6d8a55..d44b9d8 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/DuplicatesFinder.java
@@ -634,7 +634,7 @@
         array.add(child);
       }
     }
-    return PsiUtilBase.toPsiElementArray(array);
+    return PsiUtilCore.toPsiElementArray(array);
   }
 
 }
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ExpressionReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/FieldReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/GotoReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
similarity index 82%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
index 2ba06af..ef633f7 100644
--- a/java/java-impl/src/com/intellij/refactoring/util/duplicates/Match.java
+++ b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/Match.java
@@ -26,13 +26,13 @@
 import com.intellij.psi.codeStyle.CodeStyleManager;
 import com.intellij.psi.codeStyle.JavaCodeStyleManager;
 import com.intellij.psi.controlFlow.*;
-import com.intellij.psi.util.*;
-import com.intellij.refactoring.changeSignature.ChangeSignatureProcessor;
-import com.intellij.refactoring.changeSignature.ParameterInfoImpl;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.psi.util.TypeConversionUtil;
 import com.intellij.util.ArrayUtil;
 import com.intellij.util.IncorrectOperationException;
 import com.intellij.util.containers.HashMap;
-import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
 import org.jetbrains.annotations.Nullable;
 
@@ -53,7 +53,7 @@
   private final Map<PsiElement, PsiElement> myDeclarationCorrespondence = new HashMap<PsiElement, PsiElement>();
   private ReturnValue myReturnValue = null;
   private Ref<PsiExpression> myInstanceExpression = null;
-  private final Map<PsiVariable, PsiType> myChangedParams = new HashMap<PsiVariable, PsiType>();
+  final Map<PsiVariable, PsiType> myChangedParams = new HashMap<PsiVariable, PsiType>();
   private final boolean myIgnoreParameterTypes;
 
   Match(PsiElement start, PsiElement end, boolean ignoreParameterTypes) {
@@ -339,75 +339,7 @@
   }
 
   @Nullable
-  public String getChangedSignature(final PsiMethod method, final boolean shouldBeStatic, String visibility) {
-    final PsiType returnType = getChangedReturnType(method);
-    if (!myChangedParams.isEmpty() || returnType != null) {
-      @NonNls StringBuilder buffer = new StringBuilder();
-      buffer.append(visibility);
-      if (buffer.length() > 0) {
-        buffer.append(" ");
-      }
-      if (shouldBeStatic) {
-        buffer.append("static ");
-      }
-      final PsiTypeParameterList typeParameterList = method.getTypeParameterList();
-      if (typeParameterList != null) {
-        buffer.append(typeParameterList.getText());
-        buffer.append(" ");
-      }
-
-      buffer.append(PsiFormatUtil.formatType(returnType != null ? returnType : method.getReturnType(), 0, PsiSubstitutor.EMPTY));
-      buffer.append(" ");
-      buffer.append(method.getName());
-      buffer.append("(");
-      int count = 0;
-      final String INDENT = "    ";
-      final ArrayList<ParameterInfoImpl> params = patchParams(method);
-      for (ParameterInfoImpl param : params) {
-        String typeText = param.getTypeText();
-        if (count > 0) {
-          buffer.append(",");
-        }
-        buffer.append("\n");
-        buffer.append(INDENT);
-        buffer.append(typeText);
-        buffer.append(" ");
-        buffer.append(param.getName());
-        count++;
-      }
-
-      if (count > 0) {
-        buffer.append("\n");
-      }
-      buffer.append(")");
-      final PsiClassType[] exceptions = method.getThrowsList().getReferencedTypes();
-      if (exceptions.length > 0) {
-        buffer.append("\n");
-        buffer.append("throws\n");
-        for (PsiType exception : exceptions) {
-          buffer.append(INDENT);
-          buffer.append(PsiFormatUtil.formatType(exception, 0, PsiSubstitutor.EMPTY));
-          buffer.append("\n");
-        }
-      }
-      return buffer.toString();
-    }
-    return null;
-  }
-
-  public void changeSignature(final PsiMethod psiMethod) {
-    final PsiType expressionType = getChangedReturnType(psiMethod);
-    if (expressionType == null && myChangedParams.isEmpty()) return;
-    final ArrayList<ParameterInfoImpl> newParameters = patchParams(psiMethod);
-    final ChangeSignatureProcessor csp = new ChangeSignatureProcessor(psiMethod.getProject(), psiMethod, false, null, psiMethod.getName(),
-                                                                      expressionType != null ? expressionType : psiMethod.getReturnType(),
-                                                                      newParameters.toArray(new ParameterInfoImpl[newParameters.size()]));
-
-    csp.run();
-  }
-
-  @Nullable
-  private PsiType getChangedReturnType(final PsiMethod psiMethod) {
+  public PsiType getChangedReturnType(final PsiMethod psiMethod) {
     final PsiType returnType = psiMethod.getReturnType();
     if (returnType != null) {
       PsiElement parent = getMatchEnd().getParent();
@@ -487,23 +419,6 @@
     return !TypeConversionUtil.isAssignable(currentType, substitutor.substitute(returnType));
   }
 
-  private ArrayList<ParameterInfoImpl> patchParams(final PsiMethod psiMethod) {
-    final ArrayList<ParameterInfoImpl> newParameters = new ArrayList<ParameterInfoImpl>();
-    final PsiParameter[] oldParameters = psiMethod.getParameterList().getParameters();
-    for (int i = 0; i < oldParameters.length; i++) {
-      final PsiParameter oldParameter = oldParameters[i];
-      PsiType type = oldParameter.getType();
-      for (PsiVariable variable : myChangedParams.keySet()) {
-        if (PsiEquivalenceUtil.areElementsEquivalent(variable, oldParameter)) {
-          type = myChangedParams.get(variable);
-          break;
-        }
-      }
-      newParameters.add(new ParameterInfoImpl(i, oldParameter.getName(), type));
-    }
-    return newParameters;
-  }
-
   public PsiFile getFile() {
     return getMatchStart().getContainingFile();
   }
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnStatementReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/ReturnValue.java
diff --git a/java/java-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java b/java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
similarity index 100%
rename from java/java-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
rename to java/java-psi-impl/src/com/intellij/refactoring/util/duplicates/VariableReturnValue.java
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java
new file mode 100644
index 0000000..872fe86
--- /dev/null
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/ComparisonFailureData.java
@@ -0,0 +1,109 @@
+/*
+ * 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.rt.execution.junit;
+
+import junit.framework.ComparisonFailure;
+
+import java.lang.reflect.Field;
+import java.util.HashMap;
+import java.util.Map;
+
+public class ComparisonFailureData {
+  private final String myExpected;
+  private final String myActual;
+  private final String myFilePath;
+
+  private static Map EXPECTED = new HashMap();
+  private static Map ACTUAL = new HashMap();
+
+  static {
+    try {
+      init(ComparisonFailure.class);
+      init(org.junit.ComparisonFailure.class);
+    }
+    catch (Throwable e) {
+    }
+  }
+
+  private static void init(Class exceptionClass) throws NoSuchFieldException {
+    final Field expectedField = exceptionClass.getDeclaredField("fExpected");
+    expectedField.setAccessible(true);
+    EXPECTED.put(exceptionClass, expectedField);
+
+    final Field actualField = exceptionClass.getDeclaredField("fActual");
+    actualField.setAccessible(true);
+    ACTUAL.put(exceptionClass, actualField);
+  }
+
+  public ComparisonFailureData(String expected, String actual) {
+    this(expected, actual, null);
+  }
+
+  public ComparisonFailureData(String expected, String actual, String filePath) {
+    myExpected = expected;
+    myActual = actual;
+    myFilePath = filePath;
+  }
+
+  public String getFilePath() {
+    return myFilePath;
+  }
+
+  public String getExpected() {
+    return myExpected;
+  }
+
+  public String getActual() {
+    return myActual;
+  }
+
+  public static ComparisonFailureData create(Throwable assertion) {
+    if (assertion instanceof FileComparisonFailure) {
+      final FileComparisonFailure comparisonFailure = (FileComparisonFailure)assertion;
+      return new ComparisonFailureData(comparisonFailure.getExpected(), comparisonFailure.getActual(), comparisonFailure.getFilePath());
+    }
+    try {
+      return new ComparisonFailureData(getExpected(assertion), getActual(assertion));
+    }
+    catch (Throwable e) {
+      return null;
+    }
+  }
+
+  public static String getActual(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+     return get(assertion, ACTUAL, "fActual");
+   }
+ 
+   public static String getExpected(Throwable assertion) throws IllegalAccessException, NoSuchFieldException {
+     return get(assertion, EXPECTED, "fExpected");
+   }
+ 
+   private static String get(final Throwable assertion, final Map staticMap, final String fieldName) throws IllegalAccessException, NoSuchFieldException {
+     String actual;
+     if (assertion instanceof ComparisonFailure) {
+       actual = (String)((Field)staticMap.get(ComparisonFailure.class)).get(assertion);
+     }
+     else if (assertion instanceof org.junit.ComparisonFailure) {
+       actual = (String)((Field)staticMap.get(org.junit.ComparisonFailure.class)).get(assertion);
+     }
+     else {
+       Field field = assertion.getClass().getDeclaredField(fieldName);
+       field.setAccessible(true);
+       actual = (String)field.get(assertion);
+     }
+     return actual;
+   }
+}
diff --git a/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
index 0a66a53..788e872 100644
--- a/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
+++ b/java/java-runtime/src/com/intellij/rt/execution/junit/FileComparisonFailure.java
@@ -31,6 +31,18 @@
     myFilePath = filePath;
   }
 
+  public String getFilePath() {
+    return myFilePath;
+  }
+
+  public String getExpected() {
+    return myExpected;
+  }
+
+  public String getActual() {
+    return myActual;
+  }
+
   public PacketFactory getPacketFactory() {
     return new MyPacketFactory(this, myExpected, myActual, myFilePath);
   }
diff --git a/java/java-tests/java-tests.iml b/java/java-tests/java-tests.iml
index d74dcea..eb7ea31 100644
--- a/java/java-tests/java-tests.iml
+++ b/java/java-tests/java-tests.iml
@@ -30,6 +30,7 @@
     <orderEntry type="module" module-name="IntentionPowerPackPlugin" scope="TEST" />
     <orderEntry type="module" module-name="InspectionGadgetsPlugin" scope="TEST" />
     <orderEntry type="module" module-name="java-indexing-api" scope="TEST" />
+    <orderEntry type="module" module-name="external-system-impl" scope="RUNTIME" />
   </component>
 </module>
 
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java
new file mode 100644
index 0000000..2cb308f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation.java
@@ -0,0 +1,6 @@
+class MyClass {
+  String hc = this.<caret>
+
+  @Annotation
+  public void myAnnotatedMethod() {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java
new file mode 100644
index 0000000..71da13a
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodCallBeforeAnnotation_After.java
@@ -0,0 +1,6 @@
+class MyClass {
+  String hc = this.toString()<caret>
+
+  @Annotation
+  public void myAnnotatedMethod() {}
+}
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java b/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
index c976d92..b7841df 100644
--- a/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodNoPairBrace_after.java
@@ -3,6 +3,6 @@
 void foo() {}
 
 {
-  foo(<caret>
+  foo();<caret>
 }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java b/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
index c976d92..b7841df 100644
--- a/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
+++ b/java/java-tests/testData/codeInsight/completion/normal/MethodWithLeftParTailTypeNoPairBrace_after2.java
@@ -3,6 +3,6 @@
 void foo() {}
 
 {
-  foo(<caret>
+  foo();<caret>
 }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java
new file mode 100644
index 0000000..646b108
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NewByteArray2.java
@@ -0,0 +1,10 @@
+public class Bug17 {
+
+  private void f(byte[] d) {
+  }
+
+  private void g() {
+    f(new <caret>);
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
index 6d72b12..3580d9c 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket-out.java
@@ -1,6 +1,6 @@
 class A {
   {
     String x;
-    Class c = x.getClass(<caret>
+    Class c = x.getClass()<caret>
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
index 5dbeaa6..63fd0d5 100644
--- a/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
+++ b/java/java-tests/testData/codeInsight/completion/smartType/NoTailWhenNoPairBracket2-out.java
@@ -1,6 +1,6 @@
 class A {
   {
-    Class c = this.xxxxx(<caret>
+    Class c = this.xxxxx()<caret>
   }
 
   Class xxxxx() {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
index 214a3ae..fa1ed55 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/advHighlighting7/IDEA78916.java
@@ -35,4 +35,14 @@
     public abstract void execute();
 
     private void firstMethod() {}
+}
+
+class Test {
+    private class Foo {
+        private Foo() {}
+
+        {
+          new  Foo(){};
+        }
+    }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
index 8b9c700..04d39bd 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA105846.java
@@ -1,5 +1,6 @@
 class MyClass {
     public static void main(Class<? extends MyClass> clazz){
         clazz = (Class<? extends MyClass>) clazz.getSuperclass();
+        <error descr="Incompatible types. Found: 'java.lang.Class<capture<? super capture<? extends MyClass>>>', required: 'java.lang.Class<? extends MyClass>'">clazz = clazz.getSuperclass()</error>;
     }
 }
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java
new file mode 100644
index 0000000..8c8603e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA106964.java
@@ -0,0 +1,12 @@
+import java.io.Serializable;
+
+public abstract class Test {
+
+    abstract <T> T test(Class<T> cls);
+
+    abstract <T> T test(Serializable type);
+
+    private void call(){
+        <error descr="Incompatible types. Found: 'java.lang.String[]', required: 'java.lang.String'">String s = test(String[].class);</error>
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java
new file mode 100644
index 0000000..a078c65
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107782.java
@@ -0,0 +1,15 @@
+public class Test {
+  {
+    final <error descr="Incompatible types. Found: 'java.lang.Object', required: 'MyResult'">MyResult hello = parseXML(new Parser());</error>
+  }
+  public <R, P extends AbstractParser & Result<R>> R parseXML(P parser) {
+    R result = null;
+    return result;
+  }
+}
+class MyResult {}
+
+class AbstractParser {}
+interface Result<T> {}
+class Parser extends AbstractParser implements Result {}
+
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java
new file mode 100644
index 0000000..1228be1
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/genericsHighlighting/IDEA107957.java
@@ -0,0 +1,37 @@
+class Test1 {
+
+  private static final Foo<Boolean> test = new Foo().method(Boolean.TRUE);
+
+  public static void main(String[] args) {
+    System.out.println(test);
+  }
+
+  public static class Foo<T> {
+    public Foo<Boolean> method(boolean arg) {
+      return null;
+    }
+
+    public <T extends Enum<T>> Foo<T> method(T arg) {
+      return null;
+    }
+  }
+}
+
+class Test2 {
+
+  private static final Foo<Boolean> test = Foo.method(Boolean.TRUE);
+
+  public static void main(String[] args) {
+    System.out.println(test);
+  }
+
+  public static class Foo<T> {
+    public static Foo<Boolean> method(boolean arg) {
+      return null;
+    }
+
+    public static <T extends Enum<T>> Foo<T> method(T arg) {
+      return null;
+    }
+  }
+}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java
new file mode 100644
index 0000000..b9f90eb
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/SelfStaticsOnly.java
@@ -0,0 +1,14 @@
+interface Function<T, R> {
+  public R apply(T t);
+
+  static <K> Function<K, K> baz() {
+    return k -> k;
+  }
+}
+
+interface IFunction extends Function<Integer, Integer> {
+  static void bar() {}
+  static void ba() {
+    ba<caret>
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java
new file mode 100644
index 0000000..0c517e9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/interfaceMethods/StaticMethodCalls.java
@@ -0,0 +1,25 @@
+
+class Bug {
+
+  interface Function<T, R> {
+    public R apply(T t);
+
+    static <K> Function<K, K> identity() {
+      return k -> k;
+    }
+  }
+
+  interface IFunction extends Function<Integer, Integer> {
+    static void a() {
+      Function<Integer, Integer> identity = <error descr="Static method may be invoked on containing interface class only">identity();</error>
+    }
+  }
+
+  public void foo() {
+    Function<Integer, Integer> f = Function.identity();
+
+    Function<Integer, Integer> g = <error descr="Static method may be invoked on containing interface class only">f.identity();</error>
+
+    Function<Integer, Integer> h = <error descr="Static method may be invoked on containing interface class only">IFunction.identity();</error>
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
index 3ed7e3e..0fa9c84 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/RefOnArrayDeclaration.java
@@ -45,3 +45,16 @@
         ObjectArrayReturnType a5 = Foo<? extends String>[]::new;
     }
 }
+
+
+class IDEA106973 {
+  interface Function<T, R> {
+    R apply(T t);
+  }
+  
+  {
+    Function<Integer, String[]> a  = String[] :: new;
+    <error descr="Incompatible types. Found: '<method reference>', required: 'IDEA106973.Function<java.lang.String,java.lang.String[]>'">Function<String, String[]> a1  = String[] :: new;</error>
+    Function<Short, String[]> a2  = String[] :: new;
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java
new file mode 100644
index 0000000..7edfd28
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/lambda/methodRef/VarargsMethodRef.java
@@ -0,0 +1,26 @@
+import java.util.List;
+
+class Test {
+  void a(List<String> range1, List<String> range2) {
+    zip(range1, range2, Test::<String>asList);
+    I1<String> i = Test :: asList;
+  }
+
+  public static <A, B, C> List<C> zip(List<? extends A> a,
+                                      List<? extends B> b,
+                                      BiFunction<? super A, ? super B, ? extends C> zipper) {
+    return null;
+  }
+
+  public interface BiFunction<T, U, R> {
+    R apply(T t, U u);
+  }
+
+  public static <T> List<T> asList(T... a) {
+    return null;
+  }
+
+  interface I1<T> {
+    List<T> a(T... t);
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
index e9baac3..f20329a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterFieldExist.java
@@ -6,7 +6,7 @@
         setI(0);
     }
 
-    public void setI(int i) {
+    void setI(int i) {
         this.i = i;
     }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
index b28d93d..69c33eb 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/createPropertyFromUsage/afterSimple.java
@@ -6,7 +6,7 @@
         setI(0);
     }
 
-    public void setI(int i) {
+    void setI(int i) {
         this.i = i;
     }
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java
new file mode 100644
index 0000000..a355f5b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/iterateOver/before4.java
@@ -0,0 +1,6 @@
+// "Iterate" "false"
+class Test {
+  void foo() {
+    java.lang.thi<caret>s
+  }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
index 7d3370d..cd556b8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/replaceWithTernaryOperator/afterChain.java
@@ -5,6 +5,6 @@
 class A{
   void test(){
     Integer integer = null;
-    int i = integer != null ? integer.toString().length() : <selection>0</selection>;
+    int i = integer != null ? integer.toString().length() : <caret><selection>0</selection>;
   }
 }
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
index a89027d..f5d44db 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after1.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     List<Integer> list = new List<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
index 622c3e2..a7a54e2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/after2TypeParamsInOneCall.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<String, Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
index 1b85916..fbae0b9 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterAnotherParamTypeChange.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
index 1b43850..0818ad2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterBoxing.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     List<Integer> list = new List<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
index a6e6d60..67cc9ed 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterCompound.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
index 802baaf..ce1f568 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/afterMixed.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<Integer> list = new Lost<>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
index c14b834..d35d424 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before1.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     List<String> list = new List<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
index ee27ed3..9dd0ab1 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/before2TypeParamsInOneCall.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.String,java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<String, String> list = new Lost<String, String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
index 61e8684..f4558d1 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeAnotherParamTypeChange.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
index 1d02b91..88778ca 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeBoxing.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'List<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'List<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     List<String> list = new List<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
index 9f5ec3b..a2206b0 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeChangeSignatureAvailable.java
@@ -1,4 +1,4 @@
-// "Change 'var' type to 'Foo" "false"
+// "Change variable 'var' type to 'Foo" "false"
 public class Test {
   void foo()  {
     final Foo var = new Foo();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
index aa2eb0c..7f2dc11 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeCompound.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
index b0d6cab..074e647 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/varTypeFromCall/beforeMixed.java
@@ -1,4 +1,4 @@
-// "Change 'list' type to 'Lost<java.lang.Integer>'" "true"
+// "Change variable 'list' type to 'Lost<java.lang.Integer>'" "true"
 public class Test {
   void foo()  {
     Lost<String> list = new Lost<String>();
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
index b7f7e63..06c81a4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         final int[][] test = {new int<caret>[]{1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
index 1cadb61..2f4ebd3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after2.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         int[][] test = new int[][]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
index 1cadb61..2f4ebd3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after3.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         int[][] test = new int[][]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
index 89ddf94..0a68cc2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after4.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         int[][] test = new int[][]{{<caret>1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
index 8893a91..9534a4f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after5.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
 class A {
     void m() {
         final char[] test = new char[]{<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
index 0debead..5aec9e2 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after6.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
 class A {
     void m() {
         final char[] test = {<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
index a74a518..896709f 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/after9.java
@@ -1,4 +1,4 @@
-// "Change 'myArr' type to 'char[][]'" "true"
+// "Change field 'myArr' type to 'char[][]'" "true"
 class A extends B {
     void m() {
         myArr = new char[][]{{<caret>'a'}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
index 34cc492..e61ec51 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         final Long[][] test = {new int<caret>[]{1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
index be9e287..e79fc74 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before2.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         Long[][][] test = new Long[]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
index 35e45cd..c191198 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before3.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         Long[] test = new Long[]{<caret>{1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
index 007800e..4fa4be4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before4.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'int[][]'" "true"
+// "Change variable 'test' type to 'int[][]'" "true"
 class A {
     void m() {
         Long test = new Long[][][][]{{<caret>1}, {2}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
index a048c22..f9e177a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before5.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
 class A {
     void m() {
         final Long[] test = new Long[]{<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
index 2e5b97f..be8d3f8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before6.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "true"
+// "Change variable 'test' type to 'char[]'" "true"
 class A {
     void m() {
         final Long[] test = {<caret>'a'};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
index 769d870..ca5e5ea 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before7.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[]'" "false"
+// "Change variable 'test' type to 'char[]'" "false"
 class A {
     void m() {
         final Long[] test = {<caret>'a', 1};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
index 0d64ee5..cd07ae8 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before8.java
@@ -1,4 +1,4 @@
-// "Change 'test' type to 'char[][]'" "false"
+// "Change variable 'test' type to 'char[][]'" "false"
 class A {
     void m() {
         final Long[] test = {<caret>{'a'}, {1}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
index de63666..24cc6b3 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableArrayType/before9.java
@@ -1,4 +1,4 @@
-// "Change 'myArr' type to 'char[][]'" "true"
+// "Change field 'myArr' type to 'char[][]'" "true"
 class A extends B {
     void m() {
         myArr = new String[][]{{<caret>'a'}};
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
index ea910a3..7c815dc 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'a.i.ii<java.lang.String>'" "true"
+// "Change variable 'i' type to 'a.i.ii<java.lang.String>'" "true"
 class a
 {
   class i {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
index defc656..74da8a6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'a.i.ii<java.lang.String>'" "true"
+// "Change variable 'i' type to 'a.i.ii<java.lang.String>'" "true"
 class a
 {
   class i {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
index 88cad2e..c3533aa 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableParameterizedType/before2.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'O.f<java.lang.String>'" "false"
+// "Change variable 's' type to 'O.f<java.lang.String>'" "false"
 
 class O {
 
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
index a588bf7..4a73de6 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'double'" "true"
+// "Change variable 'i' type to 'double'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
index 3ee033e..d2f02db 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after2.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change variable 'i' type to 'java.lang.String'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
index 61d52c1..e29ef26 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after3.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'char'" "true"
+// "Change variable 'i' type to 'char'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
index d7b4163..4b4f439 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after4.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'java.lang.Runnable'" "true"
+// "Change field 's' type to 'java.lang.Runnable'" "true"
 
 class a {
     Runnable s = new Runnable() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
index 6a7f841..84d6850 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/after5.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
 
 class Base {
  void foo(String i) {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
index 35b2904..f707135 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/afterInCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
 
 class Ex{
  void foo(String i) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
index 4e8742b..245c148 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before1.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'double'" "true"
+// "Change variable 'i' type to 'double'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
index 6b80da6..9591611 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before2.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change variable 'i' type to 'java.lang.String'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
index f94ad9a..de69713 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before3.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'char'" "true"
+// "Change variable 'i' type to 'char'" "true"
 import java.io.*;
 
 class a {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
index 6265e56..b93daef 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before4.java
@@ -1,4 +1,4 @@
-// "Change 's' type to 'java.lang.Runnable'" "true"
+// "Change field 's' type to 'java.lang.Runnable'" "true"
 
 class a {
     String s = <caret>new Runnable() {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
index 7ead738..e2ce5b4 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/before5.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
 
 class Base {
  void foo(int i) {}
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
index 92a32c9..4c4999a 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'java.lang.String'" "true"
+// "Change parameter 'i' type to 'java.lang.String'" "true"
 
 class Ex{
  void foo(int i) {
diff --git a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
index 337af8a..62fde5e 100644
--- a/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
+++ b/java/java-tests/testData/codeInsight/daemonCodeAnalyzer/quickFix/variableType/beforeInLibCall.java
@@ -1,4 +1,4 @@
-// "Change 'i' type to 'long'" "false"
+// "Change parameter 'i' type to 'long'" "false"
 
 class M extends Thread {
   @Override
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java
new file mode 100644
index 0000000..b7c36e9
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods.java
@@ -0,0 +1,30 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+  public void method() {
+    //do nothing
+  }
+
+  public void method2() {
+
+  }
+}
+
+class ClassEx1 extends BaseClass {
+  @Override
+  public void method() {
+  }
+}
+
+class ClassEx2 extends BaseClass {
+  public void method() {
+  }
+
+  public void method(String aString) {
+  }
+}
+
+class MyClass extends B<caret>aseClass {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java
new file mode 100644
index 0000000..931d40b
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods2.java
@@ -0,0 +1,31 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+  public void method() {
+    //do nothing
+  }
+
+  public void method(String s) {
+    //do nothing
+  }
+}
+
+class ClassEx1 extends BaseClass {
+  @Override
+  public void method() {
+  }
+
+  @Override
+  public void method(String s) {
+  }
+}
+
+class ClassEx2 extends BaseClass {
+  public void method() {
+  }
+}
+
+class MyClass extends B<caret>aseClass {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java
new file mode 100644
index 0000000..d79ab2f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods3.java
@@ -0,0 +1,39 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+  public void method() {
+    //do nothing
+  }
+
+  public void method(String s) {
+    //do nothing
+  }
+}
+
+class ClassEx1 extends BaseClass {
+  @Override
+  public void method() {
+  }
+
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+class ClassEx11 extends ClassEx1 {
+  public void method2() {
+  }
+}
+
+class ClassEx2 extends BaseClass {
+  public void method() {
+  }
+}
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java
new file mode 100644
index 0000000..0295f9f
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods4.java
@@ -0,0 +1,40 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+  public void method() {
+    //do nothing
+  }
+
+  public void method(String s) {
+    //do nothing
+  }
+}
+
+class ClassEx1 extends BaseClass {
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+class ClassEx11 extends ClassEx1 {
+  public void method2() {
+  }
+}
+
+class ClassEx2 extends BaseClass {
+  public void method() {
+  }
+}
+
+class ClassEx3 extends BaseClass {
+  public void method() {
+  }
+}
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java
new file mode 100644
index 0000000..a330bf3
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/generation/javaMethodsOverridingStatistics/Methods5.java
@@ -0,0 +1,63 @@
+import java.lang.Override;
+import java.lang.String;
+
+class BaseClass {
+  public void method() {
+    //do nothing
+  }
+
+  public void method(String s) {
+    //do nothing
+  }
+}
+
+class ClassEx2 extends BaseClass {
+  public void method() {
+  }
+}
+
+class ClassEx3 extends BaseClass {
+  public void method() {
+  }
+}
+
+class ClassEx1 extends BaseClass {
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+class ClassEx11 extends ClassEx1 {
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+class ClassEx12 extends ClassEx1 {
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+class ClassEx13 extends ClassEx1 {
+  @Override
+  public void method(String s) {
+  }
+
+  public void method2() {
+  }
+}
+
+
+class MyClass extends Cl<caret>assEx1 {
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java
new file mode 100644
index 0000000..19bb377
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/invertIfCondition/afterParenthesis.java
@@ -0,0 +1,10 @@
+// "Invert If Condition" "true"
+class A {
+    public boolean foo(boolean a, boolean b, boolean c, boolean d) {
+
+        if ((a || b) && !c && !d) {
+            return true;
+        }
+        return false;
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java
new file mode 100644
index 0000000..269790e
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/invertIfCondition/beforeParenthesis.java
@@ -0,0 +1,9 @@
+// "Invert If Condition" "true"
+class A {
+    public boolean foo(boolean a, boolean b, boolean c, boolean d) {
+
+      if (!(a |<caret>| b) || c || d)
+        return false;
+      return true;
+    }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/literal.html b/java/java-tests/testData/codeInsight/javadocIG/literal.html
new file mode 100644
index 0000000..bc3d265
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/literal.html
@@ -0,0 +1,2 @@
+<html><head>    <style type="text/css">        #error {            background-color: #eeeeee;            margin-bottom: 10px;        }        p {            margin: 5px 0;        }    </style></head><body><small><b><a href="psi_element://Foo"><code>Foo</code></a></b></small><PRE>int <b>foo</b></PRE>
+     foo&lt;&gt;</body></html>
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/javadocIG/literal.java b/java/java-tests/testData/codeInsight/javadocIG/literal.java
new file mode 100644
index 0000000..a6413f5
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/javadocIG/literal.java
@@ -0,0 +1,6 @@
+class Foo {
+  /**
+   * foo{@literal <>}
+   */
+  int foo;
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java
new file mode 100644
index 0000000..75297f7
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/overrideImplement/afterRawInheritance.java
@@ -0,0 +1,11 @@
+class Obj<T> {}
+abstract class A1<X>{
+    abstract void foo(Obj<String> x);
+}
+
+class B1 extends A1{
+    @Override
+    void foo(Obj x) {
+        <caret>
+    }
+}
diff --git a/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java
new file mode 100644
index 0000000..f546cae
--- /dev/null
+++ b/java/java-tests/testData/codeInsight/overrideImplement/beforeRawInheritance.java
@@ -0,0 +1,8 @@
+class Obj<T> {}
+abstract class A1<X>{
+    abstract void foo(Obj<String> x);
+}
+
+class B1 extends A1{
+  <caret>
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
index 20d33e1..a3780aa 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/EqualsHasNoSideEffects.java
@@ -13,7 +13,7 @@
       else if (((user == null && <warning descr="Condition 'identifier.user == null' is always 'true' when reached">identifier.user == null</warning>)
                 || (this.user.equals(identifier.user)))
                &&
-               ((requestorClass == null && <warning descr="Condition 'identifier.requestorClass == null' is always 'true' when reached">identifier.requestorClass == null</warning>)
+               ((requestorClass == null && identifier.requestorClass == null)
                 || this.requestorClass.equals(identifier.requestorClass)))
         return true;
       else
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
index 411e3a0..63e606b 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/FieldChangedBetweenSynchronizedBlocks.java
@@ -12,7 +12,7 @@
       if (field != null) {
         return;
       }
-      if (<warning descr="Condition 'field == null' is always 'true'">field == null</warning>) {
+      if (field == null) {
         System.out.println();
       }
     }
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
index c542ba8..038315f 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNotAnnotatedFieldsTreatment.java
@@ -54,12 +54,12 @@
     System.out.println(data.hashCode());
   }
 
-  void warnWhenDoubleChecked_This_WithMethodCall() {
+  void doNotWarnWhenDoubleChecked_This_WithMethodCall() {
     if (data == null) {
       return;
     }
     System.out.println(data.hashCode());
-    if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) {
+    if (data == null) {
       return;
     }
     System.out.println(data.hashCode());
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
index 107d11f..282c63e 100644
--- a/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/MutableNullableFieldsTreatment.java
@@ -56,12 +56,12 @@
     System.out.println(data.hashCode());
   }
   
-  void warnWhenDoubleChecked_This_WithMethodCall() {
+  void doNotWarnWhenDoubleChecked_This_WithMethodCall() {
     if (data == null) {
       return;
     }
     System.out.println(data.hashCode());
-    if (<warning descr="Condition 'data == null' is always 'false'">data == null</warning>) {
+    if (data == null) {
       return;
     }
     System.out.println(data.hashCode());
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java
new file mode 100644
index 0000000..d76f214
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/NotNullPrimitive.java
@@ -0,0 +1,24 @@
+import org.jetbrains.annotations.NotNull;
+
+class Foo {
+  public int getValue() {
+    return 5;
+  }
+
+  public void nullcheck() {
+    Integer x = getValue();
+    System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
+  }
+}
+
+class Bar {
+  @NotNull
+  public Integer getValue() {
+    return 5;
+  }
+
+  public void nullcheck() {
+    Integer x = getValue();
+    System.out.println(<warning descr="Condition 'x == null' is always 'false'">x == null</warning> ? "NULL" : Integer.toHexString(x));
+  }
+}
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java b/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java
new file mode 100644
index 0000000..9b7ee85
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/OtherCallMayChangeFields.java
@@ -0,0 +1,26 @@
+class Ref {
+  int i;
+  Object obj;
+}
+
+class Modifier {
+  void foo(Ref r) { r.i = 239; r.obj = null; }
+}
+
+class Test {
+  void foo(Ref r, Modifier m) {
+    if (r.i == 0) {
+      m.foo(r);
+      if (r.i == 0) {
+        return;
+      }
+    }
+    if (r.obj == null) {
+      m.foo(r);
+      if (r.obj == null) {
+        return;
+      }
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java b/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java
new file mode 100644
index 0000000..dd38e5a
--- /dev/null
+++ b/java/java-tests/testData/inspection/dataFlow/fixture/StringConcatAlwaysNotNull.java
@@ -0,0 +1,15 @@
+import org.jetbrains.annotations.NotNull;
+
+class X {
+  @NotNull
+  String foo() {return "";}
+
+  void bar() {
+    String o = foo();
+    o += "";
+    if (<warning descr="Condition 'o != null' is always 'true'">o != null</warning>) {
+
+    }
+  }
+
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt b/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
index ce11e0e..f0da4d5 100644
--- a/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
+++ b/java/java-tests/testData/psi/cls/mirror/ClassRefs.txt
@@ -5,7 +5,8 @@
 package pkg;
 
 class ClassRefs {
-    @pkg.AnnWithTypeLocal(type = java.lang.String.class)
+    @pkg.DefaultArgAnno(java.lang.String.class)
+    @pkg.NamedArgAnno(type = java.lang.String.class)
     public static final java.lang.Class<?> cls;
 
     ClassRefs() { /* compiled code */ }
diff --git a/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt b/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt
new file mode 100644
index 0000000..eec6980
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/ValuedEnum.txt
@@ -0,0 +1,19 @@
+
+  // IntelliJ API Decompiler stub source generated from a class file
+  // Implementation of methods is not available
+
+package org.apache.commons.lang.enum;
+
+public abstract class ValuedEnum extends org.apache.commons.lang.enum.Enum {
+    private final int iValue;
+
+    protected ValuedEnum(java.lang.String name, int value) { /* compiled code */ }
+
+    protected static org.apache.commons.lang.enum.Enum getEnum(java.lang.Class enumClass, int value) { /* compiled code */ }
+
+    public final int getValue() { /* compiled code */ }
+
+    public int compareTo(java.lang.Object other) { /* compiled code */ }
+
+    public java.lang.String toString() { /* compiled code */ }
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class b/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class
deleted file mode 100644
index 9252a8e..0000000
--- a/java/java-tests/testData/psi/cls/mirror/pkg/AnnWithTypeLocal.class
+++ /dev/null
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class b/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
index ca03e1b..693426f 100644
--- a/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ClassRefs.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class
new file mode 100644
index 0000000..1709f6e
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/DefaultArgAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class b/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class
new file mode 100644
index 0000000..ae31837
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/NamedArgAnno.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class b/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class
new file mode 100644
index 0000000..5dbc74d
--- /dev/null
+++ b/java/java-tests/testData/psi/cls/mirror/pkg/ValuedEnum.class
Binary files differ
diff --git a/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java b/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
index af3784c..9bbfe0d 100644
--- a/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
+++ b/java/java-tests/testData/psi/cls/mirror/src/pkg/ClassRefs.java
@@ -1,10 +1,15 @@
 package pkg;
 
 class ClassRefs {
-  @AnnWithTypeLocal(type = String.class)
+  @DefaultArgAnno(String.class)
+  @NamedArgAnno(type = String.class)
   public static final Class<?> cls = String.class;  // class refs are set from class initaializer
 }
 
-@interface AnnWithTypeLocal {
-  Class type();
+@interface DefaultArgAnno {
+  Class<?> value();
+}
+
+@interface NamedArgAnno {
+  Class<?> type();
 }
diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java
new file mode 100644
index 0000000..fa5180a
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous.java
@@ -0,0 +1,13 @@
+public class Foo {
+  public void update() {}
+}
+
+class FooBar {
+  {
+    Foo tm = new Foo() {
+      {
+        <selection>update()</selection>;
+      }
+    };
+  }
+}
diff --git a/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java
new file mode 100644
index 0000000..575b821
--- /dev/null
+++ b/java/java-tests/testData/refactoring/extractMethod/TargetAnonymous_after.java
@@ -0,0 +1,17 @@
+public class Foo {
+  public void update() {}
+}
+
+class FooBar {
+  {
+    Foo tm = new Foo() {
+      {
+        newMethod();
+      }
+
+        private void newMethod() {
+            update();
+        }
+    };
+  }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java
new file mode 100644
index 0000000..8152842
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/after/Test.java
@@ -0,0 +1,27 @@
+class Test {
+  /**
+   * foo comment
+   * @param param
+   * @param s1 long1 description1
+   */
+  void foo(Param param, String s1) {
+    bar(param.getS(), s1);
+  }
+
+  void bar(String s, String s1){}
+
+    private static class Param {
+        private final String s;
+
+        /**
+         * @param s long description
+         */
+        private Param(String s) {
+            this.s = s;
+        }
+
+        public String getS() {
+            return s;
+        }
+    }
+}
diff --git a/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java
new file mode 100644
index 0000000..af7c82f
--- /dev/null
+++ b/java/java-tests/testData/refactoring/introduceParameterObject/copyJavadoc1/before/Test.java
@@ -0,0 +1,12 @@
+class Test {
+  /**
+   * foo comment
+   * @param s long description
+   * @param s1 long1 description1
+   */
+  void foo(String s, String s1) {
+    bar(s, s1);
+  }
+
+  void bar(String s, String s1){}
+}
diff --git a/java/java-tests/testData/refactoring/renameInplace/Incomplete.java b/java/java-tests/testData/refactoring/renameInplace/Incomplete.java
new file mode 100644
index 0000000..78eaf1b
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameInplace/Incomplete.java
@@ -0,0 +1,3 @@
+class Klaz {
+  final static Class K = Klaz<caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java b/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java
new file mode 100644
index 0000000..93fbccb
--- /dev/null
+++ b/java/java-tests/testData/refactoring/renameInplace/Incomplete_after.java
@@ -0,0 +1,3 @@
+class Klazz {
+  final static Class K = Klazz<caret>
+}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java
new file mode 100644
index 0000000..855ed15
--- /dev/null
+++ b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound.java
@@ -0,0 +1,3 @@
+interface Foo1 {}
+interface FooTo<caret>Delete extends Foo1 {}
+class TypeParamOwner<B extends FooToDelete> {}
\ No newline at end of file
diff --git a/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java
new file mode 100644
index 0000000..c0c81b0
--- /dev/null
+++ b/java/java-tests/testData/refactoring/safeDelete/InterfaceAsTypeParameterBound_after.java
@@ -0,0 +1,3 @@
+interface Foo1 {}
+
+class TypeParamOwner<B extends Foo1> {}
\ No newline at end of file
diff --git a/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java b/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
index 2a00e76..2bbdb91 100644
--- a/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
+++ b/java/java-tests/testSrc/com/intellij/TestClassesFilterTest.java
@@ -1,49 +1,35 @@
 /*
- * Copyright (c) 2004 JetBrains s.r.o. All  Rights Reserved.
+ * Copyright 2000-2013 JetBrains s.r.o.
  *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
  *
- * -Redistributions of source code must retain the above copyright
- *  notice, this list of conditions and the following disclaimer.
+ * http://www.apache.org/licenses/LICENSE-2.0
  *
- * -Redistribution in binary form must reproduct the above copyright
- *  notice, this list of conditions and the following disclaimer in
- *  the documentation and/or other materials provided with the distribution.
- *
- * Neither the name of JetBrains or IntelliJ IDEA
- * may be used to endorse or promote products derived from this software
- * without specific prior written permission.
- *
- * This software is provided "AS IS," without a warranty of any kind. ALL
- * EXPRESS OR IMPLIED CONDITIONS, REPRESENTATIONS AND WARRANTIES, INCLUDING
- * ANY IMPLIED WARRANTY OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE
- * OR NON-INFRINGEMENT, ARE HEREBY EXCLUDED. JETBRAINS AND ITS LICENSORS SHALL NOT
- * BE LIABLE FOR ANY DAMAGES OR LIABILITIES SUFFERED BY LICENSEE AS A RESULT
- * OF OR RELATING TO USE, MODIFICATION OR DISTRIBUTION OF THE SOFTWARE OR ITS
- * DERIVATIVES. IN NO EVENT WILL JETBRAINS OR ITS LICENSORS BE LIABLE FOR ANY LOST
- * REVENUE, PROFIT OR DATA, OR FOR DIRECT, INDIRECT, SPECIAL, CONSEQUENTIAL,
- * INCIDENTAL OR PUNITIVE DAMAGES, HOWEVER CAUSED AND REGARDLESS OF THE THEORY
- * OF LIABILITY, ARISING OUT OF THE USE OF OR INABILITY TO USE SOFTWARE, EVEN
- * IF JETBRAINS HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH DAMAGES.
- *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
  */
 package com.intellij;
 
 import com.intellij.openapi.diagnostic.Logger;
-import junit.framework.TestCase;
+import org.junit.Test;
 
 import java.io.ByteArrayInputStream;
-import java.io.IOException;
 import java.io.InputStreamReader;
+import java.io.UnsupportedEncodingException;
 
-public class TestClassesFilterTest extends TestCase {
+import static org.junit.Assert.assertFalse;
+import static org.junit.Assert.assertTrue;
+
+public class TestClassesFilterTest {
   private static final Logger LOG = Logger.getInstance("#com.intellij.TestClassesFilterTest");
 
-  @SuppressWarnings({"IOResourceOpenedButNotSafelyClosed"})
-  public void test() throws IOException {
-
+  @Test
+  public void test() throws Exception {
     LOG.info("test");
 
     String filterText = "[Group1]\n" +
@@ -55,9 +41,7 @@
                         "com.intellij.package6.ExcludedTest\n" +
                         "com.intellij.package7.*package8";
 
-
-    TestClassesFilter classesFilter = GroupBasedTestClassFilter
-      .createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), "Group1");
+    TestClassesFilter classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), "Group1");
     assertTrue(classesFilter.matches("com.intellij.package1.Test"));
     assertTrue(classesFilter.matches("com.intellij.package1.Test2"));
     assertFalse(classesFilter.matches("com.intellij.package2.Test"));
@@ -67,7 +51,6 @@
     assertFalse(classesFilter.matches("com.intellij.package3"));
     assertFalse(classesFilter.matches("com.intellij"));
     assertFalse(classesFilter.matches("com.intellij.Test"));
-
     assertFalse(classesFilter.matches("com.intellij.package5.Test"));
     assertFalse(classesFilter.matches("com.intellij.package5.Test2"));
     assertFalse(classesFilter.matches("com.intellij.package6.Test"));
@@ -76,8 +59,7 @@
     assertFalse(classesFilter.matches("com.intellij.package7.package5.package8"));
     assertFalse(classesFilter.matches("com.intellij.package7"));
 
-    classesFilter = GroupBasedTestClassFilter
-      .createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), "Group2");
+    classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), "Group2");
     assertFalse(classesFilter.matches("com.intellij.package1.Test"));
     assertFalse(classesFilter.matches("com.intellij.package1.Test2"));
     assertFalse(classesFilter.matches("com.intellij.package2.Test"));
@@ -87,7 +69,6 @@
     assertFalse(classesFilter.matches("com.intellij.package3"));
     assertFalse(classesFilter.matches("com.intellij"));
     assertFalse(classesFilter.matches("com.intellij.Test"));
-
     assertTrue(classesFilter.matches("com.intellij.package5.Test"));
     assertTrue(classesFilter.matches("com.intellij.package5.Test2"));
     assertFalse(classesFilter.matches("com.intellij.package6.Test"));
@@ -96,14 +77,18 @@
     assertTrue(classesFilter.matches("com.intellij.package7.package5.package8"));
     assertFalse(classesFilter.matches("com.intellij.package7"));
 
-    checkForNullGroup(filterText, null);
-    checkForNullGroup(filterText, GroupBasedTestClassFilter.ALL_EXCLUDE_DEFINED);
+    classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), null);
+    checkForNullGroup(classesFilter);
 
+    classesFilter = GroupBasedTestClassFilter.createOn(getReader(filterText), GroupBasedTestClassFilter.ALL_EXCLUDE_DEFINED);
+    checkForNullGroup(classesFilter);
   }
 
-  private static void checkForNullGroup(String filterText, String group0Name) {
-    TestClassesFilter classesFilter = GroupBasedTestClassFilter.createOn(new InputStreamReader(new ByteArrayInputStream(filterText.getBytes())), group0Name);
+  private static InputStreamReader getReader(String filterText) throws UnsupportedEncodingException {
+    return new InputStreamReader(new ByteArrayInputStream(filterText.getBytes("UTF-8")));
+  }
 
+  private static void checkForNullGroup(TestClassesFilter classesFilter) {
     assertFalse(classesFilter.matches("com.intellij.package1.Test"));
     assertFalse(classesFilter.matches("com.intellij.package1.Test2"));
     assertTrue(classesFilter.matches("com.intellij.package2.Test"));
@@ -113,7 +98,6 @@
     assertTrue(classesFilter.matches("com.intellij.package3"));
     assertTrue(classesFilter.matches("com.intellij"));
     assertTrue(classesFilter.matches("com.intellij.Test"));
-
     assertFalse(classesFilter.matches("com.intellij.package5.Test"));
     assertFalse(classesFilter.matches("com.intellij.package5.Test2"));
     assertTrue(classesFilter.matches("com.intellij.package6.Test"));
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
index 2ec1ed6..7cc14eb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/CopyReferenceTest.groovy
@@ -38,6 +38,28 @@
   public void testIdentifierSeparator() throws Exception { doTest(); }
   public void testMethodFromAnonymousClass() throws Exception { doTest(); }
 
+  public void testAddImport() {
+    myFixture.addClass("package foo; public class Foo {}")
+    myFixture.configureByText "a.java", "import foo.F<caret>oo;"
+    performCopy();
+    myFixture.configureByText "b.java", "class Goo { <caret> }"
+    performPaste();
+    myFixture.checkResult """import foo.Foo;
+
+class Goo { Foo }"""
+
+  }
+  
+  public void testFqnInImport() {
+    myFixture.addClass("package foo; public class Foo {}")
+    myFixture.configureByText "a.java", "import foo.F<caret>oo;"
+    performCopy();
+    myFixture.configureByText "b.java", "import <caret>"
+    performPaste();
+    myFixture.checkResult """import foo.Foo<caret>"""
+
+  }
+
   public void testCopyFile() throws Exception {
     PsiFile psiFile = myFixture.addFileToProject("x/x.txt", "");
     assertTrue(CopyReferenceAction.doCopy(psiFile, getProject()));
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
index 3ed1526..95de823 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/OverrideImplementTest.java
@@ -65,6 +65,7 @@
   public void testErasureWildcard() { doTest(false); }
   public void testMultipleInterfaceInheritance() { doTest(false); }
   public void testResolveTypeParamConflict() { doTest(false); }
+  public void testRawInheritance() { doTest(false); }
 
   public void testImplementExtensionMethods() { doTest8(false, true); }
   public void testOverrideExtensionMethods() { doTest8(false, false); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
index 11cfb31..226dbfb 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/JavaAutoPopupTest.groovy
@@ -385,50 +385,64 @@
     assert !lookup
   }
 
-  void testArrow(boolean up, boolean cycleScrolling, boolean lookupAbove, int index) {
-    myFixture.configureByText("a.java", """
-    class A {
-      { ArrayIndexOutOfBoundsException <caret> }
-    }
-    """)
+  void testArrows(String toType, int indexDown, int indexUp) {
+    Closure checkArrow = { String action, int expectedIndex ->
+      myFixture.configureByText("a.java", """
+      class A {
+        void foo() {}
+        void farObject() {}
+        void fzrObject() {}
+        { <caret> }
+      }
+      """)
 
-    type 'ind'
-    assert lookup
-    assert !lookup.focused
-    assert lookup.items.size() == 2
+      type toType
+      assert lookup
+      assert !lookup.focused
 
-    lookup.positionedAbove = lookupAbove
-    UISettings.instance.CYCLE_SCROLLING = cycleScrolling
-
-    def action = up ? IdeActions.ACTION_EDITOR_MOVE_CARET_UP : IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN
-    try {
       edt { myFixture.performEditorAction(action) }
       if (lookup) {
         assert lookup.focused
-        assert index >= 0
-        assert lookup.items[index] == lookup.currentItem
+        assert expectedIndex >= 0
+        assert lookup.items[expectedIndex] == lookup.currentItem
         edt { lookup.hide() }
       } else {
-        assert index == -1
+        assert expectedIndex == -1
       }
       type '\b'
     }
+
+    checkArrow(IdeActions.ACTION_EDITOR_MOVE_CARET_UP, indexUp)
+    checkArrow(IdeActions.ACTION_EDITOR_MOVE_CARET_DOWN, indexDown)
+  }
+
+  public void "test vertical arrows in non-focused lookup"() {
+    String toType = "ArrayIndexOutOfBoundsException ind"
+    testArrows toType, 0, 1
+
+    UISettings.instance.CYCLE_SCROLLING = false
+    try {
+      testArrows toType, 0, -1
+    }
     finally {
       UISettings.instance.CYCLE_SCROLLING = true
     }
-
   }
 
-  void testArrows(boolean cycleScrolling, boolean lookupAbove, int indexDown, int indexUp) {
-    testArrow true, cycleScrolling, lookupAbove, indexUp
-    testArrow false, cycleScrolling, lookupAbove, indexDown
-  }
+  public void "test vertical arrows in semi-focused lookup"() {
+    CodeInsightSettings.instance.SELECT_AUTOPOPUP_SUGGESTIONS_BY_CHARS = false
+    UISettings.getInstance().SORT_LOOKUP_ELEMENTS_LEXICOGRAPHICALLY = true
 
-  public void testVerticalArrows() {
-    testArrows false, false, 0, -1
-    testArrows false, true, 0, -1
-    testArrows true, false, 0, 1
-    testArrows true, true, 0, 1
+    String toType = "fo"
+    testArrows toType, 2, 0
+
+    UISettings.instance.CYCLE_SCROLLING = false
+    try {
+      testArrows toType, 2, 0
+    }
+    finally {
+      UISettings.instance.CYCLE_SCROLLING = true
+    }
   }
 
   public void testHideOnOnePrefixVariant() {
@@ -517,7 +531,7 @@
     @Override
     void fillCompletionVariants(CompletionParameters parameters, CompletionResultSet result) {
       result.runRemainingContributors(parameters, true)
-      Thread.sleep 1000
+      Thread.sleep 500
     }
   }
 
@@ -634,9 +648,9 @@
   }
 
   public void testNoSingleTemplateLookup() {
-    myFixture.configureByText 'a.java', 'class Foo {{ ite<caret> }}'
-    type 'r'
-    assert !lookup
+    myFixture.configureByText 'a.java', 'class Foo { psv<caret> }'
+    type 'm'
+    assert !lookup : myFixture.lookupElementStrings
   }
 
   public void testTemplatesWithNonImportedClasses() {
@@ -666,7 +680,7 @@
 }
 """)
     type 'er '
-    assert myFixture.editor.document.text.contains('iter ')
+    assert !myFixture.editor.document.text.contains('for ')
   }
 
   public void testNewClassParenthesis() {
@@ -780,24 +794,21 @@
 
   private void joinSomething(int degree) {
     if (degree == 0) return
-    joinAlarm()
+    joinCommit()
     if (degree == 1) return
     joinCommit()
     if (degree == 2) return
-    joinCommit()
-    if (degree == 3) return
     edt {}
-    if (degree == 4) return
+    if (degree == 3) return
     joinCompletion()
   }
 
   public void testEveryPossibleWayToTypeIf() {
     def src = "class Foo { { int ifa; <caret> } }"
     def result = "class Foo { { int ifa; if <caret> } }"
-    int actions = 5
+    int actions = 4
 
     for (a1 in 0..actions) {
-      println "a1 = $a1"
       for (a2 in 0..actions) {
         myFixture.configureByText("$a1 $a2 .java", src)
         myFixture.type 'i'
@@ -1140,9 +1151,7 @@
     myFixture.addClass("package bar; public class Abcdefg {}")
     myFixture.configureByText 'a.java', 'class Foo extends <caret>'
     type 'Abcde'
-    assert lookup.items.size() == 1
-    type ' '
-    myFixture.checkResult 'class Foo extends Abcdefg <caret>'
+    assert lookup.items.size() == 2
   }
 
   public void testClassNameInProperties() {
@@ -1186,8 +1195,8 @@
   public void testAmbiguousClassQualifier() {
     myFixture.addClass("package foo; public class Util<T> { public static void foo() {}; public static final int CONSTANT = 2; }")
     myFixture.addClass("package bar; public class Util { public static void bar() {} }")
-    myFixture.configureByText 'a.java', 'class Foo {{ <caret> }}'
-    type 'Util.'
+    myFixture.configureByText 'a.java', 'class Foo {{ Util<caret> }}'
+    type '.'
     assert myFixture.lookupElementStrings == ['Util.bar', 'Util.CONSTANT', 'Util.foo']
 
     def p = LookupElementPresentation.renderElement(myFixture.lookupElements[1])
@@ -1231,7 +1240,7 @@
 }
 '''
     type 'File('
-    assert myFixture.file.text.contains('new File()')
+    assert myFixture.editor.document.text.contains('new File()')
   }
 
   public void "test inaccessible class in another package shouldn't prevent choosing by space"() {
@@ -1289,7 +1298,7 @@
     type 'System.out.pr'
     assert lookup.currentItem.lookupString == 'println'
     type '\n2'
-    assert myFixture.file.text.contains('.println();2')
+    assert myFixture.editor.document.text.contains('.println();2')
   }
 
   public void testQuickBackspaceEnter() {
@@ -1312,10 +1321,6 @@
     myTester.joinAutopopup()
   }
 
-  protected def joinAlarm() {
-    myTester.joinAlarm()
-  }
-
   public void "test new primitive array in Object variable"() {
     CodeInsightSettings.instance.COMPLETION_CASE_SENSITIVE = CodeInsightSettings.NONE
     myFixture.configureByText 'a.java', '''
@@ -1402,7 +1407,37 @@
 '''
     type 'sette'
     myFixture.assertPreferredCompletionItems 1, 'setHorizontalText', 'setText'
+    edt { myFixture.performEditorAction IdeActions.ACTION_EDITOR_MOVE_CARET_UP }
+    myFixture.assertPreferredCompletionItems 0, 'setHorizontalText', 'setText'
   }
 
+  public void "test pressing enter while autopopup is calculating variants should cancel autopopup"() {
+    registerContributor(LongContributor, LoadingOrder.FIRST)
+    myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+    myFixture.type('a')
+    joinAutopopup()
+    type('\n')
+    assert !lookup
+  }
+
+  public void "test pressing enter and a letter while autopopup is calculating variants should restart autopopup"() {
+    registerContributor(LongContributor, LoadingOrder.FIRST)
+    myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+    myFixture.type('a')
+    joinAutopopup()
+    myFixture.type('\na')
+    joinCompletion()
+    assert lookup
+  }
+
+  public void "test a random write action shouldn't cancel autopopup"() {
+    registerContributor(LongContributor, LoadingOrder.FIRST)
+    myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+    myFixture.type('a')
+    joinAutopopup()
+    edt { ApplicationManager.application.runWriteAction {} }
+    joinCompletion()
+    assert lookup
+  }
 
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
index 0ce04d2..4882f8b 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/NormalCompletionTest.groovy
@@ -536,7 +536,11 @@
   }
 
   public void testNoThisInComment() throws Throwable { doAntiTest() }
-  public void testIncNull() throws Throwable { doAntiTest() }
+  public void testIncNull() throws Throwable {
+    configure()
+    checkResultByFile(getTestName(false) + ".java")
+    assert !('null' in myFixture.lookupElementStrings)
+  }
 
   public void testLastExpressionInFor() throws Throwable { doTest(); }
 
@@ -1363,6 +1367,32 @@
 }}'''
   }
 
+  public void "test complete lowercase class name"() {
+    myFixture.addClass("package foo; public class myClass {}")
+    myFixture.configureByText "a.java", """
+class Foo extends my<caret>
+"""
+    myFixture.completeBasic()
+    myFixture.type('\n')
+    myFixture.checkResult '''import foo.myClass;
 
+class Foo extends myClass
+'''
+  }
+
+  public void "test don't show static inner class after instance qualifier"() {
+    myFixture.configureByText "a.java", """
+class Foo {
+  static class Inner {}
+}
+class Bar {
+  void foo(Foo f) {
+    f.<caret>
+  }
+}  
+"""
+    myFixture.completeBasic()
+    assert !('Inner' in myFixture.lookupElementStrings)
+  }
 
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
index a8fc06a..ed7e90d 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/SmartTypeCompletionTest.java
@@ -613,7 +613,13 @@
     configureByTestName();
     assertStringItems("byte");
     assertEquals("[]", LookupElementPresentation.renderElement(myItems[0]).getTailText());
+  }
 
+  public void testNewByteArray2() {
+    configureByTestName();
+    assertStringItems("byte", "byte");
+    assertEquals("[]", LookupElementPresentation.renderElement(myItems[0]).getTailText());
+    assertEquals("[]{...}", LookupElementPresentation.renderElement(myItems[1]).getTailText());
   }
 
   public void testInsideStringLiteral() throws Throwable { doAntiTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
index a2481a4..212ced5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/completion/TabCompletionTest.java
@@ -14,6 +14,14 @@
     checkResultByFile("MethodLookup3_After.java");
   }
 
+  public void _testMethodCallBeforeAnnotation() {
+    String name = getTestName(false);
+    myFixture.configureByFile(name + ".java");
+    myFixture.completeBasic();
+    myFixture.type("tos\t");
+    checkResultByFile(name + "_After.java");
+  }
+
   public void testReplaceThisWithSuper() throws Throwable {
     configureByFile("ReplaceThisWithSuper.java");
     checkResultByFile("ReplaceThisWithSuper_After.java");
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
index ca4c17a..dd144e5 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/GenericsHighlightingTest.java
@@ -236,6 +236,9 @@
   public void testIDEA20244() throws Exception { doTest5(false);}
   public void testIDEA22005() throws Exception { doTest5(false);}
   public void testIDEA57259() throws Exception { doTest5(false);}
+  public void testIDEA107957() throws Exception { doTest6(false);}
+  public void testIDEA106964() throws Exception { doTest5(false);}
+  public void testIDEA107782() throws Exception { doTest5(false);}
   public void testInheritedWithDifferentArgsInTypeParams() throws Exception { doTest5(false);}
   public void testIllegalForwardReferenceInTypeParameterDefinition() throws Exception { doTest5(false);}
 
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
index a66134f..9761eb4 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/ImportHelperTest.java
@@ -228,7 +228,7 @@
       ((UndoManagerImpl)UndoManager.getInstance(getProject())).clearUndoRedoQueueInTests(getFile().getVirtualFile());
       type(" ");
       backspace();
-      
+
       assertOneElement(highlightErrors());
 
       int offset = myEditor.getCaretModel().getOffset();
@@ -260,7 +260,7 @@
       ((UndoManagerImpl)UndoManager.getInstance(getProject())).clearUndoRedoQueueInTests(getFile().getVirtualFile());
       type(" ");
       backspace();
-      
+
       assertEquals(2, highlightErrors().size());
       UIUtil.dispatchAllInvocationEvents();
 
@@ -429,6 +429,30 @@
      }
    }
 
+   public void testAutoImportSkipsClassReferenceInMethodPosition() throws Throwable {
+     @NonNls String text = "package x; import java.util.HashMap; class S { HashMap<String,String> f(){ return  Hash<caret>Map <String, String >();} }  ";
+     configureByText(StdFileTypes.JAVA, text);
+
+     boolean old = CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY;
+     CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = true;
+     DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(true);
+
+     try {
+       List<HighlightInfo> errs = highlightErrors();
+       assertTrue(errs.size() > 1);
+
+       PsiJavaFile javaFile = (PsiJavaFile)getFile();
+       assertEquals(1, javaFile.getImportList().getAllImportStatements().length);
+
+       PsiReference ref = javaFile.findReferenceAt(getEditor().getCaretModel().getOffset());
+       ImportClassFix fix = new ImportClassFix((PsiJavaCodeReferenceElement)ref);
+       assertFalse(fix.isAvailable(getProject(), getEditor(), getFile()));
+     }
+     finally {
+        CodeInsightSettings.getInstance().ADD_UNAMBIGIOUS_IMPORTS_ON_THE_FLY = old;
+     }
+   }
+
    public void testAutoImportDoNotBreakCode() throws Throwable {
      @NonNls String text = "package x; class S {{ S.<caret>\n Runnable r; }}";
      configureByText(StdFileTypes.JAVA, text);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
index e77dff3..cf99110 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Interface8MethodsHighlightingTest.java
@@ -30,6 +30,7 @@
   public void testStaticMethodsInFunctionalInterface() { doTest(false, false); }
   public void testCyclicSubstitutor() { doTest(false, false); }
   public void testThisAccessibility() { doTest(false, false); }
+  public void testStaticMethodCalls() { doTest(false, false); }
 
   private void doTest() {
     doTest(false, false);
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
index fb83e99..c47059e 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/MethodRefHighlightingTest.java
@@ -78,6 +78,7 @@
   public void testGetClassSpecifics() { doTest(); }
   public void testAbstractMethod() { doTest(); }
   public void testMethodRefAcceptance() { doTest(); }
+  public void testVarargsMethodRef() { doTest(); }
 
   public void testTypeParameterWithExtendsList() throws Exception {
     doTest();
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java
new file mode 100644
index 0000000..bb5f0a2
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/lambda/Normal8CompletionTest.java
@@ -0,0 +1,42 @@
+/*
+ * 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.codeInsight.daemon.lambda;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.completion.LightFixtureCompletionTestCase;
+import com.intellij.testFramework.LightProjectDescriptor;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * User: anna
+ */
+public class Normal8CompletionTest extends LightFixtureCompletionTestCase {
+  @NotNull
+  @Override
+  protected LightProjectDescriptor getProjectDescriptor() {
+    return JAVA_LATEST;
+  }
+
+  @Override
+  protected String getBasePath() {
+    return JavaTestUtil.getRelativeJavaTestDataPath() + "/codeInsight/daemonCodeAnalyzer/lambda/completion/normal/";
+  }
+
+  public void testSelfStaticsOnly() throws Exception {
+    configureByFile("SelfStaticsOnly.java");
+    assertStringItems("ba", "bar");
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
index f285ee4..1b92a0c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/daemon/quickFix/AnnotateMethodTest.java
@@ -24,7 +24,7 @@
       protected AnnotateMethodFix createAnnotateMethodFix(String defaultNotNull, String[] annotationsToRemove) {
         return new AnnotateMethodFix(defaultNotNull, annotationsToRemove){
           @Override
-          public int annotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
+          public int shouldAnnotateBaseMethod(final PsiMethod method, final PsiMethod superMethod, final Project project) {
             @NonNls String name = method.getName();
             int ret = name.startsWith("annotateBase") ? 0  // yes, annotate all
                       : name.startsWith("dontAnnotateBase") ? 1 // do not annotate base
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java
new file mode 100644
index 0000000..e41125c
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/generation/methodsOverridingStatistics/JavaMethodsOverridingStatisticsTest.java
@@ -0,0 +1,77 @@
+package com.intellij.codeInsight.generation.methodsOverridingStatistics;
+
+import com.intellij.JavaTestUtil;
+import com.intellij.codeInsight.generation.OverrideImplementExploreUtil;
+import com.intellij.codeInsight.generation.OverrideImplementUtil;
+import com.intellij.codeInsight.generation.PsiMethodWithOverridingPercentMember;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.infos.CandidateInfo;
+import com.intellij.testFramework.fixtures.JavaCodeInsightFixtureTestCase;
+import com.intellij.util.containers.ContainerUtil;
+
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * @author Dmitry Batkovich <dmitry.batkovich@jetbrains.com>
+ */
+@SuppressWarnings("unchecked")
+public class JavaMethodsOverridingStatisticsTest extends JavaCodeInsightFixtureTestCase {
+
+  @Override
+  protected String getTestDataPath() {
+    return JavaTestUtil.getJavaTestDataPath() + "/codeInsight/generation/javaMethodsOverridingStatistics/";
+  }
+
+  public void testMethods() {
+    doTest(1, pair("method", 100));
+  }
+
+  public void testMethods2() {
+    doTest(2, pair("method", 50), pair("method", 100));
+  }
+
+  public void testMethods3() {
+    doTest(1, pair("method2", 100));
+  }
+
+  public void testMethods4() {
+    doTest(2, pair("method2", 100), pair("method", 50));
+  }
+
+  public void testMethods5() {
+    doTest(3, pair("method", 100), pair("method2", 100), pair("method", 33));
+  }
+
+  private void doTest(final int resultSize, final Pair<String, Integer>... expectedValues) {
+    myFixture.configureByFile(getTestName(false) + ".java");
+
+    final PsiClass contextClass =
+      OverrideImplementUtil.getContextClass(myFixture.getProject(), myFixture.getEditor(), myFixture.getFile(), true);
+    assert contextClass != null;
+
+    if (OverrideImplementExploreUtil.getMethodSignaturesToOverride(contextClass).isEmpty() && expectedValues.length != 0) {
+      fail();
+    }
+
+    final Collection<CandidateInfo> candidateInfos = OverrideImplementExploreUtil.getMethodsToOverrideImplement(contextClass, false);
+    final PsiMethodWithOverridingPercentMember[] searchResults = PsiMethodWithOverridingPercentMember
+      .calculateOverridingPercents(candidateInfos);
+    assertSize(resultSize, searchResults);
+
+    final Set<Pair<String, Integer>> actualValues = new HashSet<Pair<String, Integer>>();
+    for (PsiMethodWithOverridingPercentMember searchResult : searchResults) {
+      actualValues.add(Pair.<String, Integer>create(searchResult.getElement().getName(), searchResult.getOverridingPercent()));
+    }
+
+    final Set<Pair<String, Integer>> expectedValuesSet = ContainerUtil.newHashSet(expectedValues);
+
+    assertEquals(expectedValuesSet, actualValues);
+  }
+
+  private static Pair<String, Integer> pair(final String methodName, final int percent) {
+    return Pair.create(methodName, percent);
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
index 9fefc23..28644e9 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/javadoc/JavaDocInfoGeneratorTest.java
@@ -64,6 +64,10 @@
     doTestField();
   }
 
+  public void testLiteral() throws Exception {
+    doTestField();
+  }
+
   public void testEnumConstantOrdinal() throws Exception {
     PsiClass psiClass = getTestClass();
     PsiField field = psiClass.getFields() [0];
diff --git a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
index 372c180..af208b0 100644
--- a/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/codeInsight/template/LiveTemplateTest.groovy
@@ -540,4 +540,15 @@
     }
   }
 
+  public void "test expand current live template on no suggestions in lookup"() {
+    myFixture.configureByText "a.java", "class Foo {{ <caret> }}"
+    myFixture.completeBasic()
+    assert myFixture.lookup
+    myFixture.type("sout")
+    assert myFixture.lookup
+    assert myFixture.lookupElementStrings == []
+    myFixture.type('\t')
+    myFixture.checkResult "class Foo {{\n    System.out.println(<caret>); }}"
+  }
+
 }
diff --git a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
index 82650d6..fc5824c 100644
--- a/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
+++ b/java/java-tests/testSrc/com/intellij/codeInspection/DataFlowInspectionTest.java
@@ -68,7 +68,9 @@
   public void testIDEA84489() throws Throwable { doTest(); }
   public void testComparingToNotNullShouldNotAffectNullity() throws Throwable { doTest(); }
   public void testStringTernaryAlwaysTrue() throws Throwable { doTest(); }
+  public void testStringConcatAlwaysNotNull() throws Throwable { doTest(); }
 
+  public void testNotNullPrimitive() throws Throwable { doTest(); }
   public void testBoxing128() throws Throwable { doTest(); }
   public void testFinalFieldsInitializedByAnnotatedParameters() throws Throwable { doTest(); }
   public void testMultiCatch() throws Throwable { doTest(); }
@@ -147,6 +149,7 @@
   public void testMutableVolatileNullableFieldsTreatment() { doTest(); }
   public void testMutableNotAnnotatedFieldsTreatment() { doTest(); }
   public void testSuperCallMayChangeFields() { doTest(); }
+  public void testOtherCallMayChangeFields() { doTest(); }
 
   public void testMethodCallFlushesField() { doTest(); }
   public void testUnknownFloatMayBeNaN() { doTest(); }
diff --git a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
index abbb152..75c7bf1 100644
--- a/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
+++ b/java/java-tests/testSrc/com/intellij/ide/fileStructure/JavaFileStructureFilteringTest.java
@@ -38,10 +38,10 @@
   public void testSelectLeafFirst3()  throws Exception {checkTree("clear");}
   public void testSelectLeafFirst4()  throws Exception {checkTree("clear");}
 
-  @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+  @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
   public void testMatcher1()          throws Exception {checkTree("ico");}
-  @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+  @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
   public void testMatcher2()          throws Exception {checkTree("ico");}
-  @Bombed(user = "peter", month = Calendar.MAY, day = 10)
+  @Bombed(user = "peter", month = Calendar.JUNE, day = 10)
   public void testAnonymousMatcher2() throws Exception {checkTree("ico");}
 }
diff --git a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
index 14c2e29..0217607 100644
--- a/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/ClsMirrorBuildingTest.java
@@ -42,6 +42,7 @@
   public void testEA40568() { doTest(); }
   public void testBooleans() { doTest(); }
   public void testClassRefs() { doTest(); }
+  public void testEA46236() { doTest("ValuedEnum"); }
 
   private void doTest() {
     doTest(getTestName(false));
diff --git a/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy
new file mode 100644
index 0000000..024f0cd
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/psi/codeStyle/arrangement/JavaRearrangerSpecialRuleTest.groovy
@@ -0,0 +1,115 @@
+/*
+ * 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.psi.codeStyle.arrangement
+
+import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Modifier.*
+import static com.intellij.psi.codeStyle.arrangement.std.StdArrangementTokens.Order.BY_NAME
+
+import org.junit.Before
+
+/**
+ * @author Svetlana.Zemlyanskaya
+ */
+
+class JavaRearrangerSpecialRuleTest extends AbstractJavaRearrangerTest {
+
+  @Before
+  void setUp() {
+    super.setUp()
+    commonSettings.BLANK_LINES_AROUND_METHOD = 0
+    commonSettings.BLANK_LINES_AROUND_CLASS = 0
+  }
+
+  void "test name and visibility conditions"() {
+    doTest(
+      initial: '''\
+class Test {
+  public void getI() {}
+  public void setI() {}
+  private void test() {}
+}''',
+      expected: '''\
+class Test {
+  public void setI() {}
+  public void getI() {}
+  private void test() {}
+}''',
+      rules: [rule(PUBLIC), nameRule("get.*", PUBLIC)]
+    )
+  }
+
+  void "test modifier conditions"() {
+    doTest(
+      initial: '''\
+class Test {
+  public static void a() {}
+  public voic b() {}
+}
+''',
+      expected: '''\
+class Test {
+  public voic b() {}
+  public static void a() {}
+}
+''',
+      rules: [rule(PUBLIC), rule(PUBLIC, STATIC)]
+    )
+  }
+
+  void "test multi modifier condition"() {
+    doTest(
+      initial: '''\
+class Test {
+  public abstract void a() {}
+  public static void b() {}
+  public voic c() {}
+}
+''',
+      expected: '''\
+class Test {
+  public voic c() {}
+  public static void b() {}
+  public abstract void a() {}
+}
+''',
+      rules: [rule(PUBLIC), rule(PUBLIC, STATIC), rule(PUBLIC, ABSTRACT)]
+    )
+  }
+
+  void "test modifier conditions with sort"() {
+    doTest(
+      initial: '''\
+class Test {
+  public void e() {}
+  public static void d() {}
+  public void c() {}
+  public static void b() {}
+  public void a() {}
+}
+''',
+      expected: '''\
+class Test {
+  public void a() {}
+  public void c() {}
+  public void e() {}
+  public static void b() {}
+  public static void d() {}
+}
+''',
+      rules: [ruleWithOrder(BY_NAME, rule(PUBLIC)), ruleWithOrder(BY_NAME, rule(PUBLIC, STATIC))]
+    )
+  }
+}
diff --git a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
index 2cb329b..5fa7fa8 100644
--- a/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
+++ b/java/java-tests/testSrc/com/intellij/psi/impl/source/tree/java/JavadocParamTagsTest.java
@@ -1,6 +1,6 @@
 package com.intellij.psi.impl.source.tree.java;
 
-import com.intellij.codeInsight.CodeInsightUtilBase;
+import com.intellij.codeInsight.CodeInsightUtilCore;
 import com.intellij.openapi.application.ApplicationManager;
 import com.intellij.openapi.command.CommandProcessor;
 import com.intellij.psi.*;
@@ -163,7 +163,7 @@
             final PsiDocTag[] tags = docComment.getTags();
             final PsiDocTag tag2 = factory.createParamTag("p2", "");
             docComment.addAfter(tag2, tags[0]);
-            docComment = CodeInsightUtilBase.forcePsiPostprocessAndRestoreElement(docComment);
+            docComment = CodeInsightUtilCore.forcePsiPostprocessAndRestoreElement(docComment);
             assertEquals(
               "/**\n" +
               " * Javadoc\n" +
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
index 3191c09..3639cbd 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/ExtractMethodTest.java
@@ -583,6 +583,10 @@
     doDuplicatesTest();
   }
 
+  public void testTargetAnonymous() throws Exception {
+    doTest();
+  }
+
   private void doTestDisabledParam() throws PrepareFailedException {
     final CodeStyleSettings settings = CodeStyleSettingsManager.getSettings(getProject());
     settings.ELSE_ON_NEW_LINE = true;
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
index bd70e5d..905f87e 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/IntroduceParameterObjectTest.java
@@ -27,7 +27,7 @@
 import com.intellij.psi.*;
 import com.intellij.psi.search.GlobalSearchScope;
 import com.intellij.refactoring.introduceparameterobject.IntroduceParameterObjectProcessor;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.util.Function;
 import com.intellij.util.VisibilityUtil;
 
@@ -46,9 +46,9 @@
   }
 
   private void doTest(final boolean delegate, final boolean createInner) throws Exception {
-    doTest(delegate, createInner, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+    doTest(delegate, createInner, new Function<PsiMethod, VariableData[]>() {
       @Override
-      public ParameterTablePanel.VariableData[] fun(PsiMethod psiMethod) {
+      public VariableData[] fun(PsiMethod psiMethod) {
         return generateParams(psiMethod);
       }
     });
@@ -56,7 +56,7 @@
 
   private void doTest(final boolean delegate,
                       final boolean createInner,
-                      final Function<PsiMethod, ParameterTablePanel.VariableData[]> function) throws Exception {
+                      final Function<PsiMethod, VariableData[]> function) throws Exception {
     doTest(new PerformAction() {
       @Override
       public void performAction(final VirtualFile rootDir, final VirtualFile rootAfter) throws Exception {
@@ -65,7 +65,7 @@
         assertNotNull("Class Test not found", aClass);
 
         final PsiMethod method = aClass.findMethodsByName("foo", false)[0];
-        final ParameterTablePanel.VariableData[] datas = function.fun(method);
+        final VariableData[] datas = function.fun(method);
 
         IntroduceParameterObjectProcessor processor = new IntroduceParameterObjectProcessor("Param", "", null, method, datas, delegate, false,
                                                                                             createInner, null, false);
@@ -74,13 +74,13 @@
     });
   }
 
-  private static ParameterTablePanel.VariableData[] generateParams(final PsiMethod method) {
+  private static VariableData[] generateParams(final PsiMethod method) {
     final PsiParameter[] parameters = method.getParameterList().getParameters();
 
-    final ParameterTablePanel.VariableData[] datas = new ParameterTablePanel.VariableData[parameters.length];
+    final VariableData[] datas = new VariableData[parameters.length];
     for (int i = 0; i < parameters.length; i++) {
       PsiParameter parameter = parameters[i];
-      datas[i] = new ParameterTablePanel.VariableData(parameter);
+      datas[i] = new VariableData(parameter);
       datas[i].name = parameter.getName();
       datas[i].passAsParameter = true;
     }
@@ -132,15 +132,33 @@
   }
 
   public void testSameTypeAndVarargs() throws Exception {
-    doTest(false, false, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+    doTest(false, false, new Function<PsiMethod, VariableData[]>() {
       @Override
-      public ParameterTablePanel.VariableData[] fun(PsiMethod method) {
+      public VariableData[] fun(PsiMethod method) {
         final PsiParameter[] parameters = method.getParameterList().getParameters();
 
-        final ParameterTablePanel.VariableData[] datas = new ParameterTablePanel.VariableData[parameters.length - 1];
+        final VariableData[] datas = new VariableData[parameters.length - 1];
         for (int i = 0; i < parameters.length - 1; i++) {
           PsiParameter parameter = parameters[i];
-          datas[i] = new ParameterTablePanel.VariableData(parameter);
+          datas[i] = new VariableData(parameter);
+          datas[i].name = parameter.getName();
+          datas[i].passAsParameter = true;
+        }
+        return datas;
+      }
+    });
+  }
+
+  public void testCopyJavadoc1() throws Exception {
+    doTest(false, true, new Function<PsiMethod, VariableData[]>() {
+      @Override
+      public VariableData[] fun(PsiMethod method) {
+        final PsiParameter[] parameters = method.getParameterList().getParameters();
+
+        final VariableData[] datas = new VariableData[parameters.length - 1];
+        for (int i = 0; i < parameters.length - 1; i++) {
+          PsiParameter parameter = parameters[i];
+          datas[i] = new VariableData(parameter);
           datas[i].name = parameter.getName();
           datas[i].passAsParameter = true;
         }
@@ -150,16 +168,16 @@
   }
 
   public void testTypeParametersWithChosenSubtype() throws Exception {
-    doTest(false, true, new Function<PsiMethod, ParameterTablePanel.VariableData[]>() {
+    doTest(false, true, new Function<PsiMethod, VariableData[]>() {
       @Override
-      public ParameterTablePanel.VariableData[] fun(PsiMethod psiMethod) {
+      public VariableData[] fun(PsiMethod psiMethod) {
         final PsiParameter parameter = psiMethod.getParameterList().getParameters()[0];
         final PsiClass collectionClass = getJavaFacade().findClass(CommonClassNames.JAVA_UTIL_COLLECTION);
-        final ParameterTablePanel.VariableData variableData =
-          new ParameterTablePanel.VariableData(parameter, JavaPsiFacade.getElementFactory(getProject()).createType(collectionClass));
+        final VariableData variableData =
+          new VariableData(parameter, JavaPsiFacade.getElementFactory(getProject()).createType(collectionClass));
         variableData.name = parameter.getName();
         variableData.passAsParameter = true;
-        return new ParameterTablePanel.VariableData[]{variableData};
+        return new VariableData[]{variableData};
       }
     });
   }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
index af309f3..e8121b1 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MakeClassStaticTest.java
@@ -12,7 +12,7 @@
 import com.intellij.refactoring.makeStatic.MakeClassStaticProcessor;
 import com.intellij.refactoring.makeStatic.MakeStaticUtil;
 import com.intellij.refactoring.makeStatic.Settings;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
@@ -83,7 +83,7 @@
     PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
     assertTrue(element instanceof PsiClass);
     PsiClass aClass = (PsiClass)element;
-    final ArrayList<ParameterTablePanel.VariableData> parametersForFields = new ArrayList<ParameterTablePanel.VariableData>();
+    final ArrayList<VariableData> parametersForFields = new ArrayList<VariableData>();
     final boolean addClassParameter = MakeStaticUtil.buildVariableData(aClass, parametersForFields);
 
     new MakeClassStaticProcessor(
@@ -91,7 +91,7 @@
             aClass,
             new Settings(true, addClassParameter ? "anObject" : null,
                          parametersForFields.toArray(
-                           new ParameterTablePanel.VariableData[parametersForFields.size()]))).run();
+                           new VariableData[parametersForFields.size()]))).run();
     checkResultByFile(TEST_ROOT + getTestName(false) + "_after.java");
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java b/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
index db89b94..0ef8510 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/MakeMethodStaticTest.java
@@ -22,7 +22,7 @@
 import com.intellij.refactoring.makeStatic.MakeMethodStaticProcessor;
 import com.intellij.refactoring.makeStatic.MakeStaticUtil;
 import com.intellij.refactoring.makeStatic.Settings;
-import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import org.jetbrains.annotations.NotNull;
 
 import java.util.ArrayList;
@@ -176,7 +176,7 @@
     configureByFile("/refactoring/makeMethodStatic/beforePreserveTypeParams.java");
     performWithFields();
     checkResultByFile("/refactoring/makeMethodStatic/afterPreserveTypeParams.java");
-  } 
+  }
 
   public void testInnerStaticClassUsed() throws Exception {
     configureByFile("/refactoring/makeMethodStatic/beforeInnerStaticClassUsed.java");
@@ -218,7 +218,7 @@
     PsiElement element = TargetElementUtilBase.findTargetElement(myEditor, TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
     assertTrue(element instanceof PsiMethod);
     PsiMethod method = (PsiMethod) element;
-    final ArrayList<ParameterTablePanel.VariableData> parametersForFields = new ArrayList<ParameterTablePanel.VariableData>();
+    final ArrayList<VariableData> parametersForFields = new ArrayList<VariableData>();
     final boolean addClassParameter = MakeStaticUtil.buildVariableData(method, parametersForFields);
 
     new MakeMethodStaticProcessor(
@@ -226,6 +226,6 @@
             method,
             new Settings(true, addClassParameter ? "anObject" : null,
                          parametersForFields.toArray(
-                           new ParameterTablePanel.VariableData[parametersForFields.size()]))).run();
+                           new VariableData[parametersForFields.size()]))).run();
   }
 }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy b/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
index 401de72..7794c69 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameDirectoryTest.groovy
@@ -26,12 +26,12 @@
   public void testRenameSrcRootWithTextOccurrences() {
     VirtualFile srcRoot = myFixture.tempDirFixture.findOrCreateDir("")
 
-    def fooClass = myFixture.addClass """
+    def fooClass = myFixture.addClass("""
 // PsiPackage:
 class Foo {
   String s1 = "PsiPackage:"
 }
-"""
+""")
     myFixture.configureFromExistingVirtualFile(fooClass.containingFile.virtualFile)
 
     new RenameProcessor(getProject(), psiManager.findDirectory(srcRoot), "newName", true, true).run();
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
index 314f6ed..f72add5 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/RenameMembersInplaceTest.java
@@ -40,6 +40,10 @@
     doTestInplaceRename("NEW_NAME");
   }
   
+  public void testIncomplete() throws Exception {
+    doTestInplaceRename("Klazz");
+  }
+  
   public void testConstructor() throws Exception {
     doTestInplaceRename("Bar");
   }
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
index 44f927f..0cf3fc3 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/SafeDeleteTest.java
@@ -127,6 +127,10 @@
     doTest("Super");
   }
 
+  public void testInterfaceAsTypeParameterBound() throws Exception {
+    doSingleFileTest();   
+  }
+
   public void testLocalVariableSideEffect() throws Exception {
     myDoCompare = false;
     try {
diff --git a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
index 28f0935..57582d5 100644
--- a/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
+++ b/java/java-tests/testSrc/com/intellij/refactoring/SuggestedParamTypesTest.java
@@ -31,6 +31,7 @@
 import com.intellij.refactoring.ui.TypeSelectorManager;
 import com.intellij.refactoring.ui.TypeSelectorManagerImpl;
 import com.intellij.refactoring.util.ParameterTablePanel;
+import com.intellij.refactoring.util.VariableData;
 import com.intellij.testFramework.LightCodeInsightTestCase;
 import org.jetbrains.annotations.NonNls;
 import org.jetbrains.annotations.NotNull;
@@ -110,7 +111,7 @@
 
     processor.prepare();
 
-    for (final ParameterTablePanel.VariableData data : processor.getInputVariables().getInputVariables()) {
+    for (final VariableData data : processor.getInputVariables().getInputVariables()) {
       final PsiExpression[] occurrences = ParameterTablePanel.findVariableOccurrences(elements, data.variable);
       final TypeSelectorManager manager = new TypeSelectorManagerImpl(project, data.type, occurrences, true) {
         @Override
diff --git a/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java b/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java
new file mode 100644
index 0000000..426afcb
--- /dev/null
+++ b/java/java-tests/testSrc/com/intellij/util/indexing/FileBasedIndexTest.java
@@ -0,0 +1,18 @@
+package com.intellij.util.indexing;
+
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 5/23/13
+ */
+public class FileBasedIndexTest extends LightCodeInsightFixtureTestCase {
+
+  public void testSurviveOnFileTypeChange() throws Exception {
+    myFixture.configureByText("Foo.java", "class Foo { String bar; }");
+    myFixture.testHighlighting();
+    FileTypeIndexTest.addAndRemoveFileType();
+    myFixture.configureByText("Bar.java", "class Bar { String bar; }");
+    myFixture.testHighlighting();
+  }
+}
diff --git a/java/jdkAnnotations/java/io/annotations.xml b/java/jdkAnnotations/java/io/annotations.xml
index 955ece0..df2f353 100644
--- a/java/jdkAnnotations/java/io/annotations.xml
+++ b/java/jdkAnnotations/java/io/annotations.xml
@@ -1,5 +1,44 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <root>
+  <item name="java.io.BufferedInputStream BufferedInputStream(java.io.InputStream) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedInputStream BufferedInputStream(java.io.InputStream, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedInputStream int read(byte[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedOutputStream BufferedOutputStream(java.io.OutputStream) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedOutputStream BufferedOutputStream(java.io.OutputStream, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedOutputStream void write(byte[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedReader BufferedReader(java.io.Reader) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedReader BufferedReader(java.io.Reader, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedReader int read(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedWriter BufferedWriter(java.io.Writer) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedWriter BufferedWriter(java.io.Writer, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedWriter void write(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.BufferedWriter void write(java.lang.String, int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.io.DataInput java.lang.String readUTF()">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
@@ -83,14 +122,131 @@
   <item name="java.io.File java.nio.file.Path toPath()">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
+  <item name="java.io.FileOutputStream FileOutputStream(java.io.File) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream FileOutputStream(java.io.File, boolean) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream FileOutputStream(java.io.FileDescriptor) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream FileOutputStream(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream FileOutputStream(java.lang.String, boolean) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream java.io.FileDescriptor getFD()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream java.nio.channels.FileChannel getChannel()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream void write(byte[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FileOutputStream void write(byte[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.io.FilterInputStream FilterInputStream(java.io.InputStream) 0">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
+  <item name="java.io.FilterInputStream int read(byte[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FilterInputStream int read(byte[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FilterOutputStream FilterOutputStream(java.io.OutputStream) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FilterOutputStream void write(byte[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FilterOutputStream void write(byte[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.FilterReader FilterReader(java.io.Reader) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.InputStream int read(byte[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.io.InputStream int read(byte[], int, int) 0">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.lang.String) 1">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.Charset) 1">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter OutputStreamWriter(java.io.OutputStream, java.nio.charset.CharsetEncoder) 1">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter void write(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.OutputStreamWriter void write(java.lang.String, int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.io.RandomAccessFile RandomAccessFile(java.io.File, java.lang.String) 1">
     <annotation name="org.jetbrains.annotations.NonNls" />
   </item>
+  <item name="java.io.Reader Reader(java.lang.Object) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Reader int read(char[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Reader int read(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Reader int read(java.nio.CharBuffer) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.StringReader StringReader(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.StringReader int read(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.StringWriter void write(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.StringWriter void write(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.StringWriter void write(java.lang.String, int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Writer Writer(java.lang.Object) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Writer void write(char[]) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Writer void write(char[], int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Writer void write(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.io.Writer void write(java.lang.String, int, int) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
 </root>
 
diff --git a/java/jdkAnnotations/java/lang/annotations.xml b/java/jdkAnnotations/java/lang/annotations.xml
index 4337ee6..bb5f521 100644
--- a/java/jdkAnnotations/java/lang/annotations.xml
+++ b/java/jdkAnnotations/java/lang/annotations.xml
@@ -11,6 +11,9 @@
   <item name="java.lang.Class java.lang.Class&lt;?&gt; forName(java.lang.String) 0">
     <annotation name="org.jetbrains.annotations.NonNls" />
   </item>
+  <item name="java.lang.Class java.lang.Class&lt;?&gt; forName(java.lang.String, boolean, java.lang.ClassLoader) 0">
+    <annotation name="org.jetbrains.annotations.NonNls" />
+  </item>
   <item name="java.lang.Class java.lang.reflect.Field getDeclaredField(java.lang.String) 0">
     <annotation name="org.jetbrains.annotations.NonNls" />
   </item>
@@ -44,6 +47,9 @@
   <item name="java.lang.Iterable Iterator&lt;T&gt; iterator()">
     <annotation name="org.jetbrains.annotations.NotNull" />
   </item>
+  <item name="java.lang.Readable int read(java.nio.CharBuffer) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.lang.Runtime Process exec(java.lang.String[]) 0">
     <annotation name="org.jetbrains.annotations.NonNls" />
   </item>
diff --git a/java/jdkAnnotations/java/net/annotations.xml b/java/jdkAnnotations/java/net/annotations.xml
index ccc7e16..0fb0120 100644
--- a/java/jdkAnnotations/java/net/annotations.xml
+++ b/java/jdkAnnotations/java/net/annotations.xml
@@ -1,5 +1,38 @@
 <?xml version="1.0" encoding="UTF-8"?>
 <root>
+  <item name="java.net.URI URI(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI create(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI normalize()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI parseServerAuthority()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI relativize(java.net.URI)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI relativize(java.net.URI) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI resolve(java.lang.String)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI resolve(java.lang.String) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI resolve(java.net.URI)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URI resolve(java.net.URI) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.net.URI java.net.URL toURL()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
   <item name="java.net.URL URL(java.lang.String) 0">
     <annotation name="org.jetbrains.annotations.NonNls" />
   </item>
diff --git a/java/jdkAnnotations/java/nio/annotations.xml b/java/jdkAnnotations/java/nio/annotations.xml
new file mode 100644
index 0000000..59c7057
--- /dev/null
+++ b/java/jdkAnnotations/java/nio/annotations.xml
@@ -0,0 +1,76 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<root>
+  <item name="java.nio.ByteBuffer byte[] array()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer compact()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer order(java.nio.ByteOrder)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer order(java.nio.ByteOrder) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putChar(char)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putChar(int, char)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putDouble(double)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putDouble(int, double)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putFloat(float)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putFloat(int, float)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putInt(int)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putInt(int, int)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putLong(int, long)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putLong(long)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putShort(int, short)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteBuffer putShort(short)">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ByteOrder order()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.CharBuffer asCharBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.DoubleBuffer asDoubleBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.FloatBuffer asFloatBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.IntBuffer asIntBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.LongBuffer asLongBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.ByteBuffer java.nio.ShortBuffer asShortBuffer()">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+  <item name="java.nio.CharBuffer int read(java.nio.CharBuffer) 0">
+    <annotation name="org.jetbrains.annotations.NotNull" />
+  </item>
+</root>
+
diff --git a/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java b/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
index c889ede..228d072 100644
--- a/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
+++ b/java/jsp-openapi/src/com/intellij/psi/impl/source/jsp/jspJava/JspTemplateStatement.java
@@ -15,10 +15,10 @@
  */
 package com.intellij.psi.impl.source.jsp.jspJava;
 
-import com.intellij.psi.PsiStatement;
+import com.intellij.psi.PsiTemplateStatement;
 
 /**
  * @author peter
  */
-public interface JspTemplateStatement extends PsiStatement {
+public interface JspTemplateStatement extends PsiTemplateStatement {
 }
diff --git a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
index e06b22a..7e350d9 100644
--- a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
+++ b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
@@ -68,7 +68,11 @@
       if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
         PsiExpression operand = expression.getOperand();
         if (operand instanceof PsiParenthesizedExpression) {
-          operand = ((PsiParenthesizedExpression)operand).getExpression();
+          final PsiElement parent = booleanExpression.getParent();
+          if (parent instanceof PsiPolyadicExpression && 
+              ((PsiPolyadicExpression)parent).getOperationTokenType() == JavaTokenType.ANDAND) {
+            operand = ((PsiParenthesizedExpression)operand).getExpression();
+          }
         }
         return operand;
       }
diff --git a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
index 87ad87d..5dca4c3 100644
--- a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
+++ b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -16,6 +16,7 @@
 package com.intellij.codeInsight.intention;
 
 import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.codeInspection.LocalQuickFixOnPsiElement;
 import com.intellij.openapi.components.ServiceManager;
 import com.intellij.psi.*;
 import com.intellij.psi.util.PropertyMemberType;
@@ -48,7 +49,7 @@
    */
   public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiElement psiElement);
   public abstract LocalQuickFixAndIntentionActionOnPsiElement createImplementMethodsFix(@NotNull PsiClass psiElement);
-  public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
+  public abstract LocalQuickFixOnPsiElement createMethodThrowsFix(@NotNull PsiMethod method, @NotNull PsiClassType exceptionClass, boolean shouldThrow, boolean showContainingClass);
   public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddDefaultConstructorFix(@NotNull PsiClass aClass);
   @Nullable
   public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant String modifier);
diff --git a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
index df9cfdd..5e12940 100644
--- a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
+++ b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
@@ -30,7 +30,6 @@
 import org.jetbrains.annotations.NotNull;
 
 public abstract class SuppressManager implements BatchSuppressManager {
-  public static final String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
 
   public static SuppressManager getInstance() {
     return ServiceManager.getService(SuppressManager.class);
diff --git a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
index 1fa919b..39028e7 100644
--- a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
+++ b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
@@ -1,5 +1,5 @@
 /*
- * Copyright 2000-2009 JetBrains s.r.o.
+ * 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.
@@ -15,43 +15,26 @@
  */
 package com.intellij.openapi.module;
 
-import com.intellij.openapi.projectRoots.JavaSdk;
-import com.intellij.openapi.projectRoots.JavaSdkVersion;
 import com.intellij.openapi.vfs.VirtualFile;
 import com.intellij.pom.java.LanguageLevel;
 import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
 
 /**
  * @author yole
  */
 public class LanguageLevelUtil extends EffectiveLanguageLevelUtil {
-  private LanguageLevelUtil() {
-  }
+  private LanguageLevelUtil() { }
 
   @NotNull
-  public static LanguageLevel getLanguageLevelForFile(final VirtualFile file) {
+  public static LanguageLevel getLanguageLevelForFile(@Nullable VirtualFile file) {
     if (file == null) return LanguageLevel.HIGHEST;
 
     if (file.isDirectory()) {
-      final LanguageLevel ll = file.getUserData(LanguageLevel.KEY);
-      return ll != null ? ll : LanguageLevel.HIGHEST;
+      LanguageLevel languageLevel = file.getUserData(LanguageLevel.KEY);
+      return languageLevel != null ? languageLevel : LanguageLevel.HIGHEST;
     }
 
     return getLanguageLevelForFile(file.getParent());
   }
-
-  /**
-   * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#getMaxLanguageLevel()} instead
-   */
-  public static LanguageLevel getDefaultLanguageLevel(@NotNull String versionString) {
-    JavaSdkVersion version = JavaSdk.getInstance().getVersion(versionString);
-    return version != null ? version.getMaxLanguageLevel() : LanguageLevel.JDK_1_3;
-  }
-
-  /**
-   * @deprecated use {@link com.intellij.openapi.projectRoots.JavaSdkVersion#isAtLeast(com.intellij.openapi.projectRoots.JavaSdkVersion)} instead
-   */
-  public static boolean isOfVersionOrHigher(@NotNull String versionString, String checkedVersion) {
-    return JavaSdk.getInstance().compareTo(versionString, checkedVersion) >= 0;
-  }
 }
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
index e91eb87..e72731b 100644
--- a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
@@ -24,7 +24,7 @@
  * @author peter
  */
 public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElementPattern<T,Self>> extends PsiElementPattern<T,Self> {
-  private static final @NonNls String VALUE = "value";
+  @NonNls private static final String VALUE = "value";
 
   public PsiJavaElementPattern(final Class<T> aClass) {
     super(aClass);
@@ -61,11 +61,12 @@
   }
 
   public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
-    return nameIdentifierOf(PsiJavaPatterns.instanceOf(aClass));
+    return nameIdentifierOf(StandardPatterns.instanceOf(aClass));
   }
-  
+
   public Self nameIdentifierOf(final ElementPattern<? extends PsiMember> pattern) {
     return with(new PatternCondition<T>("nameIdentifierOf") {
+      @Override
       public boolean accepts(@NotNull final T t, final ProcessingContext context) {
         if (!(t instanceof PsiIdentifier)) return false;
 
@@ -81,6 +82,7 @@
 
   public Self methodCallParameter(final int index, final ElementPattern<? extends PsiMethod> methodPattern) {
     return with(new PatternCondition<T>("methodCallParameter") {
+      @Override
       public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
         final PsiElement parent = literal.getParent();
         if (parent instanceof PsiExpressionList) {
@@ -106,6 +108,7 @@
 
   public Self constructorParameter(final int index, final String... fqns) {
     return with(new PatternCondition<T>("methodCallParameter") {
+      @Override
       public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
         final PsiElement parent = literal.getParent();
         if (parent instanceof PsiExpressionList) {
diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
index fa8b3fa..ebefeef 100644
--- a/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
@@ -72,8 +72,12 @@
   }
 
   @Override
-  public boolean contains(VirtualFile file, NamedScopesHolder holder) {
-    Project project = holder.getProject();
+  public boolean contains(VirtualFile file, @NotNull NamedScopesHolder holder) {
+    return contains(file, holder.getProject(), holder);
+  }
+
+  @Override
+  public boolean contains(VirtualFile file, @NotNull Project project, @Nullable NamedScopesHolder holder) {
     ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
     return matchesScope(file, holder.getProject(), fileIndex) && (myPattern == null || myPattern.matcher(getPackageName(file, fileIndex)).matches());
   }
diff --git a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
index 23a63e6..f899cc1 100644
--- a/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
+++ b/java/testFramework/src/com/intellij/testFramework/CompilerTester.java
@@ -124,7 +124,7 @@
     path.getChildren();
     assert path != null;
     path.refresh(false, true);
-    return path.findChild(className + ".class");
+    return path.findChild(className.replace('.', '/') + ".class");
   }
 
   public void touch(VirtualFile file) throws IOException {
diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml
index 408e30d..9d48d3d 100644
--- a/java/testFramework/testFramework-java.iml
+++ b/java/testFramework/testFramework-java.iml
@@ -21,6 +21,7 @@
     <orderEntry type="module" module-name="testFramework" exported="" />
     <orderEntry type="module" module-name="relaxng" exported="" scope="TEST" />
     <orderEntry type="module" module-name="idea-ui" exported="" />
+    <orderEntry type="module" module-name="external-system-impl" exported="" scope="TEST" />
   </component>
   <component name="copyright">
     <Base>