Snapshot of commit d5ec1d5018ed24f1b4f32b1d09df6dbd7e2fc425

from branch master of git://git.jetbrains.org/idea/community.git
diff --git a/java/openapi/openapi.iml b/java/openapi/openapi.iml
new file mode 100644
index 0000000..0f0db7c
--- /dev/null
+++ b/java/openapi/openapi.iml
@@ -0,0 +1,36 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="util" exported="" />
+    <orderEntry type="library" scope="TEST" name="JUnit4" level="project" />
+    <orderEntry type="library" name="JDOM" level="project" />
+    <orderEntry type="module" module-name="forms_rt" />
+    <orderEntry type="library" name="Trove4j" level="project" />
+    <orderEntry type="module" module-name="extensions" exported="" />
+    <orderEntry type="module" module-name="icons" />
+    <orderEntry type="library" exported="" name="NanoXML" level="project" />
+    <orderEntry type="library" exported="" name="microba" level="project" />
+    <orderEntry type="library" name="jgoodies-forms" level="project" />
+    <orderEntry type="module" module-name="xml-openapi" exported="" />
+    <orderEntry type="module" module-name="platform-api" exported="" />
+    <orderEntry type="module" module-name="lang-api" exported="" />
+    <orderEntry type="module" module-name="vcs-api" exported="" />
+    <orderEntry type="library" name="XmlRPC" level="project" />
+    <orderEntry type="module" module-name="dom-openapi" />
+    <orderEntry type="module" module-name="resources-en" exported="" />
+    <orderEntry type="module" module-name="java-psi-api" exported="" />
+    <orderEntry type="module" module-name="java-indexing-api" exported="" />
+  </component>
+  <component name="copyright">
+    <option name="body" value="/*&#10; * Copyright (c) $today.year Your Corporation. All Rights Reserved.&#10; */" />
+    <option name="location" value="1" />
+    <option name="remove" value="true" />
+  </component>
+</module>
+
diff --git a/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java
new file mode 100644
index 0000000..2bfdbb1
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/AttachSourcesProvider.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.util.ActionCallback;
+import com.intellij.psi.PsiFile;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Collection;
+import java.util.List;
+
+public interface AttachSourcesProvider {
+  @NotNull
+  Collection<AttachSourcesAction> getActions(List<LibraryOrderEntry> orderEntries, PsiFile psiFile);
+
+  interface AttachSourcesAction {
+    String getName();
+    String getBusyText();
+    ActionCallback perform(List<LibraryOrderEntry> orderEntriesContainingFile);
+  }
+
+  /**
+   * This marker interface means what this action will be shown only if it is single action.
+   */
+  interface LightAttachSourcesAction extends AttachSourcesAction {
+
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/ClassUtil.java b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java
new file mode 100644
index 0000000..eb41a67
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/ClassUtil.java
@@ -0,0 +1,105 @@
+/*
+ * 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.
+ */
+
+/**
+ * @author Alexey
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.psi.*;
+import gnu.trove.THashSet;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+import java.util.Set;
+
+public class ClassUtil {
+  private ClassUtil() { }
+
+  @Nullable
+  public static PsiMethod getAnyAbstractMethod(@NotNull PsiClass aClass) {
+    PsiMethod methodToImplement = getAnyMethodToImplement(aClass);
+    if (methodToImplement != null) {
+      return methodToImplement;
+    }
+    PsiMethod[] methods = aClass.getMethods();
+    for (PsiMethod method : methods) {
+      if (method.hasModifierProperty(PsiModifier.ABSTRACT)) return method;
+    }
+
+    return null;
+  }
+
+  @Nullable
+  public static PsiMethod getAnyMethodToImplement(@NotNull PsiClass aClass) {
+    Set<PsiMethod> alreadyImplemented = new THashSet<PsiMethod>();
+    for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
+      for (PsiMethod superS : signatureHierarchical.getMethod().findSuperMethods()) {
+        add(superS, alreadyImplemented);
+      }
+    }
+    PsiResolveHelper resolveHelper = JavaPsiFacade.getInstance(aClass.getProject()).getResolveHelper();
+    for (HierarchicalMethodSignature signatureHierarchical : aClass.getVisibleSignatures()) {
+      PsiMethod method = signatureHierarchical.getMethod();
+      PsiClass containingClass = method.getContainingClass();
+      if (containingClass == null) {
+        continue;
+      }
+      if (!aClass.equals(containingClass)
+          && method.hasModifierProperty(PsiModifier.ABSTRACT)
+          && !method.hasModifierProperty(PsiModifier.STATIC)
+          && !method.hasModifierProperty(PsiModifier.PRIVATE)
+          && !alreadyImplemented.contains(method)) {
+        return method;
+      }
+      final List<HierarchicalMethodSignature> superSignatures = signatureHierarchical.getSuperSignatures();
+      for (HierarchicalMethodSignature superSignatureHierarchical : superSignatures) {
+        final PsiMethod superMethod = superSignatureHierarchical.getMethod();
+        if (superMethod.hasModifierProperty(PsiModifier.ABSTRACT) && !resolveHelper.isAccessible(superMethod, method, null)) {
+          return superMethod;
+        }
+      }
+    }
+
+    return checkPackageLocalInSuperClass(aClass);
+  }
+
+  @Nullable
+  private static PsiMethod checkPackageLocalInSuperClass(@NotNull PsiClass aClass) {
+    // super class can have package local abstract methods not accessible for overriding
+    PsiClass superClass = aClass.getSuperClass();
+    if (superClass == null) return null;
+    if (CommonClassNames.JAVA_LANG_OBJECT.equals(aClass.getQualifiedName())) return null;
+    if (JavaPsiFacade.getInstance(aClass.getProject()).arePackagesTheSame(aClass, superClass)) return null;
+
+    for (HierarchicalMethodSignature methodSignature : superClass.getVisibleSignatures()) {
+      PsiMethod method = methodSignature.getMethod();
+      if (method.hasModifierProperty(PsiModifier.ABSTRACT) && method.hasModifierProperty(PsiModifier.PACKAGE_LOCAL)) return method;
+    }
+    return null;
+  }
+
+  private static boolean add(PsiMethod method, Set<PsiMethod> alreadyImplemented) {
+    boolean already = alreadyImplemented.add(method);
+    if (!already) return already;
+
+    for (PsiMethod superSig : method.findSuperMethods()) {
+      already &= add(superSig, alreadyImplemented);
+    }
+    return already;
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
new file mode 100644
index 0000000..b440e4c
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/CodeInsightServicesUtil.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.IncorrectOperationException;
+
+/**
+ * @author ven
+ */
+public class CodeInsightServicesUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.CodeInsightServicesUtil");
+
+  private static final IElementType[] ourTokenMap = {
+    JavaTokenType.EQEQ, JavaTokenType.NE,
+    JavaTokenType.LT, JavaTokenType.GE,
+    JavaTokenType.LE, JavaTokenType.GT,
+    JavaTokenType.OROR, JavaTokenType.ANDAND
+  };
+
+  public static PsiExpression invertCondition(PsiExpression booleanExpression) throws IncorrectOperationException {
+    PsiElementFactory factory = JavaPsiFacade.getInstance(booleanExpression.getProject()).getElementFactory();
+
+    if (booleanExpression instanceof PsiPolyadicExpression) {
+      PsiPolyadicExpression expression = (PsiPolyadicExpression)booleanExpression;
+      IElementType operationSign = expression.getOperationTokenType();
+      for (int i = 0; i < ourTokenMap.length; i++) {
+        IElementType tokenType = ourTokenMap[i];
+        if (operationSign == tokenType) {
+          expression = (PsiPolyadicExpression)expression.copy();
+          PsiExpression[] operands = expression.getOperands();
+          for (int o = 0; o < operands.length; o++) {
+            PsiExpression op = operands[o];
+            if (o != 0) {
+              expression.getTokenBeforeOperand(op).replace(createOperationToken(factory, ourTokenMap[i + (i % 2 == 0 ? 1 : -1)]));
+            }
+            if (tokenType == JavaTokenType.OROR || tokenType == JavaTokenType.ANDAND) {
+              op.replace(invertCondition(op));
+            }
+          }
+          return expression;
+        }
+      }
+    }
+    else if (booleanExpression instanceof PsiPrefixExpression) {
+      PsiPrefixExpression expression = (PsiPrefixExpression)booleanExpression;
+      if (expression.getOperationTokenType() == JavaTokenType.EXCL) {
+        PsiExpression operand = expression.getOperand();
+        if (operand instanceof PsiParenthesizedExpression) {
+          operand = ((PsiParenthesizedExpression)operand).getExpression();
+        }
+        return operand;
+      }
+    }
+    else if (booleanExpression instanceof PsiLiteralExpression) {
+      return booleanExpression.getText().equals("true") ?
+             factory.createExpressionFromText("false", null) :
+             factory.createExpressionFromText("true", null);
+    }
+
+    if (booleanExpression instanceof PsiParenthesizedExpression) {
+      PsiExpression operand = ((PsiParenthesizedExpression)booleanExpression).getExpression();
+      operand.replace(invertCondition(operand));
+      return booleanExpression;
+    }
+
+    PsiPrefixExpression result = (PsiPrefixExpression)factory.createExpressionFromText("!(a)", null);
+    if (!(booleanExpression instanceof PsiPolyadicExpression)) {
+      result.getOperand().replace(booleanExpression);
+    }
+    else {
+      PsiParenthesizedExpression e = (PsiParenthesizedExpression)result.getOperand();
+      e.getExpression().replace(booleanExpression);
+    }
+
+    return result;
+  }
+
+  private static PsiElement createOperationToken(PsiElementFactory factory, IElementType tokenType) throws IncorrectOperationException {
+    final String s;
+    if (tokenType == JavaTokenType.EQEQ) {
+      s = "==";
+    }
+    else if (tokenType == JavaTokenType.NE) {
+      s = "!=";
+    }
+    else if (tokenType == JavaTokenType.LT) {
+      s = "<";
+    }
+    else if (tokenType == JavaTokenType.LE) {
+      s = "<=";
+    }
+    else if (tokenType == JavaTokenType.GT) {
+      s = ">";
+    }
+    else if (tokenType == JavaTokenType.GE) {
+      s = ">=";
+    }
+    else if (tokenType == JavaTokenType.ANDAND) {
+      s = "&&";
+    }
+    else if (tokenType == JavaTokenType.OROR) {
+      s = "||";
+    }
+    else {
+      LOG.error("Unknown token type");
+      s = "==";
+    }
+
+    PsiBinaryExpression expression = (PsiBinaryExpression)factory.createExpressionFromText("a" + s + "b", null);
+    return expression.getOperationSign();
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java b/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java
new file mode 100644
index 0000000..63f1a42
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/ContainerProvider.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Max Medvedev
+ */
+public interface ContainerProvider {
+  ExtensionPointName<ContainerProvider> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.containerProvider");
+
+  @Nullable
+  PsiElement getContainer(@NotNull PsiElement item);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java b/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java
new file mode 100644
index 0000000..903c868
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/MethodImplementor.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.codeInsight.generation.GenerationInfo;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public interface MethodImplementor extends MemberImplementorExplorer {
+  ExtensionPointName<MethodImplementor> EXTENSION_POINT_NAME = ExtensionPointName.create("com.intellij.methodImplementor");
+
+  @NotNull
+  PsiMethod[] createImplementationPrototypes(final PsiClass inClass, PsiMethod method) throws IncorrectOperationException;
+
+  boolean isBodyGenerated();
+
+  @Nullable
+  GenerationInfo createGenerationInfo(PsiMethod method, boolean mergeIfExists);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java b/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java
new file mode 100644
index 0000000..a091f39
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/NullableNotNullDialog.java
@@ -0,0 +1,219 @@
+/*
+ * 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;
+
+import com.intellij.icons.AllIcons;
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Splitter;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.*;
+import com.intellij.ui.components.JBList;
+import com.intellij.util.ui.EmptyIcon;
+
+import javax.swing.*;
+import javax.swing.event.ListSelectionEvent;
+import javax.swing.event.ListSelectionListener;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.HashSet;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 1/25/11
+ */
+public class NullableNotNullDialog extends DialogWrapper {
+
+  private final Project myProject;
+  private AnnotationsPanel myNullablePanel;
+  private AnnotationsPanel myNotNullPanel;
+
+  public NullableNotNullDialog(Project project) {
+    super(project, true);
+    myProject = project;
+    init();
+    setTitle("Nullable/NotNull configuration");
+  }
+
+
+  @Override
+  protected JComponent createCenterPanel() {
+    final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
+    final Splitter splitter = new Splitter(true);
+    myNullablePanel =
+      new AnnotationsPanel("Nullable", manager.getDefaultNullable(), manager.getNullables(), NullableNotNullManager.DEFAULT_NULLABLES);
+    splitter.setFirstComponent(myNullablePanel.getComponent());
+    myNotNullPanel =
+      new AnnotationsPanel("NotNull", manager.getDefaultNotNull(), manager.getNotNulls(), NullableNotNullManager.DEFAULT_NOT_NULLS);
+    splitter.setSecondComponent(myNotNullPanel.getComponent());
+    splitter.setHonorComponentsMinimumSize(true);
+    splitter.setPreferredSize(new Dimension(300, 400));
+    return splitter;
+  }
+
+  @Override
+  protected void doOKAction() {
+    final NullableNotNullManager manager = NullableNotNullManager.getInstance(myProject);
+
+    manager.setNotNulls(myNotNullPanel.getAnnotations());
+    manager.setDefaultNotNull(myNotNullPanel.getDefaultAnnotation());
+
+    manager.setNullables(myNullablePanel.getAnnotations());
+    manager.setDefaultNullable(myNullablePanel.getDefaultAnnotation());
+
+    super.doOKAction();
+  }
+
+  private class AnnotationsPanel {
+    private String myDefaultAnnotation;
+    private final Set<String> myDefaultAnnotations;
+    private final JBList myList;
+    private final JPanel myComponent;
+
+    private AnnotationsPanel(final String name, final String defaultAnnotation,
+                             final Collection<String> annotations, final String[] defaultAnnotations) {
+      myDefaultAnnotation = defaultAnnotation;
+      myDefaultAnnotations = new HashSet(Arrays.asList(defaultAnnotations));
+      myList = new JBList(annotations);
+      myList.setCellRenderer(new ColoredListCellRenderer() {
+        @Override
+        protected void customizeCellRenderer(JList list, Object value, int index, boolean selected, boolean hasFocus) {
+          append((String)value, SimpleTextAttributes.REGULAR_ATTRIBUTES);
+          if (value.equals(myDefaultAnnotation)) {
+            setIcon(AllIcons.Diff.CurrentLine);
+          } else {
+            setIcon(EmptyIcon.ICON_16);
+          }
+          //if (myDefaultAnnotations.contains(value)) {
+          //  append(" (built in)", SimpleTextAttributes.GRAY_ATTRIBUTES);
+          //}
+        }
+      });
+
+      final AnActionButton selectButton =
+        new AnActionButton("Select annotation used for code generation", AllIcons.Actions.Checked) {
+          @Override
+          public void actionPerformed(AnActionEvent e) {
+            final String selectedValue = (String)myList.getSelectedValue();
+            if (selectedValue == null) return;
+            myDefaultAnnotation = selectedValue;
+            final DefaultListModel model = (DefaultListModel)myList.getModel();
+
+            // to show the new default value in the ui
+            model.setElementAt(myList.getSelectedValue(), myList.getSelectedIndex());
+          }
+
+          @Override
+          public void updateButton(AnActionEvent e) {
+            final String selectedValue = (String)myList.getSelectedValue();
+            final boolean enabled = selectedValue != null && !selectedValue.equals(myDefaultAnnotation);
+            if (!enabled) {
+              e.getPresentation().setEnabled(enabled);
+            }
+          }
+        };
+
+      final ToolbarDecorator toolbarDecorator = ToolbarDecorator.createDecorator(myList).disableUpDownActions()
+        .setAddAction(new AnActionButtonRunnable() {
+          @Override
+          public void run(AnActionButton anActionButton) {
+            chooseAnnotation(name, myList);
+          }
+        })
+        .setRemoveAction(new AnActionButtonRunnable() {
+          @Override
+          public void run(AnActionButton anActionButton) {
+            final String selectedValue = (String)myList.getSelectedValue();
+            if (selectedValue == null) return;
+            if (myDefaultAnnotation.equals(selectedValue)) myDefaultAnnotation = (String)myList.getModel().getElementAt(0);
+
+            ((DefaultListModel)myList.getModel()).removeElement(selectedValue);
+          }
+        })
+        .addExtraAction(selectButton);
+      final JPanel panel = toolbarDecorator.createPanel();
+      myComponent = new JPanel(new BorderLayout());
+      myComponent.setBorder(IdeBorderFactory.createTitledBorder(name + " annotations", false, new Insets(10, 0, 0, 0)));
+      myComponent.add(panel);
+      final AnActionButton removeButton = ToolbarDecorator.findRemoveButton(myComponent);
+      myList.addListSelectionListener(new ListSelectionListener() {
+        @Override
+        public void valueChanged(ListSelectionEvent e) {
+          if (e.getValueIsAdjusting()) return;
+          final String selectedValue = (String)myList.getSelectedValue();
+          if (myDefaultAnnotations.contains(selectedValue)) {
+            SwingUtilities.invokeLater(new Runnable() {
+              @Override
+              public void run() {
+                removeButton.setEnabled(false);
+              }
+            });
+          }
+        }
+      });
+      myList.setSelectionMode(ListSelectionModel.SINGLE_SELECTION);
+      myList.setSelectedValue(myDefaultAnnotation, true);
+    }
+
+    private void chooseAnnotation(String title, JBList list) {
+      final TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject)
+        .createNoInnerClassesScopeChooser("Choose " + title + " annotation", GlobalSearchScope.allScope(myProject), new ClassFilter() {
+          @Override
+          public boolean isAccepted(PsiClass aClass) {
+            return aClass.isAnnotationType();
+          }
+        }, null);
+      chooser.showDialog();
+      final PsiClass selected = chooser.getSelected();
+      if (selected == null) {
+        return;
+      }
+      final String qualifiedName = selected.getQualifiedName();
+      final DefaultListModel model = (DefaultListModel)list.getModel();
+      final int index = model.indexOf(qualifiedName);
+      if (index < 0) {
+        model.addElement(qualifiedName);
+      } else {
+        myList.setSelectedIndex(index);
+      }
+    }
+
+    public JComponent getComponent() {
+      return myComponent;
+    }
+
+    public String getDefaultAnnotation() {
+      return myDefaultAnnotation;
+    }
+
+    public String[] getAnnotations() {
+      final ListModel model = myList.getModel();
+      final int size = model.getSize();
+      final String[] result = new String[size];
+      for (int i = 0; i < size; i++) {
+        result[i] = (String)model.getElementAt(i);
+      }
+      return result;
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java b/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java
new file mode 100644
index 0000000..04426ec
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/NullableNotNullManagerImpl.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight;
+
+import com.intellij.openapi.components.State;
+import com.intellij.openapi.components.Storage;
+import com.intellij.openapi.components.StoragePathMacros;
+
+@State(
+  name = "NullableNotNullManager",
+  storages = {@Storage( file = StoragePathMacros.PROJECT_FILE)}
+)
+public class NullableNotNullManagerImpl extends NullableNotNullManager {
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java b/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java
new file mode 100644
index 0000000..e1f83cb
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/MethodParenthesesHandler.java
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * @author peter
+ */
+public class MethodParenthesesHandler extends ParenthesesInsertHandler<LookupElement> {
+  private final PsiMethod myMethod;
+  private final boolean myOverloadsMatter;
+
+  public MethodParenthesesHandler(final PsiMethod method, boolean overloadsMatter) {
+    myMethod = method;
+    myOverloadsMatter = overloadsMatter;
+  }
+
+  @Override
+  protected boolean placeCaretInsideParentheses(final InsertionContext context, final LookupElement item) {
+    return hasParams(item, context.getElements(), myOverloadsMatter, myMethod);
+  }
+
+  public static boolean hasParams(LookupElement item, LookupElement[] allItems, final boolean overloadsMatter, final PsiMethod method) {
+    boolean hasParams = method.getParameterList().getParametersCount() > 0;
+    if (overloadsMatter){
+      hasParams |= hasOverloads(allItems, method);
+    }
+    return hasParams;
+  }
+
+  private static boolean hasOverloads(LookupElement[] allItems, final PsiMethod method) {
+    String name = method.getName();
+    for (LookupElement another : allItems) {
+      final PsiElement element = another.getPsiElement();
+      if (method != element && element instanceof PsiMethod && ((PsiMethod)element).getName().equals(name)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java b/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java
new file mode 100644
index 0000000..2ff5f44
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/PsiTypeCanonicalLookupElement.java
@@ -0,0 +1,112 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPrimitiveType;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.psi.util.PsiUtil;
+import com.intellij.util.PlatformIcons;
+import com.intellij.util.ui.EmptyIcon;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * @author peter
+ */
+public class PsiTypeCanonicalLookupElement extends LookupElement {
+  private static final Icon EMPTY_ICON = new EmptyIcon(PlatformIcons.CLASS_ICON.getIconWidth() * 2, PlatformIcons.CLASS_ICON.getIconHeight());
+
+  private final PsiType myType;
+  private final String myPresentableText;
+
+  public PsiTypeCanonicalLookupElement(@NotNull final PsiType type) {
+    myType = type;
+    myPresentableText = myType.getPresentableText();
+  }
+
+  @NotNull
+  @Override
+  public Object getObject() {
+    final PsiClass psiClass = getPsiClass();
+    if (psiClass != null) {
+      return psiClass;
+    }
+    return super.getObject();
+  }
+
+  @Nullable
+  public PsiClass getPsiClass() {
+    return PsiUtil.resolveClassInType(myType);
+  }
+
+  @Override
+  public boolean isValid() {
+    return myType.isValid() && super.isValid();
+  }
+
+  public PsiType getPsiType() {
+    return myType;
+  }
+
+  @Override
+  @NotNull
+  public String getLookupString() {
+    return myPresentableText;
+  }
+
+  @Override
+  public void handleInsert(InsertionContext context) {
+    context.getEditor().getDocument().replaceString(context.getStartOffset(), context.getStartOffset() + getLookupString().length(), getPsiType().getCanonicalText());
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (!(o instanceof PsiTypeCanonicalLookupElement)) return false;
+
+    final PsiTypeCanonicalLookupElement that = (PsiTypeCanonicalLookupElement)o;
+
+    if (!myType.equals(that.myType)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return myType.hashCode();
+  }
+
+  @Override
+  public void renderElement(LookupElementPresentation presentation) {
+    final PsiClass psiClass = getPsiClass();
+    if (psiClass != null) {
+      presentation.setIcon(presentation.isReal() ? psiClass.getIcon(Iconable.ICON_FLAG_VISIBILITY) : EMPTY_ICON);
+      presentation.setTailText(" (" + PsiFormatUtil.getPackageDisplayName(psiClass) + ")", true);
+    }
+    final PsiType type = getPsiType();
+    presentation.setItemText(type.getPresentableText());
+    presentation.setItemTextBold(type instanceof PsiPrimitiveType);
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java b/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java
new file mode 100644
index 0000000..1ebda15
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/completion/util/SimpleMethodCallLookupElement.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion.util;
+
+import com.intellij.codeInsight.completion.InsertionContext;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupElementPresentation;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiSubstitutor;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.util.PsiFormatUtil;
+import com.intellij.openapi.util.Iconable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class SimpleMethodCallLookupElement extends LookupElement {
+  private final PsiMethod myMethod;
+
+  public SimpleMethodCallLookupElement(final PsiMethod method) {
+    myMethod = method;
+  }
+
+  @Override
+  @NotNull
+  public String getLookupString() {
+    return myMethod.getName();
+  }
+
+  @Override
+  public void handleInsert(InsertionContext context) {
+    new MethodParenthesesHandler(myMethod, true).handleInsert(context, this);
+  }
+
+  public PsiMethod getMethod() {
+    return myMethod;
+  }
+
+  @Override
+  public void renderElement(LookupElementPresentation presentation) {
+    presentation.setIcon(myMethod.getIcon(Iconable.ICON_FLAG_VISIBILITY));
+    presentation.setItemText(myMethod.getName());
+    presentation.setTailText(PsiFormatUtil.formatMethod(myMethod,
+                                                        PsiSubstitutor.EMPTY,
+                                                        PsiFormatUtil.SHOW_PARAMETERS,
+                                                        PsiFormatUtil.SHOW_NAME | PsiFormatUtil.SHOW_TYPE));
+    final PsiType returnType = myMethod.getReturnType();
+    if (returnType != null) {
+      presentation.setTypeText(returnType.getCanonicalText());
+    }
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java b/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java
new file mode 100644
index 0000000..20bd1b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/daemon/GroupNames.java
@@ -0,0 +1,71 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon;
+
+import com.intellij.codeInspection.InspectionsBundle;
+
+/**
+ * @author anna
+ * Date: Jun 22, 2005
+ */
+public interface GroupNames {
+  String ABSTRACTION_GROUP_NAME = InspectionsBundle.message("group.names.abstraction.issues");
+  String ASSIGNMENT_GROUP_NAME = InspectionsBundle.message("group.names.assignment.issues");
+  String BUGS_GROUP_NAME = InspectionsBundle.message("group.names.probable.bugs");
+  String BITWISE_GROUP_NAME = InspectionsBundle.message("group.names.bitwise.operation.issues");
+  String CLASS_LAYOUT_GROUP_NAME = InspectionsBundle.message("group.names.class.structure");
+  String CLASS_METRICS_GROUP_NAME = InspectionsBundle.message("group.names.class.metrics");
+  String COMPILER_ISSUES = InspectionsBundle.message("group.names.compiler.issues");
+  String CONFUSING_GROUP_NAME = InspectionsBundle.message("group.names.potentially.confusing.code.constructs");
+  String ENCAPSULATION_GROUP_NAME = InspectionsBundle.message("group.names.encapsulation.issues");
+  String ERROR_HANDLING_GROUP_NAME = InspectionsBundle.message("group.names.error.handling");
+  String FINALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.finalization.issues");
+  String IMPORTS_GROUP_NAME = InspectionsBundle.message("group.names.imports");
+  String INITIALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.initialization.issues");
+  String INTERNATIONALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.internationalization.issues");
+  String JUNIT_GROUP_NAME = InspectionsBundle.message("group.names.junit.issues");
+  String LOGGING_GROUP_NAME = InspectionsBundle.message("group.names.logging.issues");
+  String MATURITY_GROUP_NAME = InspectionsBundle.message("group.names.code.maturity.issues");
+  String METHOD_METRICS_GROUP_NAME = InspectionsBundle.message("group.names.method.metrics");
+  String NAMING_CONVENTIONS_GROUP_NAME = InspectionsBundle.message("group.names.naming.conventions");
+  String PERFORMANCE_GROUP_NAME = InspectionsBundle.message("group.names.performance.issues");
+  String MEMORY_GROUP_NAME = InspectionsBundle.message("group.names.memory.issues");
+  String JDK_GROUP_NAME = InspectionsBundle.message("group.names.java.language.level.issues");
+  String PORTABILITY_GROUP_NAME = InspectionsBundle.message("group.names.portability.issues");
+  String SECURITY_GROUP_NAME = InspectionsBundle.message("group.names.security.issues");
+  String SERIALIZATION_GROUP_NAME = InspectionsBundle.message("group.names.serialization.issues");
+  String STYLE_GROUP_NAME = InspectionsBundle.message("group.names.code.style.issues");
+  String THREADING_GROUP_NAME = InspectionsBundle.message("group.names.threading.issues");
+  String VERBOSE_GROUP_NAME = InspectionsBundle.message("group.names.verbose.or.redundant.code.constructs");
+  String VISIBILITY_GROUP_NAME = InspectionsBundle.message("group.names.visibility.issues");
+  String CLONEABLE_GROUP_NAME = InspectionsBundle.message("group.names.cloning.issues");
+  String RESOURCE_GROUP_NAME = InspectionsBundle.message("group.names.resource.management.issues");
+  String J2ME_GROUP_NAME = InspectionsBundle.message("group.names.j2me.issues");
+  String CONTROL_FLOW_GROUP_NAME = InspectionsBundle.message("group.names.control.flow.issues");
+  String NUMERIC_GROUP_NAME = InspectionsBundle.message("group.names.numeric.issues");
+  String LANGUAGE_LEVEL_SPECIFIC_GROUP_NAME = InspectionsBundle.message("group.names.language.level.specific.issues.and.migration.aids");
+  String JAVABEANS_GROUP_NAME = InspectionsBundle.message("group.names.javabeans.issues");
+  String INHERITANCE_GROUP_NAME = InspectionsBundle.message("group.names.inheritance.issues");
+  String DATA_FLOW_ISSUES = InspectionsBundle.message("group.names.data.flow.issues");
+  String DECLARATION_REDUNDANCY = InspectionsBundle.message("group.names.declaration.redundancy");
+  String PACKAGING_GROUP_NAME = InspectionsBundle.message("group.names.packaging.issues");
+  String DEPENDENCY_GROUP_NAME = InspectionsBundle.message("group.names.dependency.issues");
+  String MODULARIZATION_GROUP_NAME = InspectionsBundle.message("group.names.modularization.issues");
+  String JAVAEE_GROUP_NAME = InspectionsBundle.message("group.names.javaee.issues");
+  String CONCURRENCY_ANNOTATION_ISSUES = InspectionsBundle.message("group.names.concurrency.annotation.issues");
+  String JAVADOC_GROUP_NAME = InspectionsBundle.message("group.names.javadoc.issues");
+  String PROPERTIES_GROUP_NAME = InspectionsBundle.message("group.names.properties.files");
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java
new file mode 100644
index 0000000..5b2bb5e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/GenerationInfo.java
@@ -0,0 +1,48 @@
+/*
+ * 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.generation;
+
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMember;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author Medvedev Max
+ */
+public interface GenerationInfo {
+  GenerationInfo[] EMPTY_ARRAY = new GenerationInfo[0];
+
+  void insert(PsiClass aClass, PsiElement anchor, boolean before) throws IncorrectOperationException;
+
+  PsiMember getPsiMember();
+
+  /**
+   * @param aClass
+   * @param leaf leaf element. Is guaranteed to be a tree descendant of aClass.
+   * @return the value that will be passed to the {@link #insert(com.intellij.psi.PsiClass, com.intellij.psi.PsiElement, boolean)} method later.
+   */
+  @Nullable
+  PsiElement findInsertionAnchor(@NotNull PsiClass aClass, @NotNull PsiElement leaf);
+
+  /**
+   * Position caret in generated element in correct way
+   */
+  void positionCaret(Editor editor, boolean toEditMethodBody);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
new file mode 100644
index 0000000..cd3fed7
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/actions/BaseGenerateAction.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.codeInsight.generation.actions;
+
+import com.intellij.codeInsight.CodeInsightActionHandler;
+import com.intellij.codeInsight.actions.CodeInsightAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.Nullable;
+
+public class BaseGenerateAction extends CodeInsightAction {
+  private final CodeInsightActionHandler myHandler;
+
+  public BaseGenerateAction(CodeInsightActionHandler handler) {
+    myHandler = handler;
+  }
+
+  @Override
+  protected final CodeInsightActionHandler getHandler() {
+    return myHandler;
+  }
+
+  @Nullable
+  protected PsiClass getTargetClass (Editor editor, PsiFile file) {
+    int offset = editor.getCaretModel().getOffset();
+    PsiElement element = file.findElementAt(offset);
+    if (element == null) return null;
+    final PsiClass target = PsiTreeUtil.getParentOfType(element, PsiClass.class);
+    return target instanceof SyntheticElement ? null : target;
+  }
+
+  @Override
+  protected boolean isValidForFile(Project project, Editor editor, PsiFile file) {
+    if (!(file instanceof PsiJavaFile)) return false;
+    if (file instanceof PsiCompiledElement) return false;
+
+    PsiDocumentManager.getInstance(project).commitAllDocuments();
+
+    PsiClass targetClass = getTargetClass(editor, file);
+    return targetClass != null && isValidForClass(targetClass);
+  }
+
+  protected boolean isValidForClass(final PsiClass targetClass) {
+    return !targetClass.isInterface();
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
new file mode 100644
index 0000000..1265068
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/generation/surroundWith/JavaExpressionSurrounder.java
@@ -0,0 +1,52 @@
+
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.codeInsight.generation.surroundWith;
+
+import com.intellij.lang.surroundWith.Surrounder;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiExpression;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class JavaExpressionSurrounder implements Surrounder {
+  public static ExtensionPointName<JavaExpressionSurrounder> EP_NAME = ExtensionPointName.create("com.intellij.javaExpressionSurrounder");
+  
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.generation.surroundWith.SurroundExpressionHandler");
+
+  @Override
+  public boolean isApplicable(@NotNull PsiElement[] elements) {
+    LOG.assertTrue(elements.length == 1 && elements[0] instanceof PsiExpression);
+    return isApplicable((PsiExpression)elements[0]);
+  }
+
+  public abstract boolean isApplicable(PsiExpression expr);
+
+  @Override
+  public TextRange surroundElements(@NotNull Project project,
+                                    @NotNull Editor editor,
+                                    @NotNull PsiElement[] elements) throws IncorrectOperationException {
+    return surroundExpression(project, editor, (PsiExpression)elements[0]);
+  }
+
+  public abstract TextRange surroundExpression(Project project, Editor editor, PsiExpression expr) throws IncorrectOperationException;
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInsight/highlighting/package.html b/java/openapi/src/com/intellij/codeInsight/highlighting/package.html
new file mode 100644
index 0000000..6d970db
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/highlighting/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for highlighting regions of text in the IDEA editor.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
new file mode 100644
index 0000000..87ad87d
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/intention/QuickFixFactory.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.intention;
+
+import com.intellij.codeInspection.LocalQuickFixAndIntentionActionOnPsiElement;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PropertyMemberType;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author cdr
+ */
+public abstract class QuickFixFactory {
+  public static QuickFixFactory getInstance() {
+    return ServiceManager.getService(QuickFixFactory.class);
+  }
+
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierList modifierList,
+                                                                                    @PsiModifier.ModifierConstant @NotNull String modifier,
+                                                                                    boolean shouldHave,
+                                                                                    final boolean showContainingClass);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createModifierListFix(@NotNull PsiModifierListOwner owner,
+                                                                                    @PsiModifier.ModifierConstant @NotNull String modifier,
+                                                                                    boolean shouldHave,
+                                                                                    final boolean showContainingClass);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodReturnFix(@NotNull PsiMethod method, @NotNull PsiType toReturn, boolean fixWholeHierarchy);
+
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull PsiMethod method, @NotNull PsiClass toClass);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddMethodFix(@NotNull String methodText, @NotNull PsiClass toClass, String... exceptions);
+
+  /**
+   * @param psiElement psiClass or enum constant without class initializer
+   */
+  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 LocalQuickFixAndIntentionActionOnPsiElement createAddDefaultConstructorFix(@NotNull PsiClass aClass);
+  @Nullable
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createAddConstructorFix(@NotNull PsiClass aClass, @PsiModifier.ModifierConstant String modifier);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createMethodParameterTypeFix(@NotNull PsiMethod method, int index, @NotNull PsiType newType, boolean fixWholeHierarchy);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createMakeClassInterfaceFix(@NotNull PsiClass aClass, final boolean makeInterface);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createExtendsListFix(@NotNull PsiClass aClass, @NotNull PsiClassType typeToExtendFrom, boolean toAdd);
+  public abstract LocalQuickFixAndIntentionActionOnPsiElement createRemoveUnusedParameterFix(@NotNull PsiParameter parameter);
+  public abstract IntentionAction createRemoveUnusedVariableFix(@NotNull PsiVariable variable);
+
+  @Nullable
+  public abstract IntentionAction createCreateClassOrPackageFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
+  @Nullable
+  public abstract IntentionAction createCreateClassOrInterfaceFix(@NotNull PsiElement context, @NotNull String qualifiedName, final boolean createClass, final String superClass);
+  public abstract IntentionAction createCreateFieldOrPropertyFix(final PsiClass aClass, final String name, final PsiType type, final PropertyMemberType targetMember, final PsiAnnotation... annotations);
+}
diff --git a/java/openapi/src/com/intellij/codeInsight/package.html b/java/openapi/src/com/intellij/codeInsight/package.html
new file mode 100644
index 0000000..b8d2186
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/package.html
@@ -0,0 +1,22 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with highlighting in standard IDEA editors, interfaces
+and classes for defining intention actions and additional functionality related to background
+code analysis in IDEA.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
new file mode 100644
index 0000000..5f0113e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInsight/quickfix/ChangeVariableTypeQuickFixProvider.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 27-Aug-2009
+ */
+package com.intellij.codeInsight.quickfix;
+
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiType;
+import com.intellij.psi.PsiVariable;
+
+public interface ChangeVariableTypeQuickFixProvider {
+  ExtensionPointName<ChangeVariableTypeQuickFixProvider> EP_NAME = ExtensionPointName.create("com.intellij.codeInsight.changeVariableTypeQuickFixProvider");
+
+  IntentionAction[] getFixes(PsiVariable variable, PsiType toReturn);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java b/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
new file mode 100644
index 0000000..7d37f4f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/BaseJavaLocalInspectionTool.java
@@ -0,0 +1,140 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * Implement this abstract class in order to provide new inspection tool functionality. The major API limitation here is
+ * subclasses should be stateless. Thus <code>check&lt;XXX&gt;</code> methods will be called in no particular order and
+ * instances of this class provided by {@link InspectionToolProvider#getInspectionClasses()} will be created on demand.
+ * The other important thing is problem anchors (PsiElements) reported by <code>check&lt;XXX&gt;</code> methods should
+ * lie under corresponding first parameter of one method.
+ *
+ * @see GlobalInspectionTool
+ */
+public abstract class BaseJavaLocalInspectionTool extends LocalInspectionTool  implements CustomSuppressableInspectionTool {
+  /**
+   * Override this to report problems at method level.
+   *
+   * @param method     to check.
+   * @param manager    InspectionManager to ask for ProblemDescriptor's from.
+   * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+   * @return <code>null</code> if no problems found or not applicable at method level.
+   */
+  @Nullable
+  public ProblemDescriptor[] checkMethod(@NotNull PsiMethod method, @NotNull InspectionManager manager, boolean isOnTheFly) {
+    return null;
+  }
+
+  /**
+   * Override this to report problems at class level.
+   *
+   * @param aClass     to check.
+   * @param manager    InspectionManager to ask for ProblemDescriptor's from.
+   * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+   * @return <code>null</code> if no problems found or not applicable at class level.
+   */
+  @Nullable
+  public ProblemDescriptor[] checkClass(@NotNull PsiClass aClass, @NotNull InspectionManager manager, boolean isOnTheFly) {
+    return null;
+  }
+
+  /**
+   * Override this to report problems at field level.
+   *
+   * @param field      to check.
+   * @param manager    InspectionManager to ask for ProblemDescriptor's from.
+   * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+   * @return <code>null</code> if no problems found or not applicable at field level.
+   */
+  @Nullable
+  public ProblemDescriptor[] checkField(@NotNull PsiField field, @NotNull InspectionManager manager, boolean isOnTheFly) {
+    return null;
+  }
+
+  /**
+     * Override this to report problems at file level.
+     *
+     * @param file       to check.
+     * @param manager    InspectionManager to ask for ProblemDescriptor's from.
+     * @param isOnTheFly true if called during on the fly editor highlighting. Called from Inspect Code action otherwise.
+     * @return <code>null</code> if no problems found or not applicable at file level.
+     */
+  @Override
+  @Nullable
+  public ProblemDescriptor[] checkFile(@NotNull PsiFile file, @NotNull InspectionManager manager, boolean isOnTheFly) {
+    return null;
+  }
+
+  @Override
+  @NotNull
+  public PsiElementVisitor buildVisitor(@NotNull final ProblemsHolder holder, final boolean isOnTheFly) {
+    return new JavaElementVisitor() {
+      @Override public void visitMethod(PsiMethod method) {
+        addDescriptors(checkMethod(method, holder.getManager(), isOnTheFly));
+      }
+
+      @Override public void visitClass(PsiClass aClass) {
+        addDescriptors(checkClass(aClass, holder.getManager(), isOnTheFly));
+      }
+
+      @Override public void visitField(PsiField field) {
+        addDescriptors(checkField(field, holder.getManager(), isOnTheFly));
+      }
+
+      @Override public void visitFile(PsiFile file) {
+        addDescriptors(checkFile(file, holder.getManager(), isOnTheFly));
+      }
+      private void addDescriptors(final ProblemDescriptor[] descriptors) {
+        if (descriptors != null) {
+          for (ProblemDescriptor descriptor : descriptors) {
+            holder.registerProblem(descriptor);
+          }
+        }
+      }
+    };
+  }
+
+  @Override
+  public PsiNamedElement getProblemElement(final PsiElement psiElement) {
+    return PsiTreeUtil.getNonStrictParentOfType(psiElement, PsiFile.class, PsiClass.class, PsiMethod.class, PsiField.class);
+  }
+
+  @Override
+  public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
+    return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
+  }
+
+  @Override
+  public boolean isSuppressedFor(@NotNull PsiElement element) {
+    return isSuppressedFor(element, this);
+  }
+
+  public static boolean isSuppressedFor(@NotNull PsiElement element, @NotNull LocalInspectionTool tool) {
+    final SuppressManager manager = SuppressManager.getInstance();
+    String alternativeId;
+    String id;
+    return manager.isSuppressedFor(element, id = tool.getID()) ||
+           (alternativeId = tool.getAlternativeID()) != null &&
+             !alternativeId.equals(id) &&
+             manager.isSuppressedFor(element, alternativeId);
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java
new file mode 100644
index 0000000..7e2a3c5
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionContext.java
@@ -0,0 +1,98 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInspection.ex.EntryPointsManager;
+import com.intellij.codeInspection.lang.GlobalInspectionContextExtension;
+import com.intellij.codeInspection.reference.RefClass;
+import com.intellij.codeInspection.reference.RefField;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.codeInspection.reference.RefMethod;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiReference;
+import com.intellij.util.Processor;
+
+public abstract class GlobalJavaInspectionContext implements GlobalInspectionContextExtension<GlobalJavaInspectionContext> {
+  public static final Key<GlobalJavaInspectionContext> CONTEXT = Key.create("GlobalJavaInspectionContext");
+
+  public interface DerivedClassesProcessor extends Processor<PsiClass> {
+  }
+
+  public interface DerivedMethodsProcessor extends Processor<PsiMethod> {
+  }
+
+  public interface UsagesProcessor extends Processor<PsiReference> {
+  }
+
+  /**
+   * Requests that usages of the specified class outside the current analysis
+   * scope be passed to the specified processor.
+   *
+   * @param refClass the reference graph node for the class whose usages should be processed.
+   * @param p        the processor to pass the usages to.
+   */
+  public abstract void enqueueClassUsagesProcessor(RefClass refClass, UsagesProcessor p);
+
+  /**
+   * Requests that derived classes of the specified class outside the current analysis
+   * scope be passed to the specified processor.
+   *
+   * @param refClass the reference graph node for the class whose derived classes should be processed.
+   * @param p        the processor to pass the classes to.
+   */
+  public abstract void enqueueDerivedClassesProcessor(RefClass refClass, DerivedClassesProcessor p);
+
+  /**
+   * Requests that implementing or overriding methods of the specified method outside
+   * the current analysis scope be passed to the specified processor.
+   *
+   * @param refMethod the reference graph node for the method whose derived methods should be processed.
+   * @param p         the processor to pass the methods to.
+   */
+  public abstract void enqueueDerivedMethodsProcessor(RefMethod refMethod, DerivedMethodsProcessor p);
+
+  /**
+   * Requests that usages of the specified field outside the current analysis
+   * scope be passed to the specified processor.
+   *
+   * @param refField the reference graph node for the field whose usages should be processed.
+   * @param p        the processor to pass the usages to.
+   */
+  public abstract void enqueueFieldUsagesProcessor(RefField refField, UsagesProcessor p);
+
+  /**
+   * Requests that usages of the specified method outside the current analysis
+   * scope be passed to the specified processor.
+   *
+   * @param refMethod the reference graph node for the method whose usages should be processed.
+   * @param p         the processor to pass the usages to.
+   */
+  public abstract void enqueueMethodUsagesProcessor(RefMethod refMethod, UsagesProcessor p);
+
+  public abstract EntryPointsManager getEntryPointsManager(RefManager manager);
+
+  @Override
+  public Key<GlobalJavaInspectionContext> getID() {
+    return CONTEXT;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
new file mode 100644
index 0000000..cb19ce9
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/GlobalJavaInspectionTool.java
@@ -0,0 +1,51 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class GlobalJavaInspectionTool extends GlobalInspectionTool implements CustomSuppressableInspectionTool {
+  @Override
+  public boolean queryExternalUsagesRequests(final InspectionManager manager,
+                                             final GlobalInspectionContext globalContext,
+                                             final ProblemDescriptionsProcessor problemDescriptionsProcessor) {
+    return queryExternalUsagesRequests(globalContext.getRefManager(), globalContext.getExtension(GlobalJavaInspectionContext.CONTEXT), problemDescriptionsProcessor);
+  }
+
+  protected boolean queryExternalUsagesRequests(RefManager manager, GlobalJavaInspectionContext globalContext, ProblemDescriptionsProcessor processor) {
+    return false;
+  }
+
+  @Override
+  @Nullable
+  public SuppressIntentionAction[] getSuppressActions(final PsiElement element) {
+    return SuppressManager.getInstance().createSuppressActions(HighlightDisplayKey.find(getShortName()));
+  }
+
+  @Override
+  public boolean isSuppressedFor(@NotNull final PsiElement element) {
+    return SuppressManager.getInstance().isSuppressedFor(element, getShortName());
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java b/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java
new file mode 100644
index 0000000..028447e
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/HTMLJavaHTMLComposer.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 19-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInspection.lang.HTMLComposerExtension;
+import com.intellij.codeInspection.reference.RefClass;
+import com.intellij.codeInspection.reference.RefMethod;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.util.Key;
+
+public abstract class HTMLJavaHTMLComposer implements HTMLComposerExtension<HTMLJavaHTMLComposer> {
+  public static final Key<HTMLJavaHTMLComposer> COMPOSER = Key.create("HTMLJavaComposer");
+
+  public abstract void appendClassOrInterface(StringBuffer buf, RefClass refClass, boolean capitalizeFirstLetter);
+
+  public static String getClassOrInterface(RefClass refClass, boolean capitalizeFirstLetter) {
+    if (refClass.isInterface()) {
+      return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.interface") : InspectionsBundle.message("inspection.export.results.interface");
+    }
+    else if (refClass.isAbstract()) {
+      return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.abstract.class") : InspectionsBundle.message("inspection.export.results.abstract.class");
+    }
+    else {
+      return capitalizeFirstLetter ? InspectionsBundle.message("inspection.export.results.capitalized.class") : InspectionsBundle.message("inspection.export.results.class");
+    }
+  }
+
+  public abstract void appendClassExtendsImplements(StringBuffer buf, RefClass refClass);
+
+  public abstract void appendDerivedClasses(StringBuffer buf, RefClass refClass);
+
+  public abstract void appendLibraryMethods(StringBuffer buf, RefClass refClass);
+
+  public abstract void appendSuperMethods(StringBuffer buf, RefMethod refMethod);
+
+  public abstract void appendDerivedMethods(StringBuffer buf, RefMethod refMethod);
+
+  public abstract void appendTypeReferences(StringBuffer buf, RefClass refClass);
+
+  @Override
+  public Key<HTMLJavaHTMLComposer> getID() {
+    return COMPOSER;
+  }
+
+  @Override
+  public Language getLanguage() {
+    return StdLanguages.JAVA;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/SuppressManager.java b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
new file mode 100644
index 0000000..8b60d46
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/SuppressManager.java
@@ -0,0 +1,69 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 24-Dec-2007
+ */
+package com.intellij.codeInspection;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import com.intellij.psi.util.PsiTreeUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public abstract class SuppressManager {
+  public static final String SUPPRESS_INSPECTIONS_ANNOTATION_NAME = "java.lang.SuppressWarnings";
+
+  public static SuppressManager getInstance() {
+    return ServiceManager.getService(SuppressManager.class);
+  }
+
+  @NotNull
+  public abstract SuppressIntentionAction[] createSuppressActions(@NotNull HighlightDisplayKey key);
+
+  public abstract boolean isSuppressedFor(@NotNull PsiElement element, final String toolId);
+
+  public abstract PsiElement getElementMemberSuppressedIn(@NotNull PsiDocCommentOwner owner, final String inspectionToolID);
+
+  @Nullable
+  public abstract PsiElement getAnnotationMemberSuppressedIn(@NotNull PsiModifierListOwner owner, String inspectionToolID);
+
+  @Nullable
+  public abstract PsiElement getDocCommentToolSuppressedIn(@NotNull PsiDocCommentOwner owner, String inspectionToolID);
+
+  @NotNull
+  public abstract Collection<String> getInspectionIdsSuppressedInAnnotation(@NotNull PsiModifierListOwner owner);
+
+  @Nullable
+  public abstract String getSuppressedInspectionIdsIn(@NotNull PsiElement element);
+
+  @Nullable
+  public abstract PsiElement getElementToolSuppressedIn(@NotNull PsiElement place, String toolId);
+
+  public abstract boolean canHave15Suppressions(@NotNull PsiElement file);
+
+  public abstract boolean alreadyHas14Suppressions(@NotNull PsiDocCommentOwner commentOwner);
+
+  public static boolean isSuppressedInspectionName(PsiLiteralExpression expression) {
+    PsiAnnotation annotation = PsiTreeUtil.getParentOfType(expression, PsiAnnotation.class, true, PsiCodeBlock.class, PsiField.class);
+    return annotation != null && SUPPRESS_INSPECTIONS_ANNOTATION_NAME.equals(annotation.getQualifiedName());
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java b/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java
new file mode 100644
index 0000000..3b90822
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/ex/EntryPointsManager.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+  * Date: 28-Feb-2007
+  */
+package com.intellij.codeInspection.ex;
+
+import com.intellij.codeInspection.reference.RefElement;
+import com.intellij.codeInspection.reference.RefManager;
+import com.intellij.openapi.Disposable;
+
+public interface EntryPointsManager extends Disposable {
+  void resolveEntryPoints(RefManager manager);
+
+  void addEntryPoint(RefElement newEntryPoint, boolean isPersistent);
+
+  void removeEntryPoint(RefElement anEntryPoint);
+
+  RefElement[] getEntryPoints();
+
+  void cleanup();
+
+  boolean isAddNonJavaEntries();
+
+  void configureAnnotations();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/package.html b/java/openapi/src/com/intellij/codeInspection/package.html
new file mode 100644
index 0000000..476d2af
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/package.html
@@ -0,0 +1,29 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for registering and implementing code inspections. To register inspections,
+a plugin should implement the {@link com.intellij.codeInspection.InspectionToolProvider} interface and return the
+list of inspection classes from the <code>getInspectionClasses()</code> method.
+An inspection is a class extending {@link com.intellij.codeInspection.LocalInspectionTool}. During background code
+analysis or when the "Inspect Code..." action is invoked,, IDEA calls the inspection
+to inspect individual files, classes, methods and fields, and if the inspection detects any problems,
+it returns an array of {@link com.intellij.codeInspection.ProblemDescriptor} classes reporting the problem. Each problem
+descriptor can return a list of {@link com.intellij.codeInspection.LocalQuickFix} classes, each of which represents an
+action which the user can invoke by pressing Alt-Enter in order to fix the problem detected
+by the inspection.
+</body></html>
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java b/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java
new file mode 100644
index 0000000..da8a04f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefClass.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.psi.PsiClass;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.List;
+import java.util.Set;
+
+/**
+ * User: anna
+ * Date: 27-Dec-2005
+ */
+public interface RefClass extends RefJavaElement {
+
+  @NotNull
+  Set<RefClass> getBaseClasses();
+
+  @NotNull
+  Set<RefClass> getSubClasses();
+
+  @NotNull
+  List<RefMethod> getConstructors();
+
+  @NotNull
+  Set<RefElement> getInTypeReferences();
+
+  @NotNull
+  Set<RefElement> getInstanceReferences();
+
+  RefMethod getDefaultConstructor();
+
+  @NotNull
+  List<RefMethod> getLibraryMethods();
+
+  boolean isAnonymous();
+
+  boolean isInterface();
+
+  boolean isUtilityClass();
+
+  boolean isAbstract();
+
+  boolean isApplet();
+
+  boolean isServlet();
+
+  boolean isTestCase();
+
+  boolean isLocalClass();
+
+  boolean isSelfInheritor(PsiClass psiClass);
+
+  @Override
+  PsiClass getElement();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefField.java b/java/openapi/src/com/intellij/codeInspection/reference/RefField.java
new file mode 100644
index 0000000..4418b0f
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefField.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.psi.PsiField;
+
+/**
+ * A node in the reference graph corresponding to a Java field.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefField extends RefJavaElement {
+  /**
+   * Checks if the field is used for reading.
+   *
+   * @return true if the field has read accesses, false otherwise.
+   */
+  boolean isUsedForReading();
+
+  /**
+   * Checks if the field is used for writing.
+   *
+   * @return true if the field has write accesses, false otherwise.
+   */
+  boolean isUsedForWriting();
+
+  /**
+   * Checks if the only write access of the field is its initializer.
+   *
+   * @return true if the only write access of the field is its initializer, false otherwise.
+   */
+  boolean isOnlyAssignedInInitializer();
+
+  /**
+   * Returns the reference graph node for the class to which the field belongs.
+   *
+   * @return the owner class of the field.
+   */
+  RefClass getOwnerClass();
+
+  @Override
+  PsiField getElement();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java b/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java
new file mode 100644
index 0000000..036bdd6
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefImplicitConstructor.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+/**
+ * A node in the reference graph corresponding to the implicit constructor of a Java class.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefImplicitConstructor extends RefMethod {
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java
new file mode 100644
index 0000000..59e9cb0
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaElement.java
@@ -0,0 +1,75 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.psi.PsiModifier;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+public interface RefJavaElement extends RefElement {
+   /**
+   * Returns the collection of references used in this element.
+   * @return the collection of used types
+   */
+  @NotNull
+  Collection<RefClass> getOutTypeReferences();
+
+
+  /**
+   * Checks if the element is <code>final</code>.
+   *
+   * @return true if the element is final, false otherwise.
+   */
+  boolean isFinal();
+
+  /**
+   * Checks if the element is <code>static</code>.
+   *
+   * @return true if the element is static, false otherwise.
+   */
+  boolean isStatic();
+
+  /**
+   * Checks if the element directly references any elements marked as deprecated.
+   *
+   * @return true if the element references any deprecated elements, false otherwise.
+   */
+  boolean isUsesDeprecatedApi();
+
+  /**
+   * Checks if the element is, or belongs to, a synthetic class or method created for a JSP page.
+   *
+   * @return true if the element is a synthetic JSP element, false otherwise.
+   */
+  boolean isSyntheticJSP();
+
+  /**
+   * Returns the access modifier for the element, as one of the keywords from the
+   * {@link com.intellij.psi.PsiModifier} class.
+   *
+   * @return the modifier, or null if the element does not have any access modifier.
+   */
+  @Nullable
+  @PsiModifier.ModifierConstant
+  String getAccessModifier();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java
new file mode 100644
index 0000000..b217cef
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaManager.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 18-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.codeInspection.ex.EntryPointsManager;
+import com.intellij.codeInspection.lang.RefManagerExtension;
+import com.intellij.lang.Language;
+import com.intellij.lang.StdLanguages;
+import com.intellij.openapi.util.Key;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import org.jetbrains.annotations.NonNls;
+
+public abstract class RefJavaManager implements RefManagerExtension<RefJavaManager> {
+  @NonNls public static final String CLASS = "class";
+  @NonNls public static final String METHOD = "method";
+  @NonNls public static final String FIELD = "field";
+  @NonNls public static final String PARAMETER = "parameter";
+  //used in OfflineProjectDescriptor
+  @NonNls public static final String PACKAGE = "package";
+  public static final Key<RefJavaManager> MANAGER = Key.create("RefJavaManager");
+
+  /**
+   * Creates (if necessary) and returns the reference graph node for the package
+   * with the specified name.
+   *
+   * @param packageName the name of the package for which the reference graph node is requested.
+   * @return the node for the package.
+   */
+  public abstract RefPackage getPackage(String packageName);
+
+  /**
+   * Creates (if necessary) and returns the reference graph node for the specified PSI parameter.
+   *
+   * @param param the parameter for which the reference graph node is requested.
+   * @param index the index of the parameter in its parameter list.
+   * @return the node for the element, or null if the element is not valid or does not have
+   * a corresponding reference graph node type (is not a field, method, class or file).
+   */
+  public abstract RefParameter getParameterReference(PsiParameter param, int index);
+
+  public abstract RefPackage getDefaultPackage();
+
+  public abstract PsiMethod getAppMainPattern();
+
+  public abstract PsiMethod getAppPremainPattern();
+
+  public abstract PsiClass getApplet();
+
+  public abstract PsiClass getServlet();
+
+  public abstract EntryPointsManager getEntryPointsManager();
+
+  @Override
+  public Language getLanguage() {
+    return StdLanguages.JAVA;
+  }
+
+  @Override
+  public Key<RefJavaManager> getID() {
+    return MANAGER;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java
new file mode 100644
index 0000000..5065117
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaUtil.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 21-Dec-2007
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class RefJavaUtil {
+  public abstract void addReferences(final PsiModifierListOwner psiFrom, final RefJavaElement ref, @Nullable PsiElement findIn);
+
+  public abstract RefClass getTopLevelClass(RefElement refElement);
+
+  public abstract boolean isInheritor(RefClass subClass, RefClass superClass);
+
+  @Nullable //default package name
+  public abstract String getPackageName(RefEntity refEntity);
+
+  @Nullable
+  public abstract RefClass getOwnerClass(RefManager refManager, PsiElement psiElement);
+
+  @Nullable
+  public abstract RefClass getOwnerClass(RefElement refElement);
+
+  public abstract int compareAccess(String a1, String a2);
+
+  public abstract String getAccessModifier(PsiModifierListOwner psiElement);
+
+  public abstract void setAccessModifier(RefJavaElement refElement, String newAccess);
+
+  public abstract void setIsStatic(RefJavaElement refElement, boolean isStatic);
+
+  public abstract void setIsFinal(RefJavaElement refElement, boolean isFinal);
+
+  public abstract boolean isMethodOnlyCallsSuper(final PsiMethod derivedMethod);
+
+  public static boolean isDeprecated(PsiElement psiResolved) {
+    return psiResolved instanceof PsiDocCommentOwner && ((PsiDocCommentOwner)psiResolved).isDeprecated();
+  }
+
+  @Nullable
+  public static RefPackage getPackage(RefEntity refEntity) {
+   while (refEntity != null && !(refEntity instanceof RefPackage)) refEntity = refEntity.getOwner();
+
+   return (RefPackage)refEntity;
+ }
+
+  public static RefJavaUtil getInstance() {
+    return ServiceManager.getService(RefJavaUtil.class);
+  }
+
+  public abstract boolean isCallToSuperMethod(PsiExpression expression, PsiMethod method);
+
+  public abstract void addTypeReference(PsiElement psiElement, PsiType psiType, RefManager refManager);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java
new file mode 100644
index 0000000..4117c69
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefJavaVisitor.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+/**
+ * Visitor for reference graph nodes.
+ *
+ * @see RefEntity#accept
+ * @see RefManager#iterate
+ * @since 6.0
+ */
+public class RefJavaVisitor extends RefVisitor {
+
+  public void visitField(RefField field) {
+    visitElement(field);
+  }
+
+  public void visitMethod(RefMethod method) {
+    visitElement(method);
+  }
+
+  public void visitParameter(RefParameter parameter) {
+    visitElement(parameter);
+  }
+
+  public void visitClass(RefClass aClass) {
+    visitElement(aClass);
+  }
+
+  public void visitPackage(RefPackage aPackage) {
+    visitElement(aPackage);
+  }
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java b/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java
new file mode 100644
index 0000000..3803f38
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefMethod.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.reference;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiModifierListOwner;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * A node in the reference graph corresponding to a Java method.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefMethod extends RefJavaElement {
+  /**
+   * Returns the collection of the direct super methods of this method in the
+   * analysis scope.
+   *
+   * @return the collection of super methods.
+   * @see com.intellij.psi.PsiMethod#findSuperMethods()
+   * @see #hasSuperMethods
+   */
+  @NotNull Collection<RefMethod> getSuperMethods();
+
+  /**
+   * Returns the collection of the overriding methods of this method in the
+   * analysis scope.
+   *
+   * @return the collection of overriding methods.
+   */
+  @NotNull Collection<RefMethod> getDerivedMethods();
+
+  /**
+   * Checks if this method has a body (that is, not a method of an interface or an abstract
+   * method).
+   *
+   * @return true if the method has a body, false otherwise.
+   */
+  boolean hasBody();
+
+  /**
+   * Checks if the method has no body or its body contains no statements besides
+   * (possibly) a call to its super method.
+   *
+   * @return true if the element has no body or the body is empty, false otherwise.
+   */
+  boolean isBodyEmpty();
+
+  /**
+   * Checks if the method has a body which consists only of the call to its super method.
+   *
+   * @return true if the method only calls its super method, false otherwise.
+   */
+  boolean isOnlyCallsSuper();
+
+  /**
+   * Checks if the method is a test method in a testcase class.
+   *
+   * @return true if the method is a test method, false otherwise.
+   */
+  boolean isTestMethod();
+
+  /**
+   * Checks if the signature of the method matches the signature of the standard <code>main</code>
+   * or <code>premain</code> method.
+   *
+   * @return true if the method can be a main function of the application, false otherwise.
+   */
+  boolean isAppMain();
+
+  /**
+   * Checks if the method has super methods either in the analysis scope or outside of it.
+   *
+   * @return true if the method has super methods, false otherwise.
+   * @see #getSuperMethods()
+   */
+  boolean hasSuperMethods();
+
+  /**
+   * Checks if the method overrides a method outside the current analysis scope.
+   *
+   * @return true if the method overrides a method not in the analysis scope, false otherwise.
+   */
+  boolean isExternalOverride();
+
+  /**
+   * Checks if the method is a constructor.
+   *
+   * @return true if the method is a constructor, false otherwise.
+   */
+  boolean isConstructor();
+
+  /**
+   * Checks if the method is abstract.
+   *
+   * @return true if the method is abstract, false otherwise.
+   */
+  boolean isAbstract();
+
+  /**
+   * Checks if the return value of the method is used by any of its callers.
+   *
+   * @return true if the method return value is used, false otherwise.
+   */
+  boolean isReturnValueUsed();
+
+  /**
+   * If the method always returns the same value, returns that value (the name of a static
+   * final field or the text of a literal expression). Otherwise, returns null.
+   *
+   * @return the method return value or null if it's different or impossible to determine.
+   */
+  @Nullable String getReturnValueIfSame();
+
+  /**
+   * Returns the list of exceptions which are included in the <code>throws</code> list
+   * of the method but cannot be actually thrown.
+   *
+   * @return the list of exceptions declared but not thrown, or null if there are no
+   * such exceptions.
+   */
+  @Nullable PsiClass[] getUnThrownExceptions();
+
+  /**
+   * Returns the list of reference graph nodes for the method parameters.
+   *
+   * @return the method parameters.
+   */
+  @NotNull RefParameter[] getParameters();
+
+  /**
+   * Returns the class to which the method belongs.
+   *
+   * @return the class instance.
+   */
+  RefClass getOwnerClass();
+
+  @Override
+  PsiModifierListOwner getElement();
+
+  boolean isCalledOnSubClass();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java b/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java
new file mode 100644
index 0000000..699e57c
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefPackage.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+/**
+ * A node in the reference graph corresponding to a Java package.
+ *
+ * @author anna
+ * @since 6.0
+ * @see RefJavaManager#getPackage
+ */
+public interface RefPackage extends RefEntity {
+  /**
+   * Returns the full-qualified name for the package, or an empty string for the default package.
+   *
+   * @return the full-qualified name for the package.
+   */
+  @Override
+  String getQualifiedName();
+}
diff --git a/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java b/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java
new file mode 100644
index 0000000..21c62f2
--- /dev/null
+++ b/java/openapi/src/com/intellij/codeInspection/reference/RefParameter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInspection.reference;
+
+import com.intellij.psi.PsiParameter;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * A node in the reference graph corresponding to a Java method parameter.
+ *
+ * @author anna
+ * @since 6.0
+ */
+public interface RefParameter extends RefJavaElement {
+  /**
+   * Checks if the parameter is used for reading.
+   *
+   * @return true if the parameter has read accesses, false otherwise.
+   */
+  boolean isUsedForReading();
+
+  /**
+   * Checks if the parameter is used for writing.
+   *
+   * @return true if the parameter has write accesses, false otherwise.
+   */
+  boolean isUsedForWriting();
+
+  /**
+   * Returns the index of the parameter in the parameter list of its owner method.
+   *
+   * @return the index of the parameter.
+   */
+  int getIndex();
+
+  /**
+   * If all invocations of the method pass the same value to the parameter, returns
+   * that value (the name of a static final field or the text of a literal expression).
+   * Otherwise, returns null.
+   *
+   * @return the parameter value or null if it's different or impossible to determine.
+   */
+  @Nullable String getActualValueIfSame();
+
+  /**
+   * Marks the parameter as referenced for reading or writing.
+   *
+   * @param forWriting true if the parameter is marked as referenced for writing, false
+   * otherwise.
+   */
+  void parameterReferenced(final boolean forWriting);
+
+  @Override
+  PsiParameter getElement();
+}
diff --git a/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
new file mode 100644
index 0000000..e00d4d6
--- /dev/null
+++ b/java/openapi/src/com/intellij/execution/filters/ExceptionWorker.java
@@ -0,0 +1,257 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.execution.filters;
+
+import com.intellij.openapi.application.AccessToken;
+import com.intellij.openapi.application.ReadAction;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.Trinity;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.PsiShortNamesCache;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.awt.*;
+
+/**
+ * User: Irina.Chernushina
+ * Date: 8/5/11
+ * Time: 8:36 PM
+ */
+public class ExceptionWorker {
+  @NonNls private static final String AT = "at";
+  private static final String AT_PREFIX = AT + " ";
+  private static final String STANDALONE_AT = " " + AT + " ";
+
+  private static final TextAttributes HYPERLINK_ATTRIBUTES = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.HYPERLINK_ATTRIBUTES);
+
+  private final Project myProject;
+  private final GlobalSearchScope mySearchScope;
+  private Filter.Result myResult;
+  private PsiClass myClass;
+  private PsiFile myFile;
+  private String myMethod;
+  private Trinity<TextRange, TextRange, TextRange> myInfo;
+
+  public ExceptionWorker(@NotNull Project project, @NotNull GlobalSearchScope searchScope) {
+    myProject = project;
+    mySearchScope = searchScope;
+  }
+
+  public void execute(final String line, final int textEndOffset) {
+    myResult = null;
+    myInfo = parseExceptionLine(line);
+    if (myInfo == null) {
+      return;
+    }
+
+    myMethod = myInfo.getSecond().substring(line);
+
+    final int lparenthIndex = myInfo.third.getStartOffset();
+    final int rparenthIndex = myInfo.third.getEndOffset();
+    final String fileAndLine = line.substring(lparenthIndex + 1, rparenthIndex).trim();
+
+    final int colonIndex = fileAndLine.lastIndexOf(':');
+    if (colonIndex < 0) return;
+
+    final String lineString = fileAndLine.substring(colonIndex + 1);
+    try {
+      final int lineNumber = Integer.parseInt(lineString);
+      myClass = findPositionClass(line);
+      myFile = myClass == null ? null : (PsiFile)myClass.getContainingFile().getNavigationElement();
+      if (myFile == null) {
+        // try find the file with the required name
+        PsiFile[] files = PsiShortNamesCache.getInstance(myProject).getFilesByName(fileAndLine.substring(0, colonIndex).trim());
+        if (files.length > 0) {
+          myFile = files[0];
+        }
+      }
+      if (myFile == null) return;
+
+      /*
+       IDEADEV-4976: Some scramblers put something like SourceFile mock instead of real class name.
+      final String filePath = fileAndLine.substring(0, colonIndex).replace('/', File.separatorChar);
+      final int slashIndex = filePath.lastIndexOf(File.separatorChar);
+      final String shortFileName = slashIndex < 0 ? filePath : filePath.substring(slashIndex + 1);
+      if (!file.getName().equalsIgnoreCase(shortFileName)) return null;
+      */
+
+      final int textStartOffset = textEndOffset - line.length();
+
+      final int highlightStartOffset = textStartOffset + lparenthIndex + 1;
+      final int highlightEndOffset = textStartOffset + rparenthIndex;
+      final VirtualFile virtualFile = myFile.getVirtualFile();
+
+      HyperlinkInfo linkInfo = new MyHyperlinkInfo(myProject, virtualFile, lineNumber);
+
+      TextAttributes attributes = HYPERLINK_ATTRIBUTES.clone();
+      if (!ProjectRootManager.getInstance(myProject).getFileIndex().isInContent(virtualFile)) {
+        Color color = UIUtil.getInactiveTextColor();
+        attributes.setForegroundColor(color);
+        attributes.setEffectColor(color);
+      }
+      myResult = new Filter.Result(highlightStartOffset, highlightEndOffset, linkInfo, attributes);
+    }
+    catch (NumberFormatException e) {
+      //
+    }
+  }
+
+  private PsiClass findPositionClass(String line) {
+    String className = myInfo.first.substring(line).trim();
+    PsiClass result = findClassPreferringMyScope(className);
+    if (result == null) {
+      final int dollarIndex = className.indexOf('$');
+      if (dollarIndex >= 0) {
+        result = findClassPreferringMyScope(className.substring(0, dollarIndex));
+      }
+    }
+    return result;
+  }
+
+  private PsiClass findClassPreferringMyScope(String className) {
+    JavaPsiFacade psiFacade = JavaPsiFacade.getInstance(myProject);
+    PsiClass result = psiFacade.findClass(className, mySearchScope);
+    return result != null ? result : psiFacade.findClass(className, GlobalSearchScope.allScope(myProject));
+  }
+
+  public Filter.Result getResult() {
+    return myResult;
+  }
+
+  public PsiClass getPsiClass() {
+    return myClass;
+  }
+
+  public String getMethod() {
+    return myMethod;
+  }
+
+  public PsiFile getFile() {
+    return myFile;
+  }
+
+  public Trinity<TextRange, TextRange, TextRange> getInfo() {
+    return myInfo;
+  }
+
+  //todo [roma] regexp
+  @Nullable
+  static Trinity<TextRange, TextRange, TextRange> parseExceptionLine(final String line) {
+    int startIdx;
+    if (line.startsWith(AT_PREFIX)){
+      startIdx = 0;
+    }
+    else{
+      startIdx = line.indexOf(STANDALONE_AT);
+      if (startIdx < 0) {
+        startIdx = line.indexOf(AT_PREFIX);
+      }
+
+      if (startIdx < 0) {
+        startIdx = -1;
+      }
+    }
+
+    final int lparenIdx = line.indexOf('(', startIdx);
+    if (lparenIdx < 0) return null;
+    final int dotIdx = line.lastIndexOf('.', lparenIdx);
+    if (dotIdx < 0 || dotIdx < startIdx) return null;
+
+    final int rparenIdx = line.indexOf(')', lparenIdx);
+    if (rparenIdx < 0) return null;
+
+    // class, method, link
+    return Trinity.create(new TextRange(startIdx + 1 + (startIdx >= 0 ? AT.length() : 0), handleSpaces(line, dotIdx, -1, true)),
+                          new TextRange(handleSpaces(line, dotIdx + 1, 1, true), handleSpaces(line, lparenIdx + 1, -1, true)),
+                          new TextRange(lparenIdx, rparenIdx));
+  }
+
+  private static int handleSpaces(String line, int pos, int delta, boolean skip) {
+    int len = line.length();
+    while (pos >= 0 && pos < len) {
+      final char c = line.charAt(pos);
+      if (skip != Character.isSpaceChar(c)) break;
+      pos += delta;
+    }
+    return pos;
+  }
+
+  @Nullable
+  static OpenFileHyperlinkInfo getOpenFileHyperlinkInfo(Filter.Result result) {
+    if (result.hyperlinkInfo instanceof MyHyperlinkInfo) {
+      MyHyperlinkInfo info = (MyHyperlinkInfo)result.hyperlinkInfo;
+      return new OpenFileHyperlinkInfo(info.myProject, info.myVirtualFile, info.myLineNumber);
+    }
+    return null;
+  }
+
+  private static class MyHyperlinkInfo implements FileHyperlinkInfo {
+    private final VirtualFile myVirtualFile;
+    private final int myLineNumber;
+    private final Project myProject;
+
+    public MyHyperlinkInfo(@NotNull Project project, @NotNull VirtualFile virtualFile, int lineNumber) {
+      myProject = project;
+      myVirtualFile = virtualFile;
+      myLineNumber = lineNumber;
+    }
+
+    @Override
+    public void navigate(Project project) {
+      VirtualFile currentVirtualFile = null;
+
+      AccessToken accessToken = ReadAction.start();
+
+      try {
+        if (!myVirtualFile.isValid()) return;
+
+        PsiFile psiFile = PsiManager.getInstance(project).findFile(myVirtualFile);
+        if (psiFile != null) {
+          PsiElement navigationElement = psiFile.getNavigationElement(); // Sources may be downloaded.
+          if (navigationElement instanceof PsiFile) {
+            currentVirtualFile = ((PsiFile)navigationElement).getVirtualFile();
+          }
+        }
+
+        if (currentVirtualFile == null) {
+          currentVirtualFile = myVirtualFile;
+        }
+      }
+      finally {
+        accessToken.finish();
+      }
+
+      new OpenFileHyperlinkInfo(myProject, currentVirtualFile, myLineNumber - 1).navigate(project);
+    }
+
+    @Nullable
+    @Override
+    public OpenFileDescriptor getDescriptor() {
+      return new OpenFileDescriptor(myProject, myVirtualFile, myLineNumber);
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java b/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java
new file mode 100644
index 0000000..fbc8144
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/FacetEditorsFactory.java
@@ -0,0 +1,46 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.facet.ui;
+
+import com.intellij.facet.ui.libraries.*;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class FacetEditorsFactory {
+  public static FacetEditorsFactory getInstance() {
+    return ServiceManager.getService(FacetEditorsFactory.class);
+  }
+
+
+  public abstract FacetLibrariesValidator createLibrariesValidator(@NotNull LibraryInfo[] libraries, 
+                                                                   FacetLibrariesValidatorDescription description,
+                                                                   FacetEditorContext context,
+                                                                   final FacetValidatorsManager validatorsManager);
+
+  public abstract FacetLibrariesValidator createLibrariesValidator(@NotNull final LibraryInfo[] libraries,
+                                                                   @NotNull final Module module,
+                                                                   @NotNull final String libraryName);
+
+  public abstract LibrariesValidationComponent createLibrariesValidationComponent(LibraryInfo[] libraryInfos, Module module, 
+                                                                         String defaultLibraryName);
+
+  public abstract MultipleFacetEditorHelper createMultipleFacetEditorHelper();
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java
new file mode 100644
index 0000000..24ad0a1
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidator.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.facet.ui.libraries;
+
+import com.intellij.facet.ui.FacetEditorValidator;
+import com.intellij.facet.Facet;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public abstract class FacetLibrariesValidator extends FacetEditorValidator {
+
+  public abstract void setRequiredLibraries(LibraryInfo[] requiredLibraries);
+
+  public abstract void setDescription(@NotNull FacetLibrariesValidatorDescription description);
+
+  public abstract void onFacetInitialized(Facet facet);
+
+  public abstract boolean isLibrariesAdded();
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java
new file mode 100644
index 0000000..0b2c44e
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/FacetLibrariesValidatorDescription.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.facet.ui.libraries;
+
+import com.intellij.facet.Facet;
+import com.intellij.openapi.roots.libraries.Library;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class FacetLibrariesValidatorDescription {
+  private final String myDefaultLibraryName;
+
+  public FacetLibrariesValidatorDescription(final @NonNls String defaultLibraryName) {
+    myDefaultLibraryName = defaultLibraryName;
+  }
+
+  @NonNls
+  public String getDefaultLibraryName() {
+    return myDefaultLibraryName;
+  }
+
+
+  public void onLibraryAdded(final Facet facet, @NotNull Library library) {
+  }
+}
diff --git a/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java b/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java
new file mode 100644
index 0000000..6dfa6a5
--- /dev/null
+++ b/java/openapi/src/com/intellij/facet/ui/libraries/LibrariesValidationComponent.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.facet.ui.libraries;
+
+import javax.swing.*;
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface LibrariesValidationComponent {
+
+  JComponent getComponent();
+
+  void validate();
+
+  void setupLibraries();
+
+  boolean isValid();
+
+  void addValidityListener(ValidityListener listener);
+
+  void removeValidityListener(ValidityListener listener);
+
+  interface ValidityListener extends EventListener {
+    void valididyChanged(boolean isValid);
+  }
+}
diff --git a/java/openapi/src/com/intellij/ide/IconUtilEx.java b/java/openapi/src/com/intellij/ide/IconUtilEx.java
new file mode 100644
index 0000000..566b1a3
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/IconUtilEx.java
@@ -0,0 +1,44 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Iconable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IconUtil;
+import com.intellij.util.xml.ElementPresentationManager;
+
+import javax.swing.*;
+
+public class IconUtilEx {
+
+  public static Icon getIcon(Object object, @Iconable.IconFlags int flags, Project project) {
+    if (object instanceof PsiElement) {
+      return ((PsiElement)object).getIcon(flags);
+    }
+    if (object instanceof Module) {
+      return ModuleType.get((Module)object).getIcon();
+    }
+    if (object instanceof VirtualFile) {
+      VirtualFile file = (VirtualFile)object;
+      return IconUtil.getIcon(file, flags, project);
+    }
+    return ElementPresentationManager.getIcon(object);
+  }
+}
diff --git a/java/openapi/src/com/intellij/ide/package.html b/java/openapi/src/com/intellij/ide/package.html
new file mode 100644
index 0000000..1c297c7
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for accessing common IDEA actions, services and user interface components.  
+</body></html>
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java b/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java
new file mode 100644
index 0000000..1a6b681
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteDragEventListener.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.palette;
+
+/**
+ * @author yole
+ */
+public interface PaletteDragEventListener {
+  void dropActionChanged(int gestureModifiers);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java
new file mode 100644
index 0000000..a19c1ab
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteGroup.java
@@ -0,0 +1,65 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.palette;
+
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface PaletteGroup {
+  PaletteGroup[] EMPTY_ARRAY = new PaletteGroup[0];
+
+  PaletteItem[] getItems();
+
+  /**
+   * Returns the text of the group header for the palette group.
+   *
+   * @return the text of the group header for the palette group, or null if no header should be shown.
+   */
+  @Nullable String getName();
+
+  String getTabName();
+
+  /**
+   * Returns the action group from which the context menu is built when the palette
+   * item is right-clicked.
+   *
+   * @return the action group, or null if no context menu should be shown.
+   */
+  @Nullable ActionGroup getPopupActionGroup();
+
+  /**
+   * Returns the data for the specified data constant.
+   *
+   * @param project the project in the context of which data is requested.
+   * @param dataId  the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}).
+   * @return the data item, or null if no data is available for this constant.
+   */
+  @Nullable Object getData(Project project, String dataId);
+
+  /**
+   * Processes the drop of a palette item on the specified index in the palette group.
+   *
+   * @param project the project to which the drop target palette belongs.
+   * @param item    the dropped item.
+   * @param index   the index at which the dropped item should be inserted (from 0 to getItems().length).
+   */
+  void handleDrop(Project project, PaletteItem item, int index);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteItem.java b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java
new file mode 100644
index 0000000..372839d
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteItem.java
@@ -0,0 +1,56 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.palette;
+
+import com.intellij.ide.dnd.DnDDragStartBean;
+import com.intellij.openapi.actionSystem.ActionGroup;
+import com.intellij.openapi.project.Project;
+import com.intellij.ui.ColoredListCellRenderer;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author yole
+ */
+public interface PaletteItem {
+  void customizeCellRenderer(ColoredListCellRenderer cellRenderer,
+                             boolean selected,
+                             boolean hasFocus);
+
+  /**
+   * Processes dragging the item.
+   *
+   * @return the drag start bean for the drag process, or null if the item cannot be dragged.
+   */
+  @Nullable DnDDragStartBean startDragging();
+
+  /**
+   * Returns the action group from which the context menu is built when the palette
+   * item is right-clicked.
+   *
+   * @return the action group, or null if no context menu should be shown.
+   */
+  @Nullable ActionGroup getPopupActionGroup();
+
+  /**
+   * Returns the data for the specified data constant.
+   *
+   * @param project the project in the context of which data is requested.
+   * @param dataId  the data constant id (see {@link com.intellij.openapi.actionSystem.PlatformDataKeys}).
+   * @return the data item, or null if no data is available for this constant.
+   */
+  @Nullable Object getData(Project project, String dataId);
+}
diff --git a/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java b/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java
new file mode 100644
index 0000000..3f1b99d
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/palette/PaletteItemProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.palette;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.vfs.VirtualFile;
+
+import java.beans.PropertyChangeListener;
+
+/**
+ * @author yole
+ */
+public interface PaletteItemProvider {
+  ExtensionPointName<PaletteItemProvider> EP_NAME = ExtensionPointName.create("com.intellij.paletteItemProvider");
+
+  PaletteGroup[] getActiveGroups(VirtualFile virtualFile);
+
+  void addListener(PropertyChangeListener listener);
+  void removeListener(PropertyChangeListener listener);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/ClassFilter.java b/java/openapi/src/com/intellij/ide/util/ClassFilter.java
new file mode 100644
index 0000000..8b1fc2e
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/ClassFilter.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiUtil;
+
+/**
+* @author traff
+*/
+public interface ClassFilter {
+  ClassFilter INSTANTIABLE = new ClassFilter() {
+    public boolean isAccepted(PsiClass aClass) {
+      return PsiUtil.isInstantiatable(aClass);
+    }
+  };
+
+  boolean isAccepted(PsiClass aClass);
+  ClassFilter ALL = new ClassFilter() {
+    public boolean isAccepted(PsiClass aClass) {
+      return true;
+    }
+  };
+
+  interface ClassFilterWithScope extends ClassFilter {
+    GlobalSearchScope getScope();
+  }
+}
diff --git a/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java b/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java
new file mode 100644
index 0000000..9a9536c
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/TreeClassChooser.java
@@ -0,0 +1,35 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDirectory;
+
+/**
+ * User: anna
+ * Date: Jan 24, 2005
+ */
+public interface TreeClassChooser extends TreeChooser<PsiClass> {
+  PsiClass getSelected();
+
+  void select(final PsiClass aClass);
+
+  void selectDirectory(final PsiDirectory directory);
+
+  void showDialog();
+
+  void showPopup();
+}
diff --git a/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java b/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java
new file mode 100644
index 0000000..2a8d4cd
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/TreeClassChooserFactory.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * User: anna
+ * Date: Jan 25, 2005
+ */
+public abstract class TreeClassChooserFactory {
+
+  public static TreeClassChooserFactory getInstance(Project project) {
+    return ServiceManager.getService(project, TreeClassChooserFactory.class);
+  }
+
+
+  @NotNull
+  public abstract TreeClassChooser createWithInnerClassesScopeChooser(String title,
+                                                                      GlobalSearchScope scope,
+                                                                      final ClassFilter classFilter,
+                                                                      @Nullable PsiClass initialClass);
+
+
+  @NotNull
+  public abstract TreeClassChooser createNoInnerClassesScopeChooser(String title,
+                                                                    GlobalSearchScope scope,
+                                                                    ClassFilter classFilter,
+                                                                    @Nullable PsiClass initialClass);
+
+
+  @NotNull
+  public abstract TreeClassChooser createProjectScopeChooser(String title, @Nullable PsiClass initialClass);
+
+
+  @NotNull
+  public abstract TreeClassChooser createProjectScopeChooser(String title);
+
+
+  @NotNull
+  public abstract TreeClassChooser createAllProjectScopeChooser(String title);
+
+
+  @NotNull
+  public abstract TreeClassChooser createInheritanceClassChooser(String title,
+                                                                 GlobalSearchScope scope,
+                                                                 PsiClass base,
+                                                                 boolean acceptsSelf,
+                                                                 boolean acceptInner,
+                                                                 Condition<? super PsiClass> additionalCondition);
+
+  @NotNull
+  public abstract TreeClassChooser createInheritanceClassChooser(String title,
+                                                                 GlobalSearchScope scope,
+                                                                 PsiClass base,
+                                                                 PsiClass initialClass);
+
+  @NotNull
+  public abstract TreeClassChooser createInheritanceClassChooser(String title,
+                                                                 GlobalSearchScope scope,
+                                                                 PsiClass base,
+                                                                 PsiClass initialClass,
+                                                                 ClassFilter classFilter);
+
+
+  @NotNull
+  public abstract TreeFileChooser createFileChooser(@NotNull String title,
+                                                    @Nullable PsiFile initialFile,
+                                                    @Nullable FileType fileType,
+                                                    @Nullable TreeFileChooser.PsiFileFilter filter);
+
+
+  @NotNull
+  public abstract TreeFileChooser createFileChooser(@NotNull String title,
+                                                    @Nullable PsiFile initialFile,
+                                                    @Nullable FileType fileType,
+                                                    @Nullable TreeFileChooser.PsiFileFilter filter,
+                                                    boolean disableStructureProviders);
+
+
+  @NotNull
+  public abstract TreeFileChooser createFileChooser(@NotNull String title,
+                                                    @Nullable PsiFile initialFile,
+                                                    @Nullable FileType fileType,
+                                                    @Nullable TreeFileChooser.PsiFileFilter filter,
+                                                    boolean disableStructureProviders,
+                                                    boolean showLibraryContents);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/package.html b/java/openapi/src/com/intellij/ide/util/package.html
new file mode 100644
index 0000000..7d974c1
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for accessing additional user interface services and the generic
+tree view framework.
+</body></html>
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java b/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java
new file mode 100644
index 0000000..b7224d0
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/JavaModuleBuilder.java
@@ -0,0 +1,159 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util.projectWizard;
+
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.projectRoots.JavaSdkType;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.CompilerModuleExtension;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+public class JavaModuleBuilder extends ModuleBuilder implements SourcePathsBuilder {
+  private String myCompilerOutputPath;
+  // Pair<Source Path, Package Prefix>
+  private List<Pair<String,String>> mySourcePaths;
+  // Pair<Library path, Source path>
+  private final List<Pair<String, String>> myModuleLibraries = new ArrayList<Pair<String, String>>();
+
+  public final void setCompilerOutputPath(String compilerOutputPath) {
+    myCompilerOutputPath = acceptParameter(compilerOutputPath);
+  }
+
+  public List<Pair<String,String>> getSourcePaths() {
+    if (mySourcePaths == null) {
+      final List<Pair<String, String>> paths = new ArrayList<Pair<String, String>>();
+      @NonNls final String path = getContentEntryPath() + File.separator + "src";
+      new File(path).mkdirs();
+      paths.add(Pair.create(path, ""));
+      return paths;
+    }
+    return mySourcePaths;
+  }
+
+  public void setSourcePaths(List<Pair<String,String>> sourcePaths) {
+    mySourcePaths = sourcePaths != null? new ArrayList<Pair<String, String>>(sourcePaths) : null;
+  }
+
+  public void addSourcePath(Pair<String,String> sourcePathInfo) {
+    if (mySourcePaths == null) {
+      mySourcePaths = new ArrayList<Pair<String, String>>();
+    }
+    mySourcePaths.add(sourcePathInfo);
+  }
+
+  public ModuleType getModuleType() {
+    return StdModuleTypes.JAVA;
+  }
+
+  @Override
+  public boolean isSuitableSdkType(SdkTypeId sdkType) {
+    return sdkType instanceof JavaSdkType;
+  }
+
+  @Nullable
+  @Override
+  public ModuleWizardStep modifySettingsStep(SettingsStep settingsStep) {
+    return StdModuleTypes.JAVA.modifySettingsStep(settingsStep, this);
+  }
+
+  public void setupRootModel(ModifiableRootModel rootModel) throws ConfigurationException {
+    final CompilerModuleExtension compilerModuleExtension = rootModel.getModuleExtension(CompilerModuleExtension.class);
+    compilerModuleExtension.setExcludeOutput(true);
+    if (myJdk != null){
+      rootModel.setSdk(myJdk);
+    } else {
+      rootModel.inheritSdk();
+    }
+
+    ContentEntry contentEntry = doAddContentEntry(rootModel);
+    if (contentEntry != null) {
+      final List<Pair<String,String>> sourcePaths = getSourcePaths();
+
+      if (sourcePaths != null) {
+        for (final Pair<String, String> sourcePath : sourcePaths) {
+          String first = sourcePath.first;
+          new File(first).mkdirs();
+          final VirtualFile sourceRoot = LocalFileSystem.getInstance()
+            .refreshAndFindFileByPath(FileUtil.toSystemIndependentName(first));
+          if (sourceRoot != null) {
+            contentEntry.addSourceFolder(sourceRoot, false, sourcePath.second);
+          }
+        }
+      }
+    }
+
+    if (myCompilerOutputPath != null) {
+      // should set only absolute paths
+      String canonicalPath;
+      try {
+        canonicalPath = FileUtil.resolveShortWindowsName(myCompilerOutputPath);
+      }
+      catch (IOException e) {
+        canonicalPath = myCompilerOutputPath;
+      }
+      compilerModuleExtension
+        .setCompilerOutputPath(VfsUtil.pathToUrl(FileUtil.toSystemIndependentName(canonicalPath)));
+    }
+    else {
+      compilerModuleExtension.inheritCompilerOutputPath(true);
+    }
+
+    LibraryTable libraryTable = rootModel.getModuleLibraryTable();
+    for (Pair<String, String> libInfo : myModuleLibraries) {
+      final String moduleLibraryPath = libInfo.first;
+      final String sourceLibraryPath = libInfo.second;
+      Library library = libraryTable.createLibrary();
+      Library.ModifiableModel modifiableModel = library.getModifiableModel();
+      modifiableModel.addRoot(getUrlByPath(moduleLibraryPath), OrderRootType.CLASSES);
+      if (sourceLibraryPath != null) {
+        modifiableModel.addRoot(getUrlByPath(sourceLibraryPath), OrderRootType.SOURCES);
+      }
+      modifiableModel.commit();
+    }
+  }
+
+  private static String getUrlByPath(final String path) {
+    return VfsUtil.getUrlForLibraryRoot(new File(path));
+  }
+
+  public void addModuleLibrary(String moduleLibraryPath, String sourcePath) {
+    myModuleLibraries.add(Pair.create(moduleLibraryPath,sourcePath));
+  }
+
+  @Nullable
+  protected static String getPathForOutputPathStep() {
+    return null;
+  }
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java b/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java
new file mode 100644
index 0000000..9cb5fa0
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/ProjectWizardStepFactory.java
@@ -0,0 +1,78 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ide.util.projectWizard;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkType;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ui.configuration.ModulesProvider;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+
+/**
+ * A factory for creating some commonly used project wizards steps
+ */
+public abstract class ProjectWizardStepFactory {
+
+  public static ProjectWizardStepFactory getInstance() {
+    return ServiceManager.getService(ProjectWizardStepFactory.class);
+  }
+  /**
+   * @deprecated
+   */
+  public abstract ModuleWizardStep createNameAndLocationStep(WizardContext wizardContext, JavaModuleBuilder builder, ModulesProvider modulesProvider, Icon icon, @NonNls String helpId);
+
+  public abstract ModuleWizardStep createNameAndLocationStep(WizardContext wizardContext);
+
+  public abstract ModuleWizardStep createOutputPathPathsStep(ModuleWizardStep nameAndLocationStep, JavaModuleBuilder builder, Icon icon, @NonNls String helpId);
+
+  /**
+   * @deprecated Use another version of this method:
+   * @see com.intellij.ide.util.projectWizard.ProjectWizardStepFactory#createSourcePathsStep(WizardContext, SourcePathsBuilder, javax.swing.Icon, String) 
+   */
+  public abstract ModuleWizardStep createSourcePathsStep(ModuleWizardStep nameAndLocationStep, SourcePathsBuilder builder, Icon icon, @NonNls String helpId);
+
+  public abstract ModuleWizardStep createSourcePathsStep(WizardContext context, SourcePathsBuilder builder, Icon icon, @NonNls String helpId);
+
+  /**
+   * @deprecated
+   */
+  public abstract ModuleWizardStep createProjectJdkStep(WizardContext context, JavaModuleBuilder builder, Computable<Boolean> isVisibile, Icon icon, @NonNls String helpId);
+
+  public abstract ModuleWizardStep createProjectJdkStep(WizardContext context, SdkType type, JavaModuleBuilder builder, Computable<Boolean> isVisibile, Icon icon, @NonNls String helpId);
+
+  public abstract ModuleWizardStep createProjectJdkStep(final WizardContext wizardContext);
+
+  @Nullable
+  public abstract Sdk getNewProjectSdk(WizardContext wizardContext);
+
+  /**
+   * @deprecated use {@link #createSupportForFrameworksStep(WizardContext, ModuleBuilder, com.intellij.openapi.roots.ui.configuration.ModulesProvider)} instead
+   */
+  @Nullable
+  public abstract ModuleWizardStep createSupportForFrameworksStep(WizardContext context, ModuleBuilder builder);
+
+  @Nullable
+  public abstract ModuleWizardStep createSupportForFrameworksStep(WizardContext context, ModuleBuilder builder, ModulesProvider modulesProvider);
+
+  public abstract ModuleWizardStep createJavaSettingsStep(SettingsStep settingsStep, ModuleBuilder moduleBuilder, @NotNull Condition<SdkTypeId> sdkFilter);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java b/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java
new file mode 100644
index 0000000..bbcc289
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/SourcePathsBuilder.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ide.util.projectWizard;
+
+import com.intellij.openapi.options.ConfigurationException;
+import com.intellij.openapi.util.Pair;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Jul 20, 2007
+ */
+public interface SourcePathsBuilder {
+  @Nullable
+  String getContentEntryPath();
+
+  void setContentEntryPath(String moduleRootPath);
+
+  List<Pair<String,String>> getSourcePaths() throws ConfigurationException;
+
+  void setSourcePaths(List<Pair<String,String>> sourcePaths);
+
+  void addSourcePath(Pair<String,String> sourcePathInfo);
+}
diff --git a/java/openapi/src/com/intellij/ide/util/projectWizard/package.html b/java/openapi/src/com/intellij/ide/util/projectWizard/package.html
new file mode 100644
index 0000000..0abea7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/ide/util/projectWizard/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for building customized "New Project" and "New Module" wizards.
+</body></html>
diff --git a/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
new file mode 100644
index 0000000..602ee86
--- /dev/null
+++ b/java/openapi/src/com/intellij/lang/refactoring/JavaNamesValidator.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.lang.refactoring;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaPsiFacade;
+
+/**
+ * Default NamesValidator interface implementation. Uses java language keyword set and java language rules for identifier.
+ */
+public class JavaNamesValidator implements NamesValidator {
+  public boolean isKeyword(String name, Project project) {
+    return JavaPsiFacade.getInstance(project).getNameHelper().isKeyword(name);
+  }
+
+  public boolean isIdentifier(String name, Project project) {
+    return JavaPsiFacade.getInstance(project).getNameHelper().isIdentifier(name);
+  }
+}
diff --git a/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java
new file mode 100644
index 0000000..da04094
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/actionSystem/DataKeys.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: yole
+ * Date: 23.10.2006
+ * Time: 17:00:37
+ */
+package com.intellij.openapi.actionSystem;
+
+import com.intellij.openapi.vcs.changes.Change;
+import com.intellij.openapi.vcs.changes.ChangeList;
+
+@SuppressWarnings({"deprecation"})
+public final class DataKeys extends LangDataKeys {
+  private DataKeys() {
+  }
+
+  @Deprecated
+  public static final DataKey<ChangeList[]> CHANGE_LISTS = DataKey.create("vcs.ChangeList");
+  @Deprecated
+  public static final DataKey<Change[]> CHANGES = DataKey.create("vcs.Change");
+
+}
+
diff --git a/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
new file mode 100644
index 0000000..0ee5397
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/module/LanguageLevelUtil.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.module;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.JavaSdkVersion;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class LanguageLevelUtil {
+  private LanguageLevelUtil() {
+  }
+
+  @NotNull
+  public static LanguageLevel getEffectiveLanguageLevel(@NotNull final Module module) {
+    ApplicationManager.getApplication().assertReadAccessAllowed();
+    LanguageLevel level = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+    if (level != null) return level;
+    return LanguageLevelProjectExtension.getInstance(module.getProject()).getLanguageLevel();
+  }
+
+  @NotNull
+  public static LanguageLevel getLanguageLevelForFile(final VirtualFile file) {
+    if (file == null) return LanguageLevel.HIGHEST;
+
+    if (file.isDirectory()) {
+      final LanguageLevel ll = file.getUserData(LanguageLevel.KEY);
+      return ll != null ? ll : 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/openapi/module/StdModuleTypes.java b/java/openapi/src/com/intellij/openapi/module/StdModuleTypes.java
new file mode 100644
index 0000000..66b33e6
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/module/StdModuleTypes.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.module;
+
+public class StdModuleTypes {
+  // predefined module types
+  public static ModuleType JAVA;
+
+  private StdModuleTypes() {
+  }
+
+  static {
+    JAVA = instantiate("com.intellij.openapi.module.JavaModuleType");
+  }
+
+  private static ModuleType instantiate(String className) {
+    try {
+      return (ModuleType)Class.forName(className).newInstance();
+    }
+    catch (Exception e) {
+      throw new IllegalArgumentException(e);
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
new file mode 100644
index 0000000..88a5c55
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdk.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.projectRoots;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.components.ApplicationComponent;
+import com.intellij.openapi.projectRoots.impl.SdkVersionUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public abstract class JavaSdk extends SdkType implements JavaSdkType, ApplicationComponent {
+  public JavaSdk(@NonNls String name) {
+    super(name);
+  }
+
+  public static JavaSdk getInstance() {
+    return ApplicationManager.getApplication().getComponent(JavaSdk.class);
+  }
+
+  public final Sdk createJdk(@NotNull String jdkName, @NotNull String jreHome) {
+    return createJdk(jdkName, jreHome, true);
+  }
+
+  /**
+   * @deprecated use {@link #isOfVersionOrHigher(Sdk, JavaSdkVersion)} instead
+   */
+  public abstract int compareTo(@NotNull String versionString, @NotNull String versionNumber);
+
+  public abstract Sdk createJdk(@NonNls String jdkName, @NotNull String home, boolean isJre);
+
+  @Nullable
+  public abstract JavaSdkVersion getVersion(@NotNull Sdk sdk);
+
+  @Nullable
+  public abstract JavaSdkVersion getVersion(@NotNull String versionString);
+
+  public abstract boolean isOfVersionOrHigher(@NotNull Sdk sdk, @NotNull JavaSdkVersion version);
+
+  public static boolean checkForJdk(File file) {
+    return JdkUtil.checkForJdk(file);
+  }
+
+  public static boolean checkForJre(String file) {
+    return JdkUtil.checkForJre(file);
+  }
+
+  @Nullable
+  public static String getJdkVersion(final String sdkHome) {
+    return SdkVersionUtil.detectJdkVersion(sdkHome);
+  }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java
new file mode 100644
index 0000000..6c85da3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/JavaSdkVersionUtil.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.projectRoots;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.psi.PsiElement;
+
+/**
+ * User: anna
+ * Date: 3/28/12
+ */
+public class JavaSdkVersionUtil {
+  public static boolean isAtLeast(PsiElement element, JavaSdkVersion minVersion) {
+    final Module module = ModuleUtil.findModuleForPsiElement(element);
+    if (module != null) {
+      final Sdk sdk = ModuleRootManager.getInstance(module).getSdk();
+      if (sdk != null && sdk.getSdkType() instanceof JavaSdk) {
+        final JavaSdkVersion version = JavaSdk.getInstance().getVersion(sdk);
+        return version != null && version.isAtLeast(minVersion);
+      }
+    }
+    return true;
+  }
+}
diff --git a/java/openapi/src/com/intellij/openapi/projectRoots/package.html b/java/openapi/src/com/intellij/openapi/projectRoots/package.html
new file mode 100644
index 0000000..ca5e461
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/projectRoots/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with JDKs and registering new JDK types.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java b/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java
new file mode 100644
index 0000000..42e5f38
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/FileIndexUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.fileTypes.StdFileTypes;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class FileIndexUtil {
+  private FileIndexUtil() {
+  }
+
+  public static boolean isJavaSourceFile(@NotNull Project project, @NotNull VirtualFile file) {
+    FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    if (file.isDirectory()) return false;
+    if (file.getFileType() != StdFileTypes.JAVA) return false;
+    if (fileTypeManager.isFileIgnored(file)) return false;
+    return ProjectRootManager.getInstance(project).getFileIndex().isInSource(file);
+  }
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java b/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
new file mode 100644
index 0000000..e6db187
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/LanguageLevelModuleExtension.java
@@ -0,0 +1,122 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * User: anna
+ * Date: 27-Dec-2007
+ */
+package com.intellij.openapi.roots;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.WriteExternalException;
+import com.intellij.pom.java.LanguageLevel;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+public class LanguageLevelModuleExtension extends ModuleExtension<LanguageLevelModuleExtension> {
+  @NonNls private static final String LANGUAGE_LEVEL_ELEMENT_NAME = "LANGUAGE_LEVEL";
+  private Module myModule;
+  private final boolean myWritable;
+  private static final Logger LOG = Logger.getInstance("#" + LanguageLevelModuleExtension.class.getName());
+
+  public static LanguageLevelModuleExtension getInstance(final Module module) {
+    return ModuleRootManager.getInstance(module).getModuleExtension(LanguageLevelModuleExtension.class);
+  }
+
+  private LanguageLevel myLanguageLevel;
+  private final LanguageLevelModuleExtension mySource;
+
+  public LanguageLevelModuleExtension(Module module) {
+    myModule = module;
+    mySource = null;
+    myWritable = false;
+  }
+
+  public LanguageLevelModuleExtension(final LanguageLevelModuleExtension source, boolean writable) {
+    myWritable = writable;
+    myModule = source.myModule;
+    myLanguageLevel = source.myLanguageLevel;
+    mySource = source;
+  }
+
+  public void setLanguageLevel(final LanguageLevel languageLevel) {
+    LOG.assertTrue(myWritable, "Writable model can be retrieved from writable ModifiableRootModel");
+    myLanguageLevel = languageLevel;
+  }
+
+  @Nullable
+  public LanguageLevel getLanguageLevel() {
+    return myLanguageLevel;
+  }
+
+  @Override
+  public void readExternal(final Element element) throws InvalidDataException {
+    final String languageLevel = element.getAttributeValue(LANGUAGE_LEVEL_ELEMENT_NAME);
+    if (languageLevel != null) {
+      try {
+        myLanguageLevel = LanguageLevel.valueOf(languageLevel);
+      }
+      catch (IllegalArgumentException e) {
+        //bad value was stored
+      }
+    }
+  }
+
+  @Override
+  public void writeExternal(final Element element) throws WriteExternalException {
+    if (myLanguageLevel != null) {
+      element.setAttribute(LANGUAGE_LEVEL_ELEMENT_NAME, myLanguageLevel.toString());
+    }
+  }
+
+  @Override
+  public ModuleExtension getModifiableModel(final boolean writable) {
+    return new LanguageLevelModuleExtension(this, writable);
+  }
+
+  @Override
+  public void commit() {
+    if (mySource != null && mySource.myLanguageLevel != myLanguageLevel) {
+      if (myModule.isLoaded()) { //do not reload project for non-committed modules: j2me|project imports
+        if (mySource.myLanguageLevel != myLanguageLevel) {
+          final LanguageLevelProjectExtension languageLevelProjectExtension =
+            LanguageLevelProjectExtension.getInstance(myModule.getProject());
+          final LanguageLevel projectLanguageLevel = languageLevelProjectExtension.getLanguageLevel();
+          final boolean explicit2ImplicitProjectLevel = myLanguageLevel == null && mySource.myLanguageLevel == projectLanguageLevel;
+          final boolean implicit2ExplicitProjectLevel = mySource.myLanguageLevel == null && myLanguageLevel == projectLanguageLevel;
+          if (!(explicit2ImplicitProjectLevel || implicit2ExplicitProjectLevel)) {
+            languageLevelProjectExtension.reloadProjectOnLanguageLevelChange(myLanguageLevel == null ? projectLanguageLevel : myLanguageLevel, true);
+          }
+        }
+      }
+      mySource.myLanguageLevel = myLanguageLevel;
+    }
+  }
+
+  @Override
+  public boolean isChanged() {
+    return mySource != null && mySource.myLanguageLevel != myLanguageLevel;
+  }
+
+  @Override
+  public void dispose() {
+    myModule = null;
+    myLanguageLevel = null;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java
new file mode 100644
index 0000000..f92d61b
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/JarVersionDetectionUtil.java
@@ -0,0 +1,110 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.roots.libraries;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.LibraryOrderEntry;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.IOException;
+import java.io.InputStream;
+import java.util.List;
+import java.util.jar.Attributes;
+import java.util.jar.JarFile;
+import java.util.jar.Manifest;
+import java.util.zip.ZipEntry;
+
+public class JarVersionDetectionUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.roots.libraries.JarVersionDetectionUtil");
+
+  private JarVersionDetectionUtil() {
+  }
+
+  @Nullable
+  public static String detectJarVersion(@NotNull final String detectionClass, @NotNull Module module) {
+    try {
+      return detectJarVersion(getDetectionJar(detectionClass, module));
+    }
+    catch (IOException e) {
+      return null;
+    }
+  }
+
+  @Nullable
+  public static String detectJarVersion(@NotNull String detectionClass, @NotNull List<VirtualFile> files) {
+    final VirtualFile jar = LibrariesHelper.getInstance().findRootByClass(files, detectionClass);
+    if (jar != null && jar.getFileSystem() instanceof JarFileSystem) {
+      final VirtualFile manifestFile = jar.findFileByRelativePath(JarFile.MANIFEST_NAME);
+      if (manifestFile != null) {
+        try {
+          final InputStream input = manifestFile.getInputStream();
+          try {
+            return new Manifest(input).getMainAttributes().getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+          }
+          finally {
+            input.close();
+          }
+        }
+        catch (IOException e) {
+          LOG.debug(e);
+          return null;
+        }
+      }
+    }
+    return null;
+  }
+
+  @Nullable
+  public static String detectJarVersion(com.intellij.openapi.vfs.JarFile zipFile) {
+    if (zipFile == null) {
+      return null;
+    }
+    try {
+      final com.intellij.openapi.vfs.JarFile.JarEntry zipEntry = zipFile.getEntry(JarFile.MANIFEST_NAME);
+      if (zipEntry == null) {
+        return null;
+      }
+      final InputStream inputStream = zipFile.getInputStream(zipEntry);
+      final Manifest manifest = new Manifest(inputStream);
+      final Attributes attributes = manifest.getMainAttributes();
+      return attributes.getValue(Attributes.Name.IMPLEMENTATION_VERSION);
+    }
+    catch (IOException e) {
+      return null;
+    }
+  }
+
+  @Nullable
+  private static com.intellij.openapi.vfs.JarFile getDetectionJar(final String detectionClass, Module module) throws IOException {
+      for (OrderEntry library : ModuleRootManager.getInstance(module).getOrderEntries()) {
+        if (library instanceof LibraryOrderEntry) {
+          VirtualFile file = LibrariesHelper.getInstance().findJarByClass(((LibraryOrderEntry)library).getLibrary(), detectionClass);
+          if (file != null && file.getFileSystem() instanceof JarFileSystem) {
+            return JarFileSystem.getInstance().getJarFile(file);
+          }
+        }
+      }
+    return null;
+  }
+}
+
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java b/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java
new file mode 100644
index 0000000..3367f11
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/LibrariesHelper.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots.libraries;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.List;
+
+/**
+ * author: lesya
+ */
+public abstract class LibrariesHelper {
+  public static LibrariesHelper getInstance(){
+    return ServiceManager.getService(LibrariesHelper.class);
+  }
+
+  public abstract boolean isClassAvailableInLibrary(final Library library, @NonNls final String fqn);
+
+  public abstract boolean isClassAvailable(@NonNls String[] urls, @NonNls String fqn);
+
+  @Nullable
+  public abstract VirtualFile findJarByClass(final Library library, @NonNls String fqn);
+
+  @Nullable
+  public abstract VirtualFile findRootByClass(List<VirtualFile> roots, String fqn);
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/libraries/package.html b/java/openapi/src/com/intellij/openapi/roots/libraries/package.html
new file mode 100644
index 0000000..7a8b45a
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/libraries/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for defining the contents of a library and for working with lists
+of libraries.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/package.html b/java/openapi/src/com/intellij/openapi/roots/package.html
new file mode 100644
index 0000000..0f1e1b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for defining the structure and contents of projects and modules
+and the libraries used in them.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java b/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java
new file mode 100644
index 0000000..85cb7d3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/OrderEntryAppearanceService.java
@@ -0,0 +1,47 @@
+/*
+ * 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.openapi.roots.ui;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ContentFolder;
+import com.intellij.openapi.roots.OrderEntry;
+import com.intellij.openapi.roots.libraries.Library;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class OrderEntryAppearanceService {
+  public static OrderEntryAppearanceService getInstance() {
+    return ServiceManager.getService(OrderEntryAppearanceService.class);
+  }
+
+  @NotNull
+  public abstract CellAppearanceEx forOrderEntry(Project project, @NotNull OrderEntry orderEntry, boolean selected);
+
+  @NotNull
+  public abstract CellAppearanceEx forLibrary(Project project, @NotNull Library library, boolean hasInvalidRoots);
+
+  @NotNull
+  public abstract CellAppearanceEx forJdk(@Nullable Sdk jdk, boolean isInComboBox, boolean selected, boolean showVersion);
+
+  @NotNull
+  public abstract CellAppearanceEx forContentFolder(@NotNull ContentFolder folder);
+
+  @NotNull
+  public abstract CellAppearanceEx forModule(@NotNull Module module);
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java
new file mode 100644
index 0000000..35336c3
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/DefaultModuleConfigurationEditorFactory.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.openapi.roots.ui.configuration;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.module.ModuleConfigurationEditor;
+
+public abstract class DefaultModuleConfigurationEditorFactory {
+
+  public abstract ModuleConfigurationEditor createModuleContentRootsEditor(ModuleConfigurationState state);
+
+  public abstract ModuleConfigurationEditor createClasspathEditor(ModuleConfigurationState state);
+
+  public abstract ModuleConfigurationEditor createOutputEditor(ModuleConfigurationState state);
+
+  public static DefaultModuleConfigurationEditorFactory getInstance() {
+    return ServiceManager.getService(DefaultModuleConfigurationEditorFactory.class);
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html
new file mode 100644
index 0000000..e6d3b1d
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/roots/ui/configuration/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for customizing the configuration interface for modules of specific types.
+</body></html>
diff --git a/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java b/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java
new file mode 100644
index 0000000..a0b0119
--- /dev/null
+++ b/java/openapi/src/com/intellij/openapi/ui/PackageChooser.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.openapi.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiPackage;
+
+import java.util.List;
+
+/**
+ * @author ven
+ */
+public abstract class PackageChooser extends DialogWrapper {
+  public PackageChooser(Project project, boolean canBeParent) {
+    super(project, canBeParent);
+  }
+
+  public abstract PsiPackage getSelectedPackage();
+
+  public abstract List<PsiPackage> getSelectedPackages();
+
+  public abstract void selectPackage(String qualifiedName);
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java b/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java
new file mode 100644
index 0000000..ddc7c69
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiAnnotationPattern.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiAnnotation;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiAnnotationPattern extends PsiElementPattern<PsiAnnotation, PsiAnnotationPattern> {
+  protected PsiAnnotationPattern() {
+    super(PsiAnnotation.class);
+  }
+
+  public PsiAnnotationPattern qName(final ElementPattern<String> pattern) {
+    return with(new PatternCondition<PsiAnnotation>("qName") {
+      public boolean accepts(@NotNull final PsiAnnotation psiAnnotation, final ProcessingContext context) {
+        return pattern.getCondition().accepts(psiAnnotation.getQualifiedName(), context);
+      }
+    });
+  }
+  public PsiAnnotationPattern qName(@NonNls String qname) {
+    return qName(StandardPatterns.string().equalTo(qname));
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java
new file mode 100644
index 0000000..4a900d7
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiBinaryExpressionPattern.java
@@ -0,0 +1,54 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiBinaryExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiBinaryExpressionPattern extends PsiExpressionPattern<PsiBinaryExpression, PsiBinaryExpressionPattern>{
+  protected PsiBinaryExpressionPattern() {
+    super(PsiBinaryExpression.class);
+  }
+
+  public PsiBinaryExpressionPattern left(@NotNull final ElementPattern pattern) {
+    return with(new PatternCondition<PsiBinaryExpression>("left") {
+      public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+        return pattern.getCondition().accepts(psiBinaryExpression.getLOperand(), context);
+      }
+    });
+  }
+
+  public PsiBinaryExpressionPattern right(@NotNull final ElementPattern pattern) {
+    return with(new PatternCondition<PsiBinaryExpression>("right") {
+      public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+        return pattern.getCondition().accepts(psiBinaryExpression.getROperand(), context);
+      }
+    });
+  }
+
+  public PsiBinaryExpressionPattern operation(final ElementPattern pattern) {
+    return with(new PatternCondition<PsiBinaryExpression>("operation") {
+      public boolean accepts(@NotNull final PsiBinaryExpression psiBinaryExpression, final ProcessingContext context) {
+        return pattern.getCondition().accepts(psiBinaryExpression.getOperationSign(), context);
+      }
+    });
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiClassPattern.java b/java/openapi/src/com/intellij/patterns/PsiClassPattern.java
new file mode 100644
index 0000000..d8933fd
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiClassPattern.java
@@ -0,0 +1,120 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.psi.util.InheritanceUtil;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiClassPattern extends PsiMemberPattern<PsiClass, PsiClassPattern>{
+  protected PsiClassPattern() {
+    super(PsiClass.class);
+  }
+
+  public PsiClassPattern inheritorOf(final boolean strict, final PsiClassPattern pattern) {
+    return with(new PatternCondition<PsiClass>("inheritorOf") {
+      public boolean accepts(@NotNull PsiClass psiClass, final ProcessingContext context) {
+        return isInheritor(psiClass, pattern, context, !strict);
+      }
+    });
+  }
+
+  private static boolean isInheritor(PsiClass psiClass, ElementPattern pattern, final ProcessingContext matchingContext, boolean checkThisClass) {
+    if (psiClass == null) return false;
+    if (checkThisClass && pattern.getCondition().accepts(psiClass, matchingContext)) return true;
+    if (isInheritor(psiClass.getSuperClass(), pattern, matchingContext, true)) return true;
+    for (final PsiClass aClass : psiClass.getInterfaces()) {
+      if (isInheritor(aClass, pattern, matchingContext, true)) return true;
+    }
+    return false;
+  }
+
+  public PsiClassPattern inheritorOf(final boolean strict, final String className) {
+    return with(new PatternCondition<PsiClass>("inheritorOf") {
+      public boolean accepts(@NotNull PsiClass psiClass, final ProcessingContext context) {
+        return InheritanceUtil.isInheritor(psiClass, strict, className);
+      }
+    });
+  }
+
+  public PsiClassPattern isInterface() {
+    return with(new PatternCondition<PsiClass>("isInterface") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        return psiClass.isInterface();
+      }
+    });}
+  public PsiClassPattern isAnnotationType() {
+    return with(new PatternCondition<PsiClass>("isAnnotationType") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        return psiClass.isAnnotationType();
+      }
+    });}
+
+  public PsiClassPattern withMethod(final boolean checkDeep, final ElementPattern<? extends PsiMethod> memberPattern) {
+    return with(new PatternCondition<PsiClass>("withMethod") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        for (PsiMethod method : (checkDeep ? psiClass.getAllMethods() : psiClass.getMethods())) {
+          if (memberPattern.accepts(method, context)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    });
+  }
+  public PsiClassPattern withField(final boolean checkDeep, final ElementPattern<? extends PsiField> memberPattern) {
+    return with(new PatternCondition<PsiClass>("withField") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        for (PsiField field : (checkDeep ? psiClass.getAllFields() : psiClass.getFields())) {
+          if (memberPattern.accepts(field, context)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    });
+  }
+
+   public PsiClassPattern nonAnnotationType() {
+    return with(new PatternCondition<PsiClass>("nonAnnotationType") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        return !psiClass.isAnnotationType();
+      }
+    });
+  }
+
+  public PsiClassPattern withQualifiedName(@NonNls @NotNull final String qname) {
+    return with(new PatternCondition<PsiClass>("withQualifiedName") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        return qname.equals(psiClass.getQualifiedName());
+      }
+    });
+  }
+  public PsiClassPattern withQualifiedName(@NonNls @NotNull final ElementPattern<String> qname) {
+    return with(new PatternCondition<PsiClass>("withQualifiedName") {
+      public boolean accepts(@NotNull final PsiClass psiClass, final ProcessingContext context) {
+        return qname.accepts(psiClass.getQualifiedName(), context);
+      }
+    });
+  }
+
+
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java
new file mode 100644
index 0000000..67b9cb0
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiExpressionPattern.java
@@ -0,0 +1,72 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiExpressionPattern<T extends PsiExpression, Self extends PsiExpressionPattern<T,Self>> extends PsiJavaElementPattern<T,Self> {
+  protected PsiExpressionPattern(final Class<T> aClass) {
+    super(aClass);
+  }
+
+  public Self ofType(@NotNull final ElementPattern pattern) {
+    return with(new PatternCondition<T>("ofType") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        return pattern.getCondition().accepts(t.getType(), context);
+      }
+    });
+  }
+
+  public PsiMethodCallPattern methodCall(final ElementPattern<? extends PsiMethod> method) {
+    return new PsiMethodCallPattern().and(this).with(new PatternCondition<PsiMethodCallExpression>("methodCall") {
+      public boolean accepts(@NotNull PsiMethodCallExpression callExpression, ProcessingContext context) {
+        final JavaResolveResult[] results = callExpression.getMethodExpression().multiResolve(true);
+        for (JavaResolveResult result : results) {
+          if (method.getCondition().accepts(result.getElement(), context)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    });
+  }
+
+  public Self skipParentheses(final ElementPattern<? extends PsiExpression> expressionPattern) {
+    return with(new PatternCondition<T>("skipParentheses") {
+      @Override
+      public boolean accepts(@NotNull T t, ProcessingContext context) {
+        PsiExpression expression = t;
+        while (expression instanceof PsiParenthesizedExpression) {
+          expression = ((PsiParenthesizedExpression)expression).getExpression();
+        }
+        return expressionPattern.accepts(expression, context);
+      }
+    });
+  }
+
+  public static class Capture<T extends PsiExpression> extends PsiExpressionPattern<T, Capture<T>> {
+    public Capture(final Class<T> aClass) {
+      super(aClass);
+    }
+
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java b/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java
new file mode 100644
index 0000000..0b3d634
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiFieldPattern.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiField;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class PsiFieldPattern extends PsiMemberPattern<PsiField, PsiFieldPattern>{
+  public PsiFieldPattern() {
+    super(new InitialPatternCondition<PsiField>(PsiField.class) {
+      public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+        return o instanceof PsiField;
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
new file mode 100644
index 0000000..e91eb87
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaElementPattern.java
@@ -0,0 +1,144 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiJavaElementPattern<T extends PsiElement,Self extends PsiJavaElementPattern<T,Self>> extends PsiElementPattern<T,Self> {
+  private static final @NonNls String VALUE = "value";
+
+  public PsiJavaElementPattern(final Class<T> aClass) {
+    super(aClass);
+  }
+
+  public PsiJavaElementPattern(@NotNull final InitialPatternCondition<T> condition) {
+    super(condition);
+  }
+
+  public Self annotationParam(@NonNls final String annotationQualifiedName, @NonNls final String parameterName) {
+    return annotationParam(StandardPatterns.string().equalTo(annotationQualifiedName), parameterName);
+  }
+
+  public Self annotationParam(@NonNls final String annotationQualifiedName) {
+    return annotationParam(annotationQualifiedName, VALUE);
+  }
+
+  public Self annotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
+    return withParent(
+      PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
+        PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
+          PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
+  }
+
+  public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName, @NonNls final String parameterName) {
+    return inside(true,
+      PsiJavaPatterns.psiNameValuePair().withName(parameterName).withParent(
+        PlatformPatterns.psiElement(PsiAnnotationParameterList.class).withParent(
+          PsiJavaPatterns.psiAnnotation().qName(annotationQualifiedName))));
+  }
+
+  public Self insideAnnotationParam(final ElementPattern<String> annotationQualifiedName) {
+    return insideAnnotationParam(annotationQualifiedName, VALUE);
+  }
+
+  public Self nameIdentifierOf(final Class<? extends PsiMember> aClass) {
+    return nameIdentifierOf(PsiJavaPatterns.instanceOf(aClass));
+  }
+  
+  public Self nameIdentifierOf(final ElementPattern<? extends PsiMember> pattern) {
+    return with(new PatternCondition<T>("nameIdentifierOf") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        if (!(t instanceof PsiIdentifier)) return false;
+
+        final PsiElement parent = t.getParent();
+        if (parent instanceof PsiClass && t != ((PsiClass) parent).getNameIdentifier()) return false;
+        if (parent instanceof PsiMethod && t != ((PsiMethod) parent).getNameIdentifier()) return false;
+        if (parent instanceof PsiVariable && t != ((PsiVariable) parent).getNameIdentifier()) return false;
+
+        return pattern.getCondition().accepts(parent, context);
+      }
+    });
+  }
+
+  public Self methodCallParameter(final int index, final ElementPattern<? extends PsiMethod> methodPattern) {
+    return with(new PatternCondition<T>("methodCallParameter") {
+      public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
+        final PsiElement parent = literal.getParent();
+        if (parent instanceof PsiExpressionList) {
+          final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
+          final PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
+          if (!(psiExpressions.length > index && psiExpressions[index] == literal)) return false;
+
+          final PsiElement element = psiExpressionList.getParent();
+          if (element instanceof PsiMethodCallExpression) {
+            final JavaResolveResult[] results = ((PsiMethodCallExpression)element).getMethodExpression().multiResolve(false);
+            for (JavaResolveResult result : results) {
+              final PsiElement psiElement = result.getElement();
+              if (methodPattern.getCondition().accepts(psiElement, context)) {
+                return true;
+              }
+            }
+          }
+        }
+        return false;
+      }
+    });
+  }
+
+  public Self constructorParameter(final int index, final String... fqns) {
+    return with(new PatternCondition<T>("methodCallParameter") {
+      public boolean accepts(@NotNull final T literal, final ProcessingContext context) {
+        final PsiElement parent = literal.getParent();
+        if (parent instanceof PsiExpressionList) {
+          final PsiExpressionList psiExpressionList = (PsiExpressionList)parent;
+          final PsiExpression[] psiExpressions = psiExpressionList.getExpressions();
+          if (!(psiExpressions.length > index && psiExpressions[index] == literal)) return false;
+
+          final PsiElement element = psiExpressionList.getParent();
+          if (element instanceof PsiNewExpression) {
+            PsiJavaCodeReferenceElement reference = ((PsiNewExpression)element).getClassOrAnonymousClassReference();
+            if (reference != null) {
+              String qualifiedName = reference.getQualifiedName();
+              for (String fqn : fqns) {
+                if( fqn.equals(qualifiedName)) return true;
+              }
+            }
+          }
+        }
+        return false;
+      }
+    });
+  }
+
+  public static class Capture<T extends PsiElement> extends PsiJavaElementPattern<T, Capture<T>> {
+    public Capture(final Class<T> aClass) {
+      super(aClass);
+    }
+
+    public Capture(@NotNull final InitialPatternCondition<T> condition) {
+      super(condition);
+    }
+  }
+
+
+
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
new file mode 100644
index 0000000..3de211a
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiJavaPatterns.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.*;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @author peter
+ */
+public class PsiJavaPatterns extends StandardPatterns{
+
+  public static IElementTypePattern elementType() {
+    return PlatformPatterns.elementType();
+  }
+
+  public static VirtualFilePattern virtualFile() {
+    return PlatformPatterns.virtualFile();
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiElement> psiElement() {
+    return new PsiJavaElementPattern.Capture<PsiElement>(PsiElement.class);
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiElement> psiElement(IElementType type) {
+    return psiElement().withElementType(type);
+  }
+
+  public static <T extends PsiElement> PsiJavaElementPattern.Capture<T> psiElement(final Class<T> aClass) {
+    return new PsiJavaElementPattern.Capture<T>(aClass);
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiElement> psiElement(final Class<? extends PsiElement>... classAlternatives) {
+    return new PsiJavaElementPattern.Capture<PsiElement>(new InitialPatternCondition<PsiElement>(PsiElement.class) {
+      @Override
+      public boolean accepts(@Nullable Object o, ProcessingContext context) {
+        for (Class<? extends PsiElement> classAlternative : classAlternatives) {
+          if (classAlternative.isInstance(o)) {
+            return true;
+          }
+        }
+        return false;
+      }
+    });
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiLiteralExpression> literalExpression() {
+    return literalExpression(null);
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral() {
+    return psiLiteral(null);
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiLiteral> psiLiteral(@Nullable final ElementPattern value) {
+    return new PsiJavaElementPattern.Capture<PsiLiteral>(new InitialPatternConditionPlus<PsiLiteral>(PsiLiteral.class) {
+      public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+        return o instanceof PsiLiteral && (value == null || value.accepts(((PsiLiteral)o).getValue(), context));
+      }
+
+      @Override
+      public List<ElementPattern<?>> getPatterns() {
+        return Collections.<ElementPattern<?>>singletonList(value);
+      }
+    });
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiNewExpression> psiNewExpression(@NotNull final String... fqns) {
+    return new PsiJavaElementPattern.Capture<PsiNewExpression>(new InitialPatternCondition<PsiNewExpression>(PsiNewExpression.class) {
+      public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+        if(o instanceof PsiNewExpression) {
+          PsiJavaCodeReferenceElement reference = ((PsiNewExpression)o).getClassOrAnonymousClassReference();
+          if (reference != null) {
+            for (String fqn : fqns) {
+              if( fqn.equals(reference.getQualifiedName())) return true;
+            }
+          }
+        }
+        return  false;
+      }
+    });
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiLiteralExpression> literalExpression(@Nullable final ElementPattern value) {
+    return new PsiJavaElementPattern.Capture<PsiLiteralExpression>(new InitialPatternConditionPlus<PsiLiteralExpression>(PsiLiteralExpression.class) {
+      public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+        return o instanceof PsiLiteralExpression && (value == null || value.accepts(((PsiLiteralExpression)o).getValue(), context));
+      }
+
+      @Override
+      public List<ElementPattern<?>> getPatterns() {
+        return Collections.<ElementPattern<?>>singletonList(value);
+      }
+    });
+  }
+
+  public static PsiMemberPattern.Capture psiMember() {
+    return new PsiMemberPattern.Capture();
+  }
+
+  public static PsiMethodPattern psiMethod() {
+    return new PsiMethodPattern();
+  }
+
+  public static PsiParameterPattern psiParameter() {
+    return new PsiParameterPattern();
+  }
+
+  public static PsiModifierListOwnerPattern.Capture<PsiModifierListOwner> psiModifierListOwner() {
+    return new PsiModifierListOwnerPattern.Capture<PsiModifierListOwner>(new InitialPatternCondition<PsiModifierListOwner>(PsiModifierListOwner.class) {
+      @Override
+      public boolean accepts(@Nullable Object o, ProcessingContext context) {
+        return o instanceof PsiModifierListOwner;
+      }
+    });
+  }
+  
+
+  public static PsiFieldPattern psiField() {
+    return new PsiFieldPattern();
+  }
+
+  public static PsiClassPattern psiClass() {
+    return new PsiClassPattern();
+  }
+
+  public static PsiAnnotationPattern psiAnnotation() {
+    return new PsiAnnotationPattern();
+  }
+
+  public static PsiNameValuePairPattern psiNameValuePair() {
+    return new PsiNameValuePairPattern();
+  }
+
+  public static PsiTypePattern psiType() {
+    return new PsiTypePattern();
+  }
+
+  public static PsiExpressionPattern.Capture<PsiExpression> psiExpression() {
+    return new PsiExpressionPattern.Capture<PsiExpression>(PsiExpression.class);
+  }
+
+  public static PsiBinaryExpressionPattern psiBinaryExpression() {
+    return new PsiBinaryExpressionPattern();
+  }
+
+  public static PsiTypeCastExpressionPattern psiTypeCastExpression() {
+    return new PsiTypeCastExpressionPattern();
+  }
+
+  public static PsiJavaElementPattern.Capture<PsiReferenceExpression> psiReferenceExpression() {
+    return psiElement(PsiReferenceExpression.class);
+  }
+
+  public static PsiStatementPattern.Capture<PsiExpressionStatement> psiExpressionStatement() {
+    return new PsiStatementPattern.Capture<PsiExpressionStatement>(PsiExpressionStatement.class);
+  }
+
+  public static PsiStatementPattern.Capture<PsiReturnStatement> psiReturnStatement() {
+    return new PsiStatementPattern.Capture<PsiReturnStatement>(PsiReturnStatement.class);
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java b/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java
new file mode 100644
index 0000000..d6501d7
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMemberPattern.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class PsiMemberPattern<T extends PsiMember, Self extends PsiMemberPattern<T,Self>> extends PsiModifierListOwnerPattern<T,Self> {
+  public PsiMemberPattern(@NotNull final InitialPatternCondition<T> condition) {
+    super(condition);
+  }
+
+  protected PsiMemberPattern(final Class<T> aClass) {
+    super(aClass);
+  }
+
+  public Self inClass(final @NonNls String qname) {
+    return inClass(PsiJavaPatterns.psiClass().withQualifiedName(qname));
+  }
+
+  public Self inClass(final ElementPattern pattern) {
+    return with(new PatternConditionPlus<T, PsiClass>("inClass", pattern) {
+      @Override
+      public boolean processValues(T t, ProcessingContext context, PairProcessor<PsiClass, ProcessingContext> processor) {
+        return processor.process(t.getContainingClass(), context);
+      }
+    });
+  }
+
+  public static class Capture extends PsiMemberPattern<PsiMember, Capture> {
+
+    protected Capture() {
+      super(new InitialPatternCondition<PsiMember>(PsiMember.class) {
+        public boolean accepts(@Nullable final Object o, final ProcessingContext context) {
+          return o instanceof PsiMember;
+        }
+      });
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java b/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java
new file mode 100644
index 0000000..a649126
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMethodCallPattern.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiMethodCallExpression;
+import com.intellij.psi.PsiExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class PsiMethodCallPattern extends PsiExpressionPattern<PsiMethodCallExpression, PsiMethodCallPattern> {
+  PsiMethodCallPattern() {
+    super(PsiMethodCallExpression.class);
+  }
+
+  public PsiMethodCallPattern withArguments(final ElementPattern<? extends PsiExpression>... arguments) {
+    return with(new PatternCondition<PsiMethodCallExpression>("withArguments") {
+      @Override
+      public boolean accepts(@NotNull PsiMethodCallExpression callExpression, ProcessingContext context) {
+        final PsiExpression[] actualArguments = callExpression.getArgumentList().getExpressions();
+        if (arguments.length != actualArguments.length) {
+          return false;
+        }
+        for (int i = 0; i < actualArguments.length; i++) {
+          if (!arguments[i].accepts(actualArguments[i], context)) {
+            return false;
+          }
+        }
+        return true;
+      }
+    });
+  }
+
+  public PsiMethodCallPattern withQualifier(final ElementPattern<? extends PsiExpression> qualifier) {
+    return with(new PatternCondition<PsiMethodCallExpression>("withQualifier") {
+      @Override
+      public boolean accepts(@NotNull PsiMethodCallExpression psiMethodCallExpression, ProcessingContext context) {
+        return qualifier.accepts(psiMethodCallExpression.getMethodExpression().getQualifierExpression(), context);
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java
new file mode 100644
index 0000000..d4f6096
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiMethodPattern.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.patterns;
+
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.search.searches.SuperMethodsSearch;
+import com.intellij.psi.util.MethodSignatureBackedByPsiMethod;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.Processor;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiMethodPattern extends PsiMemberPattern<PsiMethod,PsiMethodPattern> {
+  public PsiMethodPattern() {
+    super(PsiMethod.class);
+  }
+
+  public PsiMethodPattern withParameterCount(@NonNls final int paramCount) {
+    return with(new PatternCondition<PsiMethod>("withParameterCount") {
+      @Override
+      public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+        return method.getParameterList().getParametersCount() == paramCount;
+      }
+    });
+  }
+
+  /**
+   * Selects the corrected method by argument types
+   * @param inputTypes the array of FQN of the parameter types or wildcards.
+   * The special values are:<bl><li>"?" - means any type</li><li>".." - instructs pattern to accept the rest of the arguments</li></bl>
+   * @return
+   */
+  public PsiMethodPattern withParameters(@NonNls final String... inputTypes) {
+    final String[] types = inputTypes.length == 0 ? ArrayUtil.EMPTY_STRING_ARRAY : inputTypes;
+    return with(new PatternCondition<PsiMethod>("withParameters") {
+      @Override
+      public boolean accepts(@NotNull final PsiMethod psiMethod, final ProcessingContext context) {
+        final PsiParameterList parameterList = psiMethod.getParameterList();
+        int dotsIndex = -1;
+        while (++dotsIndex <types.length) {
+          if (Comparing.equal("..", types[dotsIndex])) break;
+        }
+
+        if (dotsIndex == types.length && parameterList.getParametersCount() != dotsIndex
+          || dotsIndex < types.length && parameterList.getParametersCount() < dotsIndex) {
+          return false;
+        }
+        if (dotsIndex > 0) {
+          final PsiParameter[] psiParameters = parameterList.getParameters();
+          for (int i = 0; i < dotsIndex; i++) {
+            if (!Comparing.equal("?", types[i]) && !typeEquivalent(psiParameters[i].getType(), types[i])) {
+              return false;
+            }
+          }
+        }
+        return true;
+      }
+
+      private boolean typeEquivalent(PsiType type, String expectedText) {
+        final PsiType erasure = TypeConversionUtil.erasure(type);
+        final String text;
+        if (erasure instanceof PsiEllipsisType && expectedText.endsWith("[]")) {
+          text = ((PsiEllipsisType)erasure).getComponentType().getCanonicalText() + "[]";
+        }
+        else if (erasure instanceof PsiArrayType && expectedText.endsWith("...")) {
+          text = ((PsiArrayType)erasure).getComponentType().getCanonicalText() +"...";
+        }
+        else {
+          text = erasure.getCanonicalText();
+        }
+        return expectedText.equals(text);
+      }
+    });
+  }
+
+  public PsiMethodPattern definedInClass(@NonNls final String qname) {
+    return definedInClass(PsiJavaPatterns.psiClass().withQualifiedName(qname));
+  }
+
+  public PsiMethodPattern definedInClass(final ElementPattern<? extends PsiClass> pattern) {
+    return with(new PatternConditionPlus<PsiMethod, PsiClass>("definedInClass", pattern) {
+
+      @Override
+      public boolean processValues(PsiMethod t, final ProcessingContext context, final PairProcessor<PsiClass, ProcessingContext> processor) {
+        if (!processor.process(t.getContainingClass(), context)) return false;
+        final Ref<Boolean> result = Ref.create(Boolean.TRUE);
+        SuperMethodsSearch.search(t, null, true, false).forEach(new Processor<MethodSignatureBackedByPsiMethod>() {
+          @Override
+          public boolean process(final MethodSignatureBackedByPsiMethod signature) {
+            if (!processor.process(signature.getMethod().getContainingClass(), context)) {
+              result.set(Boolean.FALSE);
+              return false;
+            }
+            return true;
+          }
+        });
+        return result.get();
+      }
+    });
+  }
+
+  public PsiMethodPattern constructor(final boolean isConstructor) {
+    return with(new PatternCondition<PsiMethod>("constructor") {
+      @Override
+      public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+        return method.isConstructor() == isConstructor;
+      }
+    });
+  }
+
+
+  public PsiMethodPattern withThrowsList(final ElementPattern<?> pattern) {
+    return with(new PatternCondition<PsiMethod>("withThrowsList") {
+      @Override
+      public boolean accepts(@NotNull final PsiMethod method, final ProcessingContext context) {
+        return pattern.accepts(method.getThrowsList());
+      }
+    });
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java b/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java
new file mode 100644
index 0000000..4fd3ae1
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiModifierListOwnerPattern.java
@@ -0,0 +1,85 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiModifierList;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.util.ProcessingContext;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.codeInsight.AnnotationUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiModifierListOwnerPattern<T extends PsiModifierListOwner, Self extends PsiModifierListOwnerPattern<T,Self>> extends PsiElementPattern<T,Self> {
+  public PsiModifierListOwnerPattern(@NotNull final InitialPatternCondition<T> condition) {
+    super(condition);
+  }
+
+  protected PsiModifierListOwnerPattern(final Class<T> aClass) {
+    super(aClass);
+  }
+
+  public Self withModifiers(final String... modifiers) {
+    return with(new PatternCondition<T>("withModifiers") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        return ContainerUtil.and(modifiers, new Condition<String>() {
+          public boolean value(final String s) {
+            return t.hasModifierProperty(s);
+          }
+        });
+      }
+    });
+  }
+
+  public Self withoutModifiers(final String... modifiers) {
+    return with(new PatternCondition<T>("withoutModifiers") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        return ContainerUtil.and(modifiers, new Condition<String>() {
+          public boolean value(final String s) {
+            return !t.hasModifierProperty(s);
+          }
+        });
+      }
+    });
+  }
+
+  public Self withAnnotation(@NonNls final String qualifiedName) {
+    return with(new PatternCondition<T>("withAnnotation") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        final PsiModifierList modifierList = t.getModifierList();
+        return modifierList != null && modifierList.findAnnotation(qualifiedName) != null;
+      }
+    });
+  }
+
+  public Self withAnnotations(@NonNls final String... qualifiedNames) {
+    return with(new PatternCondition<T>("withAnnotations") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        return AnnotationUtil.findAnnotation(t, qualifiedNames) != null;
+      }
+    });
+  }
+
+  public static class Capture<T extends PsiModifierListOwner> extends PsiModifierListOwnerPattern<T, Capture<T>> {
+    public Capture(@NotNull InitialPatternCondition<T> condition) {
+      super(condition);
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java b/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java
new file mode 100644
index 0000000..9612c87
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiNameValuePairPattern.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiNameValuePair;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiNameValuePairPattern extends PsiElementPattern<PsiNameValuePair, PsiNameValuePairPattern> {
+  protected PsiNameValuePairPattern() {
+    super(PsiNameValuePair.class);
+  }
+
+  public PsiNameValuePairPattern withName(@NotNull @NonNls final String requiredName) {
+    return with(new PatternCondition<PsiNameValuePair>("withName") {
+      public boolean accepts(@NotNull final PsiNameValuePair psiNameValuePair, final ProcessingContext context) {
+        String actualName = psiNameValuePair.getName();
+        return requiredName.equals(actualName) || actualName == null && "value".equals(requiredName);
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java b/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java
new file mode 100644
index 0000000..e6f0cca
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiParameterPattern.java
@@ -0,0 +1,55 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.util.PairProcessor;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author Gregory Shrago
+ */
+public class PsiParameterPattern extends PsiModifierListOwnerPattern<PsiParameter, PsiParameterPattern> {
+
+  protected PsiParameterPattern() {
+    super(PsiParameter.class);
+  }
+
+  public PsiParameterPattern ofMethod(final int index, final ElementPattern pattern) {
+    return with(new PatternConditionPlus<PsiParameter, PsiMethod>("ofMethod", pattern) {
+      @Override
+      public boolean processValues(PsiParameter t,
+                                   ProcessingContext context,
+                                   PairProcessor<PsiMethod, ProcessingContext> processor) {
+        PsiElement scope = t.getDeclarationScope();
+        if (!(scope instanceof PsiMethod)) return true;
+        return processor.process((PsiMethod)scope, context);
+      }
+
+      public boolean accepts(@NotNull final PsiParameter t, final ProcessingContext context) {
+        if (!super.accepts(t, context)) return false;
+        final PsiMethod psiMethod = (PsiMethod)t.getDeclarationScope();
+
+        final PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+        if (index < 0 || index >= parameters.length || !t.equals(parameters[index])) return false;
+        return true;
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java b/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java
new file mode 100644
index 0000000..aa1db7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiStatementPattern.java
@@ -0,0 +1,57 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiStatement;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public class PsiStatementPattern<T extends PsiStatement, Self extends PsiStatementPattern<T, Self>> extends PsiJavaElementPattern<T, Self>{
+  public PsiStatementPattern(final Class<T> aClass) {
+    super(aClass);
+  }
+
+  public Self insideMethod(final PsiMethodPattern pattern) {
+    return with(new PatternCondition<T>("insideMethod") {
+      public boolean accepts(@NotNull final T t, final ProcessingContext context) {
+        PsiMethod method = PsiTreeUtil.getParentOfType(t, PsiMethod.class, false, PsiMember.class);
+        return method != null && pattern.accepts(method, context);
+      }
+    });
+  }
+
+  public Self insideMethod(StringPattern methodName, String qualifiedClassName) {
+    return insideMethod(PsiJavaPatterns.psiMethod().withName(methodName).definedInClass(qualifiedClassName));
+  }
+
+  public Self insideMethod(@NotNull @NonNls String methodName, @NotNull @NonNls String qualifiedClassName) {
+    return insideMethod(StandardPatterns.string().equalTo(methodName), qualifiedClassName);
+  }
+
+  public static class Capture<T extends PsiStatement> extends PsiStatementPattern<T, Capture<T>> {
+    public Capture(final Class<T> aClass) {
+      super(aClass);
+    }
+
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java b/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java
new file mode 100644
index 0000000..b119409
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiTypeCastExpressionPattern.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiExpression;
+import com.intellij.psi.PsiTypeCastExpression;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class PsiTypeCastExpressionPattern extends PsiExpressionPattern<PsiTypeCastExpression, PsiTypeCastExpressionPattern> {
+  PsiTypeCastExpressionPattern() {
+    super(PsiTypeCastExpression.class);
+  }
+
+  public PsiTypeCastExpressionPattern withOperand(final ElementPattern<? extends PsiExpression> operand) {
+    return with(new PatternCondition<PsiTypeCastExpression>("withOperand") {
+      @Override
+      public boolean accepts(@NotNull PsiTypeCastExpression psiTypeCastExpression, ProcessingContext context) {
+        return operand.accepts(psiTypeCastExpression.getOperand(), context);
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/patterns/PsiTypePattern.java b/java/openapi/src/com/intellij/patterns/PsiTypePattern.java
new file mode 100644
index 0000000..b7d8e1b
--- /dev/null
+++ b/java/openapi/src/com/intellij/patterns/PsiTypePattern.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.patterns;
+
+import com.intellij.psi.PsiArrayType;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiType;
+import com.intellij.util.ProcessingContext;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class PsiTypePattern extends ObjectPattern<PsiType,PsiTypePattern> {
+  protected PsiTypePattern() {
+    super(PsiType.class);
+  }
+
+  public PsiTypePattern arrayOf(final ElementPattern pattern) {
+    return with(new PatternCondition<PsiType>("arrayOf") {
+      public boolean accepts(@NotNull final PsiType psiType, final ProcessingContext context) {
+        return psiType instanceof PsiArrayType &&
+               pattern.getCondition().accepts(((PsiArrayType)psiType).getComponentType(), context);
+      }
+    });
+  }
+
+  public PsiTypePattern classType(final ElementPattern<? extends PsiClass> pattern) {
+    return with(new PatternCondition<PsiType>("classType") {
+      public boolean accepts(@NotNull final PsiType psiType, final ProcessingContext context) {
+        return psiType instanceof PsiClassType &&
+               pattern.getCondition().accepts(((PsiClassType)psiType).resolve(), context);
+      }
+    });
+  }
+}
diff --git a/java/openapi/src/com/intellij/peer/PeerFactory.java b/java/openapi/src/com/intellij/peer/PeerFactory.java
new file mode 100644
index 0000000..2f55b27
--- /dev/null
+++ b/java/openapi/src/com/intellij/peer/PeerFactory.java
@@ -0,0 +1,83 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.peer;
+
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.Language;
+import com.intellij.lang.PsiBuilder;
+import com.intellij.lexer.Lexer;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.diff.DiffRequestFactory;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.highlighter.EditorHighlighter;
+import com.intellij.openapi.fileChooser.FileSystemTreeFactory;
+import com.intellij.openapi.fileTypes.SyntaxHighlighter;
+import com.intellij.openapi.module.ModuleConfigurationEditor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkType;
+import com.intellij.openapi.roots.ui.configuration.ModuleConfigurationState;
+import com.intellij.openapi.ui.DialogWrapperPeerFactory;
+import com.intellij.openapi.vcs.FileStatusFactory;
+import com.intellij.openapi.vcs.actions.VcsContextFactory;
+import com.intellij.psi.search.scope.packageSet.PackageSetFactory;
+import com.intellij.ui.UIHelper;
+import com.intellij.ui.content.ContentFactory;
+import com.intellij.ui.errorView.ErrorViewFactory;
+import org.apache.xmlrpc.WebServer;
+import org.apache.xmlrpc.XmlRpcServer;
+
+import java.net.InetAddress;
+
+/** @deprecated to remove in IDEA 13 */
+@SuppressWarnings({"UnusedDeclaration", "deprecation"})
+public abstract class PeerFactory {
+  public static PeerFactory getInstance() {
+    return ServiceManager.getService(PeerFactory.class);
+  }
+
+  public abstract FileStatusFactory getFileStatusFactory();
+
+  public abstract DialogWrapperPeerFactory getDialogWrapperPeerFactory();
+
+  public abstract PackageSetFactory getPackageSetFactory();
+
+  public abstract UIHelper getUIHelper();
+
+  public abstract ErrorViewFactory getErrorViewFactory();
+
+  public abstract ContentFactory getContentFactory();
+
+  public abstract FileSystemTreeFactory getFileSystemTreeFactory();
+
+  public abstract DiffRequestFactory getDiffRequestFactory();
+
+  public abstract VcsContextFactory getVcsContextFactory();
+
+  public abstract PsiBuilder createBuilder(ASTNode tree, Language lang, CharSequence seq, final Project project);
+
+  public abstract PsiBuilder createBuilder(ASTNode tree, Lexer lexer, Language lang, CharSequence seq, final Project project);
+
+  public abstract XmlRpcServer createRpcServer();
+
+  public abstract WebServer createWebServer(int port, InetAddress addr, XmlRpcServer xmlRpc);
+
+  public abstract EditorHighlighter createEditorHighlighter(SyntaxHighlighter syntaxHighlighter, EditorColorsScheme colors);
+
+  public abstract Sdk createProjectJdk(String name, final String version, final String homePath, SdkType sdkType);
+
+  public abstract ModuleConfigurationEditor createModuleConfigurationEditor(String moduleName, ModuleConfigurationState state);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/peer/package.html b/java/openapi/src/com/intellij/peer/package.html
new file mode 100644
index 0000000..604a8db
--- /dev/null
+++ b/java/openapi/src/com/intellij/peer/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for creating internal IDEA implementations of components defined by
+abstract interfaces.
+</body></html>
diff --git a/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java b/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java
new file mode 100644
index 0000000..36e5eaf
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/PomJavaAspect.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.pom.java;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.pom.PomModel;
+import com.intellij.pom.PomModelAspect;
+
+public abstract class PomJavaAspect implements PomModelAspect {
+  public static PomJavaAspect getInstance(Project project) {
+    return project.getComponent(PomJavaAspect.class);
+  }
+
+  public static PomJavaAspect getInstance(PomModel model) {
+    return model.getModelAspect(PomJavaAspect.class);
+  }
+
+  public abstract LanguageLevel getLanguageLevel();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java
new file mode 100644
index 0000000..3ae8f6e
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/events/PomJavaAspectChangeSet.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.pom.java.events;
+
+import com.intellij.pom.PomModel;
+import com.intellij.pom.PomModelAspect;
+import com.intellij.pom.event.PomChangeSet;
+import com.intellij.pom.java.PomJavaAspect;
+import org.jetbrains.annotations.NotNull;
+
+public class PomJavaAspectChangeSet implements PomChangeSet{
+  private final PomModel myModel;
+
+  public PomJavaAspectChangeSet(PomModel model) {
+    myModel = model;
+  }
+
+  @NotNull
+  public PomModelAspect getAspect() {
+    return myModel.getModelAspect(PomJavaAspect.class);
+  }
+
+  public void merge(@NotNull PomChangeSet blocked) {
+  }
+}
diff --git a/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java b/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java
new file mode 100644
index 0000000..87a8a1e
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/events/PomJavaChange.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.pom.java.events;
+
+/**
+ * @author peter
+ */
+public interface PomJavaChange {
+}
diff --git a/java/openapi/src/com/intellij/pom/java/package.html b/java/openapi/src/com/intellij/pom/java/package.html
new file mode 100644
index 0000000..6d18672
--- /dev/null
+++ b/java/openapi/src/com/intellij/pom/java/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+The POM API is unfinished, undocumented, does not allow to perform any tasks for which no other
+APIs exist, and thus should not be used.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java b/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java
new file mode 100644
index 0000000..3710d5a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/CommonReferenceProviderTypes.java
@@ -0,0 +1,43 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+
+/**
+ * @author peter
+ */
+public abstract class CommonReferenceProviderTypes {
+
+  /**
+   * @deprecated
+   * @see #getInstance()
+   */
+  public static CommonReferenceProviderTypes getInstance(final Project project) {
+    return getInstance();
+  }
+
+  public static CommonReferenceProviderTypes getInstance() {
+    return ServiceManager.getService(CommonReferenceProviderTypes.class);
+  }
+
+  public static final ReferenceProviderType PROPERTIES_FILE_KEY_PROVIDER = new ReferenceProviderType("Properties File Key Provider");
+  public static final ReferenceProviderType URI_PROVIDER = new ReferenceProviderType("Uri references provider");
+  public static final ReferenceProviderType SCHEMA_PROVIDER = new ReferenceProviderType("Schema references provider");
+
+  public abstract PsiReferenceProvider getClassReferenceProvider();
+}
diff --git a/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java b/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java
new file mode 100644
index 0000000..eefda40
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/JavaCodeFragmentFactory.java
@@ -0,0 +1,121 @@
+/*
+ * 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.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.intellij.lang.annotations.MagicConstant;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class JavaCodeFragmentFactory {
+  public static JavaCodeFragmentFactory getInstance(Project project) {
+    return ServiceManager.getService(project, JavaCodeFragmentFactory.class);
+  }
+  
+  /**
+   * Creates a Java expression code fragment from the text of the expression.
+   *
+   * @param text         the text of the expression to create.
+   * @param context      the context for resolving references from the code fragment.
+   * @param expectedType expected type of the expression (does not have any effect on creation
+   *                     but can be accessed as {@link PsiExpressionCodeFragment#getExpectedType()}).
+   * @param isPhysical   whether the code fragment is created as a physical element
+   *                     (see {@link PsiElement#isPhysical()}).
+   * @return the created code fragment.
+   */
+  @NotNull
+  public abstract PsiExpressionCodeFragment createExpressionCodeFragment(@NotNull String text,
+                                                                         @Nullable PsiElement context,
+                                                                         @Nullable final PsiType expectedType,
+                                                                         boolean isPhysical);
+
+  /**
+   * Creates a Java code fragment from the text of a Java code block.
+   *
+   * @param text       the text of the code block to create.
+   * @param context    the context for resolving references from the code fragment.
+   * @param isPhysical whether the code fragment is created as a physical element
+   *                   (see {@link PsiElement#isPhysical()}).
+   * @return the created code fragment.
+   */
+  @NotNull
+  public abstract JavaCodeFragment createCodeBlockCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+  /**
+   * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows void type.
+   */
+  public static final int ALLOW_VOID = 0x01;
+  /**
+   * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows type with ellipsis.
+   */
+  public static final int ALLOW_ELLIPSIS = 0x02;
+  /**
+   * Flag for {@linkplain #createTypeCodeFragment(String, PsiElement, boolean, int)} - allows disjunctive type.
+   */
+  public static final int ALLOW_DISJUNCTION = 0x04;
+
+  /**
+   * Creates a Java type code fragment from the text of the name of a Java type (the name
+   * of a primitive type, array type or class), with <code>void</code> and ellipsis
+   * not treated as a valid type.
+   *
+   * @param text       the text of the Java type to create.
+   * @param context    the context for resolving references from the code fragment.
+   * @param isPhysical whether the code fragment is created as a physical element
+   *                   (see {@link PsiElement#isPhysical()}).
+   * @return the created code fragment.
+   */
+  @NotNull
+  public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text, @Nullable PsiElement context, boolean isPhysical);
+
+  /**
+   * Creates a Java type code fragment from the text of the name of a Java type (the name
+   * of a primitive type, array type or class).<br>
+   * {@code void}, ellipsis and disjunctive types are optionally treated as valid ones.
+   *
+   * @param text       the text of the Java type to create.
+   * @param context    the context for resolving references from the code fragment.
+   * @param isPhysical whether the code fragment is created as a physical element
+   *                   (see {@link PsiElement#isPhysical()}).
+   * @param flags      types allowed to present in text.
+   * @return the created code fragment.
+   */
+  @NotNull
+  public abstract PsiTypeCodeFragment createTypeCodeFragment(@NotNull String text,
+                                                             @Nullable PsiElement context,
+                                                             boolean isPhysical,
+                                                             @MagicConstant(flags = {ALLOW_VOID, ALLOW_ELLIPSIS, ALLOW_DISJUNCTION}) int flags);
+
+  /**
+   * Creates a Java reference code fragment from the text of a Java reference to a
+   * package or class.
+   *
+   * @param text              the text of the reference to create.
+   * @param context           the context for resolving the reference.
+   * @param isPhysical        whether the code fragment is created as a physical element
+   *                          (see {@link PsiElement#isPhysical()}).
+   * @param isClassesAccepted if true then classes as well as packages are accepted as
+   *                          reference target, otherwise only packages are
+   * @return the created reference fragment.
+   */
+  @NotNull
+  public abstract PsiJavaCodeReferenceCodeFragment createReferenceCodeFragment(@NotNull String text,
+                                                                               @Nullable PsiElement context,
+                                                                               boolean isPhysical,
+                                                                               boolean isClassesAccepted);
+
+}
diff --git a/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java b/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java
new file mode 100644
index 0000000..71389fb
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/LanguageAnnotationSupport.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi;
+
+import com.intellij.lang.LanguageExtension;
+
+/**
+ * @author Serega.Vasiliev
+ */
+public class LanguageAnnotationSupport extends LanguageExtension<PsiAnnotationSupport> {
+  public static final LanguageAnnotationSupport INSTANCE = new LanguageAnnotationSupport();
+
+  private LanguageAnnotationSupport() {
+    super("com.intellij.annotationSupport");
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointer.java b/java/openapi/src/com/intellij/psi/SmartTypePointer.java
new file mode 100644
index 0000000..43556c8
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/SmartTypePointer.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ *  @author dsl
+ */
+public interface SmartTypePointer {
+  @Nullable
+  PsiType getType();
+}
diff --git a/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
new file mode 100644
index 0000000..2624506
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/SmartTypePointerManager.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import org.jetbrains.annotations.NotNull;
+
+public abstract class SmartTypePointerManager {
+  public static SmartTypePointerManager getInstance(Project project) {
+    return ServiceManager.getService(project, SmartTypePointerManager.class);
+  }
+
+  @NotNull
+  public abstract SmartTypePointer createSmartTypePointer(@NotNull PsiType type);
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java b/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java
new file mode 100644
index 0000000..1a91db0
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/infos/CandidatesGroup.java
@@ -0,0 +1,67 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.infos;
+
+import java.util.ArrayList;
+import java.util.Iterator;
+import java.util.List;
+
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: ik
+ * Date: 10.06.2003
+ * Time: 13:37:39
+ * To change this template use Options | File Templates.
+ */
+public class CandidatesGroup {
+  public static final int UNKNOWN = -1;
+  public static final int CONFLICT = 0;
+
+  private List myCandidates = new ArrayList();
+  private int myCause = UNKNOWN;
+
+  public CandidateInfo get(int index){
+    return (CandidateInfo) myCandidates.get(index);
+  }
+
+  public int size(){
+    return myCandidates.size();
+  }
+
+  public Iterator iterator(){
+    return myCandidates.iterator();
+  }
+
+  public int getCause(){
+    return myCause;
+  }
+
+  public CandidatesGroup(List candidates, int cause){
+    myCandidates = candidates;
+    myCause = cause;
+  }
+
+  public CandidatesGroup(int cause){
+    myCause = cause;
+  }
+
+  public CandidatesGroup(){}
+
+  public void add(CandidateInfo candidate){
+    myCandidates.add(candidate);
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/infos/package.html b/java/openapi/src/com/intellij/psi/infos/package.html
new file mode 100644
index 0000000..8983870
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/infos/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides classes which represent possible completion variants in completion lists.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java b/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java
new file mode 100644
index 0000000..0790306
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/JavadocManager.java
@@ -0,0 +1,42 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.javadoc;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author mike
+ */
+public interface JavadocManager {
+  class SERVICE {
+    private SERVICE() {
+    }
+
+    public static JavadocManager getInstance(Project project) {
+      return ServiceManager.getService(project, JavadocManager.class);
+    }
+  }
+  
+  @NotNull
+  JavadocTagInfo[] getTagInfos(PsiElement context);
+
+  @Nullable
+  JavadocTagInfo getTagInfo(String name);
+}
diff --git a/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
new file mode 100644
index 0000000..7435213
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/JavadocTagInfo.java
@@ -0,0 +1,48 @@
+/*
+ * 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.psi.javadoc;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author mike
+ */
+public interface JavadocTagInfo {
+  ExtensionPointName<JavadocTagInfo> EP_NAME = ExtensionPointName.create("com.intellij.javadocTagInfo");
+
+  @NonNls String getName();
+  boolean isInline();
+
+  boolean isValidInContext(PsiElement element);
+
+  Object[] getPossibleValues(PsiElement context, PsiElement place, String prefix);
+
+  /**
+   * Checks the tag value for correctness.
+   *
+   * @param value Doc tag to check.
+   * @return Returns null if correct, error message otherwise.
+   */
+  @Nullable
+  String checkTagValue(PsiDocTagValue value);
+
+  @Nullable
+  PsiReference getReference(PsiDocTagValue value);
+}
diff --git a/java/openapi/src/com/intellij/psi/javadoc/package.html b/java/openapi/src/com/intellij/psi/javadoc/package.html
new file mode 100644
index 0000000..d56bfa4
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/javadoc/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides the PSI structure for Javadoc comments and services for registering custom Javadoc tags.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/package.html b/java/openapi/src/com/intellij/psi/package.html
new file mode 100644
index 0000000..52dff27
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with the Program Source Interface (IDEA's internal representation
+of the program structure).
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java b/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java
new file mode 100644
index 0000000..a65ebb3
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/AnnotationAttributeChildLink.java
@@ -0,0 +1,73 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.ref;
+
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ObjectUtils;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+*/
+public class AnnotationAttributeChildLink extends PsiChildLink<PsiAnnotation, PsiAnnotationMemberValue> {
+  private final String myAttributeName;
+
+  public AnnotationAttributeChildLink(@NotNull @NonNls String attributeName) {
+    myAttributeName = attributeName;
+  }
+
+  @NotNull
+  public String getAttributeName() {
+    return myAttributeName;
+  }
+
+  @Override
+  public PsiAnnotationMemberValue findLinkedChild(@Nullable PsiAnnotation psiAnnotation) {
+    if (psiAnnotation == null) return null;
+
+    psiAnnotation.getText();
+    return psiAnnotation.findDeclaredAttributeValue(myAttributeName);
+  }
+
+  @Override
+  @NotNull
+  public PsiAnnotationMemberValue createChild(@NotNull PsiAnnotation psiAnnotation) throws IncorrectOperationException {
+    psiAnnotation.getText();
+    final PsiExpression nullValue = JavaPsiFacade.getElementFactory(psiAnnotation.getProject()).createExpressionFromText(PsiKeyword.NULL, null);
+    psiAnnotation.setDeclaredAttributeValue(myAttributeName, nullValue);
+    return ObjectUtils.assertNotNull(psiAnnotation.findDeclaredAttributeValue(myAttributeName));
+  }
+
+  @Override
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final AnnotationAttributeChildLink link = (AnnotationAttributeChildLink)o;
+
+    if (!myAttributeName.equals(link.myAttributeName)) return false;
+
+    return true;
+  }
+
+  @Override
+  public int hashCode() {
+    return myAttributeName.hashCode();
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java b/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java
new file mode 100644
index 0000000..f4b6e17
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/AnnotationChildLink.java
@@ -0,0 +1,62 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.ref;
+
+import com.intellij.psi.*;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author peter
+ */
+public class AnnotationChildLink extends PsiChildLink<PsiModifierListOwner, PsiAnnotation> {
+  private final String myAnnoFqn;
+
+  public AnnotationChildLink(String fqn) {
+    myAnnoFqn = fqn;
+  }
+
+  public String getAnnotationQualifiedName() {
+    return myAnnoFqn;
+  }
+
+  public static PsiElementRef<PsiAnnotation> createRef(@NotNull PsiModifierListOwner parent, @NonNls String fqn) {
+    return new AnnotationChildLink(fqn).createChildRef(parent);
+  }
+
+  @Override
+  public PsiAnnotation findLinkedChild(@Nullable PsiModifierListOwner member) {
+    if (member == null) return null;
+
+    final PsiModifierList modifierList = member.getModifierList();
+    return modifierList != null ? modifierList.findAnnotation(myAnnoFqn) : null;
+  }
+
+  @Override
+  @NotNull
+  public PsiAnnotation createChild(@NotNull PsiModifierListOwner member) throws IncorrectOperationException {
+    final PsiModifierList modifierList = member.getModifierList();
+    assert modifierList != null;
+    return modifierList.addAnnotation(myAnnoFqn);
+  }
+
+  @Override
+  public String toString() {
+    return "AnnotationChildLink{" + "myAnnoFqn='" + myAnnoFqn + '\'' + '}';
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java b/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java
new file mode 100644
index 0000000..921c6a0
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/ref/InstanceofLink.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.ref;
+
+import com.intellij.psi.PsiChildLink;
+import com.intellij.psi.PsiElement;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author peter
+ */
+public class InstanceofLink<Parent extends PsiElement, Child extends PsiElement, CastTo extends Child> extends PsiChildLink<Parent, CastTo> {
+  private final PsiChildLink<Parent, Child> myDelegate;
+  private final Class<CastTo> myCastTo;
+
+  private InstanceofLink(PsiChildLink<Parent, Child> delegate, Class<CastTo> castTo) {
+    myDelegate = delegate;
+    myCastTo = castTo;
+  }
+
+  @Override
+  public CastTo findLinkedChild(@Nullable Parent parent) {
+    final Child existing = myDelegate.findLinkedChild(parent);
+    return myCastTo.isInstance(existing) ? (CastTo) existing : null;
+  }
+
+  @Override
+  @NotNull
+  public CastTo createChild(@NotNull Parent parent) throws IncorrectOperationException {
+    return (CastTo) myDelegate.createChild(parent);
+  }
+
+  public static <Parent extends PsiElement, Child extends PsiElement, CastTo extends Child> InstanceofLink<Parent, Child, CastTo> create(
+    PsiChildLink<Parent, Child> delegate, Class<CastTo> castTo) {
+    return new InstanceofLink<Parent, Child, CastTo>(delegate, castTo);
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/search/package.html b/java/openapi/src/com/intellij/psi/search/package.html
new file mode 100644
index 0000000..c4b46c1
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for searching references to elements, searching for classes and symbols by name,
+searching for TODO items and defining scope of searches.
+</body></html>
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
new file mode 100644
index 0000000..fa8b3fa
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/PatternPackageSet.java
@@ -0,0 +1,181 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.search.scope.packageSet;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.problems.WolfTheProblemSolver;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.List;
+import java.util.regex.Pattern;
+
+public class PatternPackageSet extends PatternBasedPackageSet {
+  @NonNls public static final String SCOPE_TEST = "test";
+  @NonNls public static final String SCOPE_SOURCE = "src";
+  @NonNls public static final String SCOPE_LIBRARY = "lib";
+  @NonNls public static final String SCOPE_PROBLEM = "problem";
+  public static final String SCOPE_ANY = "";
+
+  private final Pattern myPattern;
+  private final Pattern myModulePattern;
+  private final Pattern myModuleGroupPattern;
+  private final String myAspectJSyntaxPattern;
+  private final String myScope;
+  private final String myModulePatternText;
+
+  public PatternPackageSet(@NonNls @Nullable String aspectPattern,
+                           @NotNull String scope,
+                           @NonNls String modulePattern) {
+    myAspectJSyntaxPattern = aspectPattern;
+    myScope = scope;
+    myModulePatternText = modulePattern;
+    Pattern mmgp = null;
+    Pattern mmp = null;
+    if (modulePattern == null || modulePattern.length() == 0) {
+      mmp = null;
+    }
+    else {
+      if (modulePattern.startsWith("group:")) {
+        int idx = modulePattern.indexOf(':', 6);
+        if (idx == -1) idx = modulePattern.length();
+        mmgp = Pattern.compile(StringUtil.replace(modulePattern.substring(6, idx), "*", ".*"));
+        if (idx < modulePattern.length() - 1) {
+          mmp = Pattern.compile(StringUtil.replace(modulePattern.substring(idx + 1), "*", ".*"));
+        }
+      } else {
+        mmp = Pattern.compile(StringUtil.replace(modulePattern, "*", ".*"));
+      }
+    }
+    myModulePattern = mmp;
+    myModuleGroupPattern = mmgp;
+    myPattern = aspectPattern != null ? Pattern.compile(FilePatternPackageSet.convertToRegexp(aspectPattern, '.')) : null;
+  }
+
+  @Override
+  public boolean contains(VirtualFile file, NamedScopesHolder holder) {
+    Project project = holder.getProject();
+    ProjectFileIndex fileIndex = ProjectRootManager.getInstance(project).getFileIndex();
+    return matchesScope(file, holder.getProject(), fileIndex) && (myPattern == null || myPattern.matcher(getPackageName(file, fileIndex)).matches());
+  }
+
+  private boolean matchesScope(VirtualFile file, Project project, ProjectFileIndex fileIndex) {
+    if (file == null) return false;
+    boolean isSource = fileIndex.isInSourceContent(file);
+    if (myScope == SCOPE_ANY) {
+      return fileIndex.isInContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
+    }
+    if (myScope == SCOPE_SOURCE) {
+      return isSource && !fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
+                                                                                                       file, fileIndex);
+    }
+    if (myScope == SCOPE_LIBRARY) {
+      return (fileIndex.isInLibraryClasses(file) || fileIndex.isInLibrarySource(file)) && matchesLibrary(myModulePattern, file, fileIndex);
+    }
+    if (myScope == SCOPE_TEST) {
+      return isSource && fileIndex.isInTestSourceContent(file) && FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern,
+                                                                                                      file, fileIndex);
+    }
+    if (myScope == SCOPE_PROBLEM) {
+      return isSource && WolfTheProblemSolver.getInstance(project).isProblemFile(file) &&
+             FilePatternPackageSet.matchesModule(myModuleGroupPattern, myModulePattern, file, fileIndex);
+    }
+    throw new RuntimeException("Unknown scope: " + myScope);
+  }
+
+  private static String getPackageName(VirtualFile file, ProjectFileIndex fileIndex) {
+    return StringUtil.getQualifiedName(fileIndex.getPackageNameByDirectory(file.isDirectory() ? file :  file.getParent()), file.getNameWithoutExtension());
+  }
+
+  @NotNull
+  @Override
+  public PackageSet createCopy() {
+    return new PatternPackageSet(myAspectJSyntaxPattern, myScope, myModulePatternText);
+  }
+
+  @Override
+  public int getNodePriority() {
+    return 0;
+  }
+
+  @NotNull
+  @Override
+  public String getText() {
+    StringBuilder buf = new StringBuilder();
+    if (myScope != SCOPE_ANY) {
+      buf.append(myScope);
+    }
+
+    if (myModulePattern != null || myModuleGroupPattern != null) {
+      buf.append("[").append(myModulePatternText).append("]");
+    }
+
+    if (buf.length() > 0) {
+      buf.append(':');
+    }
+
+    buf.append(myAspectJSyntaxPattern);
+    return buf.toString();
+  }
+
+  @Override
+  public String getModulePattern() {
+    return myModulePatternText;
+  }
+
+  @Override
+  public boolean isOn(String oldQName) {
+    return Comparing.strEqual(oldQName, myAspectJSyntaxPattern) || //class qname
+           Comparing.strEqual(oldQName + "..*", myAspectJSyntaxPattern) || //package req
+           Comparing.strEqual(oldQName + ".*", myAspectJSyntaxPattern); //package
+  }
+
+  @Override
+  public String getPattern() {
+    return myAspectJSyntaxPattern;
+  }
+
+  public static boolean matchesLibrary(final Pattern libPattern,
+                                       final VirtualFile file,
+                                       final ProjectFileIndex fileIndex) {
+    if (libPattern != null) {
+      final List<OrderEntry> entries = fileIndex.getOrderEntriesForFile(file);
+      for (OrderEntry orderEntry : entries) {
+        if (orderEntry instanceof LibraryOrderEntry) {
+          final String libraryName = ((LibraryOrderEntry)orderEntry).getLibraryName();
+          if (libraryName != null) {
+            if (libPattern.matcher(libraryName).matches()) return true;
+          } else {
+            final String presentableName = orderEntry.getPresentableName();
+            final String fileName = new File(presentableName).getName();
+            if (libPattern.matcher(fileName).matches()) return true;
+          }
+        } else if (orderEntry instanceof JdkOrderEntry) {
+          final String jdkName = ((JdkOrderEntry)orderEntry).getJdkName();
+          if (jdkName != null && libPattern.matcher(jdkName).matches()) return true;
+        }
+      }
+      return false;
+    }
+    return true;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html b/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html
new file mode 100644
index 0000000..156ddbc
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/scope/packageSet/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for working with named search scopes containing sets of packages.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
new file mode 100644
index 0000000..213c3e4
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedMembersSearch.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotatedMembersSearch {
+
+  private AnnotatedMembersSearch() {}
+
+  public static Query<PsiMember> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+    return AnnotatedElementsSearch.searchPsiMembers(annotationClass, scope);
+  }
+
+  public static Query<PsiMember> search(@NotNull PsiClass annotationClass) {
+    return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
new file mode 100644
index 0000000..bece77b
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotatedPackagesSearch.java
@@ -0,0 +1,58 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotatedPackagesSearch extends ExtensibleQueryFactory<PsiPackage, AnnotatedPackagesSearch.Parameters> {
+  public static final AnnotatedPackagesSearch INSTANCE = new AnnotatedPackagesSearch();
+
+  public static class Parameters {
+    private final PsiClass myAnnotationClass;
+    private final SearchScope myScope;
+
+    public Parameters(final PsiClass annotationClass, final SearchScope scope) {
+      myAnnotationClass = annotationClass;
+      myScope = scope;
+    }
+
+    public PsiClass getAnnotationClass() {
+      return myAnnotationClass;
+    }
+
+    public SearchScope getScope() {
+      return myScope;
+    }
+  }
+
+  private AnnotatedPackagesSearch() {}
+
+  public static Query<PsiPackage> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+    return INSTANCE.createQuery(new Parameters(annotationClass, scope));
+  }
+
+  public static Query<PsiPackage> search(@NotNull PsiClass annotationClass) {
+    return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java b/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
new file mode 100644
index 0000000..586bb3a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/search/searches/AnnotationTargetsSearch.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.search.searches;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiModifierListOwner;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.SearchScope;
+import com.intellij.util.MergeQuery;
+import com.intellij.util.Query;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author max
+ */
+public class AnnotationTargetsSearch {
+  public static AnnotationTargetsSearch INSTANCE = new AnnotationTargetsSearch();
+
+  public static class Parameters {
+    private final PsiClass myAnnotationClass;
+    private final SearchScope myScope;
+
+    public Parameters(final PsiClass annotationClass, final SearchScope scope) {
+      myAnnotationClass = annotationClass;
+      myScope = scope;
+    }
+
+    public PsiClass getAnnotationClass() {
+      return myAnnotationClass;
+    }
+
+    public SearchScope getScope() {
+      return myScope;
+    }
+  }
+
+  private AnnotationTargetsSearch() {}
+
+  public static Query<PsiModifierListOwner> search(@NotNull PsiClass annotationClass, @NotNull SearchScope scope) {
+    final Query<PsiMember> members = AnnotatedMembersSearch.search(annotationClass, scope);
+    final Query<PsiPackage> packages = AnnotatedPackagesSearch.search(annotationClass, scope);
+    return new MergeQuery<PsiModifierListOwner>(members, packages);
+  }
+
+  public static Query<PsiModifierListOwner> search(@NotNull PsiClass annotationClass) {
+    return search(annotationClass, GlobalSearchScope.allScope(annotationClass.getProject()));
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java b/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java
new file mode 100644
index 0000000..8d855d3
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/statistics/JavaStatisticsManager.java
@@ -0,0 +1,147 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.statistics;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.util.TypeConversionUtil;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+
+/**
+ * @author yole
+ */
+public abstract class JavaStatisticsManager {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.psi.statistics.JavaStatisticsManager");
+  @NonNls public static final String CLASS_PREFIX = "class#";
+
+  private static StatisticsInfo createVariableUseInfo(final String name, final VariableKind variableKind,
+                                                      final String propertyName,
+                                                      final PsiType type) {
+    String key1 = getVariableNameUseKey1(propertyName, type);
+    String key2 = getVariableNameUseKey2(variableKind, name);
+    return new StatisticsInfo(key1, key2);
+  }
+
+  private static String getVariableNameUseKey1(String propertyName, PsiType type) {
+    @NonNls StringBuilder buffer = new StringBuilder();
+    buffer.append("variableName#");
+    if (propertyName != null){
+      buffer.append(propertyName);
+    }
+    buffer.append("#");
+    if (type != null){
+      buffer.append(type.getCanonicalText());
+    }
+    return buffer.toString();
+  }
+
+  private static String getVariableNameUseKey2(VariableKind kind, String name) {
+    StringBuilder buffer = new StringBuilder();
+    buffer.append(kind);
+    buffer.append("#");
+    buffer.append(name);
+    return buffer.toString();
+  }
+
+  public static int getVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) {
+    return createVariableUseInfo(name, variableKind, propertyName, type).getUseCount();
+  }
+
+  public static void incVariableNameUseCount(String name, VariableKind variableKind, String propertyName, PsiType type) {
+    createVariableUseInfo(name, variableKind, propertyName, type).incUseCount();
+  }
+
+  @Nullable
+  public static String getName(String key2){
+    final int startIndex = key2.indexOf("#");
+    LOG.assertTrue(startIndex >= 0);
+    @NonNls String s = key2.substring(0, startIndex);
+    if(!"variableName".equals(s)) return null;
+    final int index = key2.indexOf("#", startIndex + 1);
+    LOG.assertTrue(index >= 0);
+    return key2.substring(index + 1);
+  }
+
+  private static VariableKind getVariableKindFromKey2(String key2){
+    int index = key2.indexOf("#");
+    LOG.assertTrue(index >= 0);
+    String s = key2.substring(0, index);
+    return VariableKind.valueOf(s);
+  }
+
+  private static String getVariableNameFromKey2(String key2){
+    int index = key2.indexOf("#");
+    LOG.assertTrue(index >= 0);
+    return key2.substring(index + 1);
+  }
+
+  @NonNls @NotNull
+  public static String getMemberUseKey1(@Nullable PsiType qualifierType) {
+    qualifierType = TypeConversionUtil.erasure(qualifierType);
+    return "member#" + (qualifierType == null ? "" : qualifierType.getCanonicalText());
+  }
+
+  @NonNls
+  public static String getMemberUseKey2(PsiMember member) {
+    if (member instanceof PsiMethod){
+      PsiMethod method = (PsiMethod)member;
+      @NonNls StringBuilder buffer = new StringBuilder();
+      buffer.append("method#");
+      buffer.append(method.getName());
+      for (PsiParameter parm : method.getParameterList().getParameters()) {
+        buffer.append("#");
+        buffer.append(parm.getType().getPresentableText());
+      }
+      return buffer.toString();
+    }
+
+    if (member instanceof PsiField){
+      return "field#" + member.getName();
+    }
+
+    return CLASS_PREFIX + ((PsiClass)member).getQualifiedName();
+  }
+
+  public static StatisticsInfo createInfo(@Nullable final PsiType qualifierType, final PsiMember member) {
+    return new StatisticsInfo(getMemberUseKey1(qualifierType), getMemberUseKey2(member));
+  }
+
+  public static String[] getAllVariableNamesUsed(VariableKind variableKind, String propertyName, PsiType type) {
+    StatisticsInfo[] keys2 = StatisticsManager.getInstance().getAllValues(getVariableNameUseKey1(propertyName, type));
+
+    ArrayList<String> list = new ArrayList<String>();
+
+    for (StatisticsInfo key2 : keys2) {
+      VariableKind variableKind1 = getVariableKindFromKey2(key2.getValue());
+      if (variableKind1 != variableKind) continue;
+      String name = getVariableNameFromKey2(key2.getValue());
+      list.add(name);
+    }
+
+    return ArrayUtil.toStringArray(list);
+  }
+
+  public static String getAfterNewKey(@Nullable PsiType expectedType) {
+    return getMemberUseKey1(expectedType) + "###smartAfterNew";
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/psi/statistics/package.html b/java/openapi/src/com/intellij/psi/statistics/package.html
new file mode 100644
index 0000000..273ed0a
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/statistics/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for tracking the statistics of using different elements in
+completion lists.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/tree/java/package.html b/java/openapi/src/com/intellij/psi/tree/java/package.html
new file mode 100644
index 0000000..1ad6046
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/tree/java/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for Java elements found in AST trees.
+</body></html>
diff --git a/java/openapi/src/com/intellij/psi/util/ClassKind.java b/java/openapi/src/com/intellij/psi/util/ClassKind.java
new file mode 100644
index 0000000..3c91030
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/ClassKind.java
@@ -0,0 +1,23 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.psi.util;
+
+/**
+ * @author peter
+ */
+public enum ClassKind {
+  CLASS, INTERFACE, ENUM, ANNOTATION
+}
diff --git a/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java b/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
new file mode 100644
index 0000000..4a370cd
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/EnclosingLoopMatcherExpression.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopMatcherExpression implements PsiMatcherExpression {
+  public static final PsiMatcherExpression INSTANCE = new EnclosingLoopMatcherExpression();
+
+  @Override
+  public Boolean match(PsiElement element) {
+    if (element instanceof PsiForStatement) return Boolean.TRUE;
+    if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+    if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+    if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+    if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+    return Boolean.FALSE;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java b/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
new file mode 100644
index 0000000..b40ce68
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/EnclosingLoopOrSwitchMatcherExpression.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+
+public class EnclosingLoopOrSwitchMatcherExpression implements PsiMatcherExpression {
+  public static final PsiMatcherExpression INSTANCE = new EnclosingLoopOrSwitchMatcherExpression();
+
+  @Override
+  public Boolean match(PsiElement element) {
+    if (element instanceof PsiForStatement) return Boolean.TRUE;
+    if (element instanceof PsiForeachStatement) return Boolean.TRUE;
+    if (element instanceof PsiWhileStatement) return Boolean.TRUE;
+    if (element instanceof PsiDoWhileStatement) return Boolean.TRUE;
+    if (element instanceof PsiSwitchStatement) return Boolean.TRUE;
+    if (element instanceof PsiMethod || element instanceof PsiClassInitializer) return null;
+    return Boolean.FALSE;
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/ImportsUtil.java b/java/openapi/src/com/intellij/psi/util/ImportsUtil.java
new file mode 100644
index 0000000..7b61ade
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/ImportsUtil.java
@@ -0,0 +1,82 @@
+/*
+ * 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.psi.util;
+
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.List;
+
+/**
+ * User: anna
+ * Date: 9/1/11
+ */
+public class ImportsUtil {
+  private ImportsUtil() {
+  }
+
+  public static List<PsiJavaCodeReferenceElement> collectReferencesThrough(PsiFile file,
+                                                                           @Nullable final PsiJavaCodeReferenceElement refExpr,
+                                                                           final PsiImportStaticStatement staticImport) {
+    final List<PsiJavaCodeReferenceElement> expressionToExpand = new ArrayList<PsiJavaCodeReferenceElement>();
+    file.accept(new JavaRecursiveElementWalkingVisitor() {
+      @Override
+      public void visitReferenceElement(PsiJavaCodeReferenceElement expression) {
+        if (refExpr == null || refExpr != expression) {
+          final PsiElement resolveScope = expression.advancedResolve(true).getCurrentFileResolveScope();
+          if (resolveScope == staticImport) {
+            expressionToExpand.add(expression);
+          }
+        }
+        super.visitElement(expression);
+      }
+    });
+    return expressionToExpand;
+  }
+
+  public static void replaceAllAndDeleteImport(List<PsiJavaCodeReferenceElement> expressionToExpand,
+                                               @Nullable PsiJavaCodeReferenceElement refExpr,
+                                                PsiImportStaticStatement staticImport) {
+    if (refExpr != null) {
+      expressionToExpand.add(refExpr);
+    }
+    Collections.sort(expressionToExpand, new Comparator<PsiJavaCodeReferenceElement>() {
+      @Override
+      public int compare(PsiJavaCodeReferenceElement o1, PsiJavaCodeReferenceElement o2) {
+        return o2.getTextOffset() - o1.getTextOffset();
+      }
+    });
+    for (PsiJavaCodeReferenceElement expression : expressionToExpand) {
+      expand(expression, staticImport);
+    }
+    staticImport.delete();
+  }
+
+  public static void expand(@NotNull PsiJavaCodeReferenceElement refExpr, PsiImportStaticStatement staticImport) {
+    final PsiElementFactory elementFactory = JavaPsiFacade.getElementFactory(refExpr.getProject());
+    final PsiReferenceExpression referenceExpression = elementFactory.createReferenceExpression(staticImport.resolveTargetClass());
+    if (refExpr instanceof PsiReferenceExpression) {
+      ((PsiReferenceExpression)refExpr).setQualifierExpression(referenceExpression);
+    }
+    else {
+      refExpr.replace(elementFactory.createReferenceFromText(referenceExpression.getText() + "." + refExpr.getText(), refExpr));
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java b/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java
new file mode 100644
index 0000000..90bdec5
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PropertyMemberType.java
@@ -0,0 +1,24 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.psi.util;
+
+/**
+ * @author Gregory.Shrago
+*/
+public enum PropertyMemberType {
+  FIELD, GETTER, SETTER
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java b/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java
new file mode 100644
index 0000000..9b60456
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PsiConcatenationUtil.java
@@ -0,0 +1,138 @@
+/*
+ * 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.psi.util;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.util.IncorrectOperationException;
+
+import java.util.List;
+
+/**
+ * User: cdr
+ */
+public class PsiConcatenationUtil {
+  public static void buildFormatString(
+    PsiExpression expression, StringBuilder formatString,
+    List<PsiExpression> formatParameters, boolean printfFormat) {
+      if (expression instanceof PsiLiteralExpression) {
+          final PsiLiteralExpression literalExpression =
+                  (PsiLiteralExpression) expression;
+          final String text = String.valueOf(literalExpression.getValue());
+          final String formatText;
+        if (printfFormat) {
+          formatText = StringUtil.escapeStringCharacters(text)
+            .replace("%", "%%").replace("\\'", "'");
+        }
+        else {
+          formatText = StringUtil.escapeStringCharacters(text)
+            .replace("'", "''").replace("{", "'{").replace("}", "'}");
+        }
+        formatString.append(formatText);
+      } else if (expression instanceof PsiPolyadicExpression) {
+          final PsiType type = expression.getType();
+          if (type != null && type.equalsToText("java.lang.String")) {
+              final PsiPolyadicExpression binaryExpression =
+                  (PsiPolyadicExpression) expression;
+            PsiExpression[] operands = binaryExpression.getOperands();
+            PsiType left = operands[0].getType();
+            boolean stringStarted = left != null && left.equalsToText("java.lang.String");
+            if (stringStarted) {
+              buildFormatString(operands[0], formatString, formatParameters, printfFormat);
+            }
+            for (int i = 1; i < operands.length; i++) {
+              PsiExpression op = operands[i];
+              PsiType optype = op.getType();
+              PsiType r = TypeConversionUtil.calcTypeForBinaryExpression(left, optype, binaryExpression.getOperationTokenType(), true);
+              if (r != null && r.equalsToText("java.lang.String") && !stringStarted) {
+                stringStarted = true;
+                PsiElement element = binaryExpression.getTokenBeforeOperand(op);
+                if (element.getPrevSibling() instanceof PsiWhiteSpace) element = element.getPrevSibling();
+                String text = binaryExpression.getText().substring(0, element.getStartOffsetInParent());
+                PsiExpression subExpression = JavaPsiFacade.getInstance(binaryExpression.getProject()).getElementFactory()
+                  .createExpressionFromText(text, binaryExpression);
+                addFormatParameter(subExpression, formatString, formatParameters, printfFormat);
+              }
+              if (stringStarted) {
+                if (optype != null && (optype.equalsToText("java.lang.String") || optype == PsiType.CHAR)) {
+                  buildFormatString(op, formatString, formatParameters, printfFormat);
+                }
+                else {
+                  addFormatParameter(op, formatString, formatParameters, printfFormat);
+                }
+              }
+              left = r;
+            }
+          }
+          else {
+              addFormatParameter(expression, formatString, formatParameters, printfFormat);
+          }
+      }
+      else {
+        addFormatParameter(expression, formatString, formatParameters, printfFormat);
+      }
+  }
+
+  private static void addFormatParameter(PsiExpression expression,
+                                         StringBuilder formatString,
+                                         List<PsiExpression> formatParameters, boolean printfFormat) {
+    final PsiType type = expression.getType();
+    if (!printfFormat) {
+      formatString.append("{" + formatParameters.size() + "}");
+    }
+    else if (type != null &&
+        (type.equalsToText("long") ||
+           type.equalsToText("int") ||
+           type.equalsToText("java.lang.Long") ||
+           type.equalsToText("java.lang.Integer"))) {
+      formatString.append("%d");
+    }
+    else {
+      formatString.append("%s");
+    }
+    formatParameters.add(getBoxedArgument(expression));
+  }
+
+  private static PsiExpression getBoxedArgument(PsiExpression arg) throws IncorrectOperationException {
+    arg = PsiUtil.deparenthesizeExpression(arg);
+    assert arg != null;
+    if (PsiUtil.isLanguageLevel5OrHigher(arg)) {
+      return arg;
+    }
+    final PsiType type = arg.getType();
+    if (!(type instanceof PsiPrimitiveType) || type.equals(PsiType.NULL)) {
+      return arg;
+    }
+    final PsiPrimitiveType primitiveType = (PsiPrimitiveType)type;
+    final String boxedQName = primitiveType.getBoxedTypeName();
+    if (boxedQName == null) {
+      return arg;
+    }
+    final GlobalSearchScope resolveScope = arg.getResolveScope();
+    final PsiElementFactory factory = JavaPsiFacade.getElementFactory(arg.getProject());
+    final PsiJavaCodeReferenceElement ref = factory.createReferenceElementByFQClassName(boxedQName, resolveScope);
+    final PsiNewExpression newExpr = (PsiNewExpression)factory.createExpressionFromText("new A(b)", null);
+    final PsiElement classRef = newExpr.getClassReference();
+    assert classRef != null;
+    classRef.replace(ref);
+    final PsiExpressionList argumentList = newExpr.getArgumentList();
+    assert argumentList != null;
+    argumentList.getExpressions()[0].replace(arg);
+    return newExpr;
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/psi/util/PsiMatchers.java b/java/openapi/src/com/intellij/psi/util/PsiMatchers.java
new file mode 100644
index 0000000..72f9367
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/PsiMatchers.java
@@ -0,0 +1,115 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author max
+ */
+package com.intellij.psi.util;
+
+import com.intellij.psi.*;
+import com.intellij.psi.xml.XmlTag;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NotNull;
+
+public class PsiMatchers {
+
+  private PsiMatchers() {
+  }
+
+  public static PsiMatcherExpression hasModifier(@PsiModifier.ModifierConstant final String modifier, final boolean shouldHave) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        PsiModifierListOwner owner = element instanceof PsiModifierListOwner ? (PsiModifierListOwner) element : null;
+
+        if (owner != null && owner.hasModifierProperty(modifier) == shouldHave) return Boolean.TRUE;
+        return Boolean.FALSE;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasText(final String text) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        if (element.getTextLength() != text.length()) return Boolean.FALSE;
+        return text.equals(element.getText());
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasText(@NotNull final String... texts) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        String text = element.getText();
+        return ArrayUtil.find(texts, text) != -1;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasClass(final Class aClass) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        if (aClass.isAssignableFrom(element.getClass())) return Boolean.TRUE;
+        return Boolean.FALSE;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasClass(final Class... classes) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        for (Class aClass : classes) {
+          if (aClass.isAssignableFrom(element.getClass())) return Boolean.TRUE;
+        }
+        return Boolean.FALSE;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasName(final String name) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        if (element instanceof PsiNamedElement && name.equals(((PsiNamedElement) element).getName())) return Boolean.TRUE;
+        if (element instanceof XmlTag && name.equals(((XmlTag) element).getName())) return Boolean.TRUE;
+        return Boolean.FALSE;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression hasTagValue(final String value) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        if (element instanceof XmlTag && value.equals(((XmlTag) element).getValue().getTrimmedText())) return Boolean.TRUE;
+        return Boolean.FALSE;
+      }
+    };
+  }
+
+  public static PsiMatcherExpression isConstructor(final boolean shouldBe) {
+    return new PsiMatcherExpression() {
+      @Override
+      public Boolean match(PsiElement element) {
+        return element instanceof PsiMethod && ((PsiMethod)element).isConstructor() == shouldBe;
+      }
+    };
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java
new file mode 100644
index 0000000..ee390db
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/RedundantCastUtil.java
@@ -0,0 +1,595 @@
+/*
+ * 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.psi.util;
+
+import com.intellij.codeInsight.AnnotationUtil;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.psi.codeStyle.CodeStyleManager;
+import com.intellij.psi.tree.IElementType;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.HashSet;
+import java.util.List;
+import java.util.Set;
+
+/**
+ * @author max
+ * Date: Mar 24, 2002
+ */
+public class RedundantCastUtil {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInspection.redundantCast.RedundantCastUtil");
+
+  private RedundantCastUtil() { }
+
+  @NotNull
+  public static List<PsiTypeCastExpression> getRedundantCastsInside(PsiElement where) {
+    MyCollectingVisitor visitor = new MyCollectingVisitor();
+    if (where instanceof PsiEnumConstant) {
+      where.accept(visitor);
+    } else {
+      where.acceptChildren(visitor);
+    }
+    return new ArrayList<PsiTypeCastExpression>(visitor.myFoundCasts);
+  }
+
+  public static boolean isCastRedundant (PsiTypeCastExpression typeCast) {
+    PsiElement parent = typeCast.getParent();
+    while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+    if (parent instanceof PsiExpressionList) parent = parent.getParent();
+    if (parent instanceof PsiReferenceExpression) parent = parent.getParent();
+    MyIsRedundantVisitor visitor = new MyIsRedundantVisitor(false);
+    parent.accept(visitor);
+    return visitor.isRedundant;
+  }
+
+  @Nullable
+  private static PsiExpression deparenthesizeExpression(PsiExpression arg) {
+    while (arg instanceof PsiParenthesizedExpression) arg = ((PsiParenthesizedExpression) arg).getExpression();
+    return arg;
+  }
+
+  public static void removeCast(PsiTypeCastExpression castExpression) {
+    if (castExpression == null) return;
+    PsiExpression operand = castExpression.getOperand();
+    if (operand instanceof PsiParenthesizedExpression) {
+      final PsiParenthesizedExpression parExpr = (PsiParenthesizedExpression)operand;
+      operand = parExpr.getExpression();
+    }
+    if (operand == null) return;
+
+    PsiElement toBeReplaced = castExpression;
+
+    PsiElement parent = castExpression.getParent();
+    while (parent instanceof PsiParenthesizedExpression) {
+      toBeReplaced = parent;
+      parent = parent.getParent();
+    }
+
+    try {
+      toBeReplaced.replace(operand);
+    }
+    catch (IncorrectOperationException e) {
+      LOG.error(e);
+    }
+  }
+
+  private static class MyCollectingVisitor extends MyIsRedundantVisitor {
+    private final Set<PsiTypeCastExpression> myFoundCasts = new HashSet<PsiTypeCastExpression>();
+
+    private MyCollectingVisitor() {
+      super(true);
+    }
+
+    @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+      expression.acceptChildren(this);
+    }
+
+    @Override public void visitClass(PsiClass aClass) {
+      // avoid multiple visit
+    }
+
+    @Override public void visitMethod(PsiMethod method) {
+      // avoid multiple visit
+    }
+
+    @Override public void visitField(PsiField field) {
+      // avoid multiple visit
+    }
+
+    @Override
+    protected void addToResults(@NotNull PsiTypeCastExpression typeCast){
+      if (!isTypeCastSemantical(typeCast)) {
+        myFoundCasts.add(typeCast);
+      }
+    }
+  }
+
+  private static class MyIsRedundantVisitor extends JavaRecursiveElementVisitor {
+    private boolean isRedundant = false;
+    private final boolean myRecursive;
+
+    private MyIsRedundantVisitor(final boolean recursive) {
+      myRecursive = recursive;
+    }
+
+    @Override
+    public void visitElement(final PsiElement element) {
+      if (myRecursive) {
+        super.visitElement(element);
+      }
+    }
+
+    protected void addToResults(@NotNull PsiTypeCastExpression typeCast){
+      if (!isTypeCastSemantical(typeCast)) {
+        isRedundant = true;
+      }
+    }
+
+    @Override public void visitAssignmentExpression(PsiAssignmentExpression expression) {
+      processPossibleTypeCast(expression.getRExpression(), expression.getLExpression().getType());
+      super.visitAssignmentExpression(expression);
+    }
+
+    @Override public void visitVariable(PsiVariable variable) {
+      processPossibleTypeCast(variable.getInitializer(), variable.getType());
+      super.visitVariable(variable);
+    }
+
+    @Override public void visitReturnStatement(PsiReturnStatement statement) {
+      final PsiMethod method = PsiTreeUtil.getParentOfType(statement, PsiMethod.class);
+      if (method != null) {
+        final PsiType returnType = method.getReturnType();
+        final PsiExpression returnValue = statement.getReturnValue();
+        if (returnValue != null) {
+          processPossibleTypeCast(returnValue, returnType);
+        }
+      }
+      super.visitReturnStatement(statement);
+    }
+
+    @Override
+    public void visitPolyadicExpression(PsiPolyadicExpression expression) {
+      IElementType tokenType = expression.getOperationTokenType();
+      PsiExpression[] operands = expression.getOperands();
+      if (operands.length >= 2) {
+        PsiType lType = operands[0].getType();
+        processBinaryExpressionOperand(deparenthesizeExpression(operands[0]), operands[1].getType(), tokenType);
+        for (int i = 1; i < operands.length; i++) {
+          PsiExpression operand = deparenthesizeExpression(operands[i]);
+          if (operand == null) continue;
+          processBinaryExpressionOperand(operand, lType, tokenType);
+          lType = TypeConversionUtil.calcTypeForBinaryExpression(lType, operand.getType(), tokenType, true);
+        }
+      }
+      super.visitPolyadicExpression(expression);
+    }
+
+    private void processBinaryExpressionOperand(final PsiExpression operand,
+                                                final PsiType otherType,
+                                                final IElementType binaryToken) {
+      if (operand instanceof PsiTypeCastExpression) {
+        PsiTypeCastExpression typeCast = (PsiTypeCastExpression)operand;
+        PsiExpression toCast = typeCast.getOperand();
+        if (toCast != null && TypeConversionUtil.isBinaryOperatorApplicable(binaryToken, toCast.getType(), otherType, false)) {
+          addToResults(typeCast);
+        }
+      }
+    }
+
+    private void processPossibleTypeCast(PsiExpression rExpr, @Nullable PsiType lType) {
+      rExpr = deparenthesizeExpression(rExpr);
+      if (rExpr instanceof PsiTypeCastExpression) {
+        PsiExpression castOperand = ((PsiTypeCastExpression)rExpr).getOperand();
+        if (castOperand != null) {
+          PsiType operandType = castOperand.getType();
+          if (operandType != null) {
+            if (lType != null && TypeConversionUtil.isAssignable(lType, operandType, false)) {
+              addToResults((PsiTypeCastExpression)rExpr);
+            }
+          }
+        }
+      }
+    }
+
+    @Override public void visitMethodCallExpression(PsiMethodCallExpression expression) {
+      processCall(expression);
+
+      checkForVirtual(expression);
+      super.visitMethodCallExpression(expression);
+    }
+
+    private void checkForVirtual(PsiMethodCallExpression methodCall) {
+      PsiReferenceExpression methodExpr = methodCall.getMethodExpression();
+      PsiExpression qualifier = methodExpr.getQualifierExpression();
+      if (!(qualifier instanceof PsiParenthesizedExpression)) return;
+      PsiExpression operand = ((PsiParenthesizedExpression)qualifier).getExpression();
+      if (!(operand instanceof PsiTypeCastExpression)) return;
+      PsiTypeCastExpression typeCast = (PsiTypeCastExpression)operand;
+      PsiExpression castOperand = typeCast.getOperand();
+      if (castOperand == null) return;
+
+      PsiType type = castOperand.getType();
+      if (type == null) return;
+      if (type instanceof PsiPrimitiveType) return;
+
+      final JavaResolveResult resolveResult = methodExpr.advancedResolve(false);
+      PsiMethod targetMethod = (PsiMethod)resolveResult.getElement();
+      if (targetMethod == null) return;
+      if (targetMethod.hasModifierProperty(PsiModifier.STATIC)) return;
+
+      try {
+        PsiManager manager = methodExpr.getManager();
+        PsiElementFactory factory = JavaPsiFacade.getInstance(manager.getProject()).getElementFactory();
+
+        PsiMethodCallExpression newCall = (PsiMethodCallExpression)factory.createExpressionFromText(methodCall.getText(), methodCall);
+        PsiExpression newQualifier = newCall.getMethodExpression().getQualifierExpression();
+        PsiExpression newOperand = ((PsiTypeCastExpression)((PsiParenthesizedExpression)newQualifier).getExpression()).getOperand();
+        newQualifier.replace(newOperand);
+
+        final JavaResolveResult newResult = newCall.getMethodExpression().advancedResolve(false);
+        if (!newResult.isValidResult()) return;
+        final PsiMethod newTargetMethod = (PsiMethod)newResult.getElement();
+        final PsiType newReturnType = newResult.getSubstitutor().substitute(newTargetMethod.getReturnType());
+        final PsiType oldReturnType = resolveResult.getSubstitutor().substitute(targetMethod.getReturnType());
+        if (Comparing.equal(newReturnType, oldReturnType)) {
+          if (newTargetMethod.equals(targetMethod) ||
+              (newTargetMethod.getSignature(newResult.getSubstitutor()).equals(targetMethod.getSignature(resolveResult.getSubstitutor())) &&
+               !(newTargetMethod.isDeprecated() && !targetMethod.isDeprecated()) &&  // see SCR11555, SCR14559
+               areThrownExceptionsCompatible(targetMethod, newTargetMethod))) {
+            addToResults(typeCast);
+          }
+        }
+      }
+      catch (IncorrectOperationException ignore) { }
+    }
+
+    private static boolean areThrownExceptionsCompatible(final PsiMethod targetMethod, final PsiMethod newTargetMethod) {
+      final PsiClassType[] oldThrowsTypes = targetMethod.getThrowsList().getReferencedTypes();
+      final PsiClassType[] newThrowsTypes = newTargetMethod.getThrowsList().getReferencedTypes();
+      for (final PsiClassType throwsType : newThrowsTypes) {
+        if (!isExceptionThrown(throwsType, oldThrowsTypes)) return false;
+      }
+      return true;
+    }
+
+    private static boolean isExceptionThrown(PsiClassType exceptionType, PsiClassType[] thrownTypes) {
+      for (final PsiClassType type : thrownTypes) {
+        if (type.equals(exceptionType)) return true;
+      }
+      return false;
+    }
+
+    @Override public void visitNewExpression(PsiNewExpression expression) {
+      processCall(expression);
+      super.visitNewExpression(expression);
+    }
+
+    @Override
+    public void visitEnumConstant(PsiEnumConstant enumConstant) {
+      processCall(enumConstant);
+      super.visitEnumConstant(enumConstant);
+    }
+
+    @Override public void visitReferenceExpression(PsiReferenceExpression expression) {
+      //expression.acceptChildren(this);
+    }
+
+    private void processCall(PsiCall expression){
+      PsiExpressionList argumentList = expression.getArgumentList();
+      if (argumentList == null) return;
+      PsiExpression[] args = argumentList.getExpressions();
+      PsiMethod oldMethod = expression.resolveMethod();
+      if (oldMethod == null) return;
+      PsiParameter[] parameters = oldMethod.getParameterList().getParameters();
+
+      try {
+        for (int i = 0; i < args.length; i++) {
+          final PsiExpression arg = deparenthesizeExpression(args[i]);
+          if (arg instanceof PsiTypeCastExpression) {
+            PsiTypeCastExpression cast = (PsiTypeCastExpression)arg;
+            if (i == args.length - 1 && args.length == parameters.length && parameters[i].isVarArgs()) {
+              //do not mark cast to resolve ambiguity for calling varargs method with inexact argument
+              continue;
+            }
+            PsiCall newCall = (PsiCall) expression.copy();
+            final PsiExpressionList argList = newCall.getArgumentList();
+            LOG.assertTrue(argList != null);
+            PsiExpression[] newArgs = argList.getExpressions();
+            PsiTypeCastExpression castExpression = (PsiTypeCastExpression) deparenthesizeExpression(newArgs[i]);
+            PsiExpression castOperand = castExpression.getOperand();
+            if (castOperand == null) return;
+            castExpression.replace(castOperand);
+            if (newCall instanceof PsiEnumConstant) {
+              // do this manually, because PsiEnumConstantImpl.resolveMethodGenerics() will assert (no containing class for the copy)
+              final PsiEnumConstant enumConstant = (PsiEnumConstant)expression;
+              PsiClass containingClass = enumConstant.getContainingClass();
+              final JavaPsiFacade facade = JavaPsiFacade.getInstance(enumConstant.getProject());
+              final PsiClassType type = facade.getElementFactory().createType(containingClass);
+              final JavaResolveResult newResult = facade.getResolveHelper().resolveConstructor(type, newCall.getArgumentList(), enumConstant);
+              if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult()) {
+                addToResults(cast);
+              }
+            } else {
+              final JavaResolveResult newResult = newCall.resolveMethodGenerics();
+              if (oldMethod.equals(newResult.getElement()) && newResult.isValidResult() &&
+                Comparing.equal(((PsiCallExpression)newCall).getType(), ((PsiCallExpression)expression).getType())) {
+                addToResults(cast);
+              }
+            }
+          }
+        }
+      }
+      catch (IncorrectOperationException e) {
+        return;
+      }
+
+      for (PsiExpression arg : args) {
+        if (arg instanceof PsiTypeCastExpression) {
+          PsiExpression castOperand = ((PsiTypeCastExpression)arg).getOperand();
+          if (castOperand != null) {
+            castOperand.accept(this);
+          }
+        }
+        else {
+          arg.accept(this);
+        }
+      }
+    }
+
+    @Override public void visitTypeCastExpression(PsiTypeCastExpression typeCast) {
+      PsiExpression operand = typeCast.getOperand();
+      if (operand == null) return;
+
+      PsiElement expr = deparenthesizeExpression(operand);
+
+      final PsiType topCastType = typeCast.getType();
+      if (expr instanceof PsiTypeCastExpression) {
+        PsiTypeElement typeElement = ((PsiTypeCastExpression)expr).getCastType();
+        if (typeElement == null) return;
+        PsiType castType = typeElement.getType();
+        final PsiExpression innerOperand = ((PsiTypeCastExpression)expr).getOperand();
+        final PsiType operandType = innerOperand != null ? innerOperand.getType() : null;
+        if (!(castType instanceof PsiPrimitiveType)) {
+          if (operandType != null && topCastType != null && TypeConversionUtil.areTypesConvertible(operandType, topCastType)) {
+            addToResults((PsiTypeCastExpression)expr);
+          }
+        } else if (PsiPrimitiveType.getUnboxedType(operandType) == topCastType) {
+          addToResults((PsiTypeCastExpression)expr);
+        }
+      }
+      else {
+        PsiElement parent = typeCast.getParent();
+        if (parent instanceof PsiConditionalExpression) {
+          //branches need to be of the same type
+          if (!Comparing.equal(operand.getType(), ((PsiConditionalExpression)parent).getType())) {
+            if (!PsiUtil.isLanguageLevel5OrHigher(typeCast)) {
+              return;
+            }
+            if (!checkResolveAfterRemoveCast(parent)) return;
+          }
+        } else if (parent instanceof PsiSynchronizedStatement && (expr instanceof PsiExpression && ((PsiExpression)expr).getType() instanceof PsiPrimitiveType)) {
+          return;
+        } else if (expr instanceof PsiLambdaExpression || expr instanceof PsiMethodReferenceExpression) {
+          if (parent instanceof PsiParenthesizedExpression && parent.getParent() instanceof PsiReferenceExpression) {
+            return;
+          }
+
+          final PsiType functionalInterfaceType = LambdaUtil.getFunctionalInterfaceType(typeCast, true);
+          if (topCastType != null && functionalInterfaceType != null && !TypeConversionUtil.isAssignable(topCastType, functionalInterfaceType, false)) return;
+        }
+        processAlreadyHasTypeCast(typeCast);
+      }
+      super.visitTypeCastExpression(typeCast);
+    }
+
+    private static boolean checkResolveAfterRemoveCast(PsiElement parent) {
+      PsiElement grandPa = parent.getParent();
+      if (grandPa instanceof PsiExpressionList) {
+        PsiExpression[] expressions = ((PsiExpressionList)grandPa).getExpressions();
+        int idx = ArrayUtil.find(expressions, parent);
+        PsiElement grandGrandPa = grandPa.getParent();
+        if (grandGrandPa instanceof PsiCall) {
+          PsiElement resolve = ((PsiCall)grandGrandPa).resolveMethod();
+          if (resolve instanceof PsiMethod) {
+            PsiCall expression = (PsiCall)grandGrandPa.copy();
+            PsiExpressionList argumentList = expression.getArgumentList();
+            LOG.assertTrue(argumentList != null);
+            PsiExpression toReplace = argumentList.getExpressions()[idx];
+            if (toReplace instanceof PsiConditionalExpression) {
+              PsiExpression thenExpression = ((PsiConditionalExpression)toReplace).getThenExpression();
+              PsiExpression elseExpression = ((PsiConditionalExpression)toReplace).getElseExpression();
+              if (thenExpression instanceof PsiTypeCastExpression) {
+                final PsiExpression thenOperand = ((PsiTypeCastExpression)thenExpression).getOperand();
+                if (thenOperand != null) {
+                  thenExpression.replace(thenOperand);
+                }
+              } else if (elseExpression instanceof PsiTypeCastExpression) {
+                final PsiExpression elseOperand = ((PsiTypeCastExpression)elseExpression).getOperand();
+                if (elseOperand != null) {
+                  elseExpression.replace(elseOperand);
+                }
+              }
+            }
+            if (expression.resolveMethod() != resolve) {
+              return false;
+            }
+          }
+        }
+      }
+      return true;
+    }
+
+    private void processAlreadyHasTypeCast(PsiTypeCastExpression typeCast){
+      PsiElement parent = typeCast.getParent();
+      while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+      if (parent instanceof PsiExpressionList) return; // do not replace in arg lists - should be handled by parent
+      if (parent instanceof PsiReturnStatement) return;
+      if (parent instanceof PsiTypeCastExpression) return;
+
+      if (isTypeCastSemantical(typeCast)) return;
+
+      PsiTypeElement typeElement = typeCast.getCastType();
+      if (typeElement == null) return;
+      final PsiType castTo = typeElement.getType();
+      final PsiType opType = typeCast.getOperand().getType();
+      if (opType == null) return;
+      if (parent instanceof PsiReferenceExpression) {
+        if (castTo instanceof PsiClassType && opType instanceof PsiPrimitiveType) return; //explicit boxing
+        //Check accessibility
+        if (opType instanceof PsiClassType) {
+          final PsiReferenceExpression refExpression = (PsiReferenceExpression)parent;
+          PsiElement element = refExpression.resolve();
+          if (!(element instanceof PsiMember)) return;
+          PsiClass accessClass = ((PsiClassType)opType).resolve();
+          if (accessClass == null) return;
+          if (!JavaPsiFacade.getInstance(parent.getProject()).getResolveHelper().isAccessible((PsiMember)element, typeCast, accessClass)) return;
+          if (!isCastRedundantInRefExpression(refExpression, typeCast.getOperand())) return;
+        }
+      }
+
+      if (arrayAccessAtTheLeftSideOfAssignment(parent)) {
+        if (TypeConversionUtil.isAssignable(opType, castTo, false) && opType.getArrayDimensions() == castTo.getArrayDimensions()) {
+          addToResults(typeCast);
+        }
+      }
+      else {
+        if (TypeConversionUtil.isAssignable(castTo, opType, false)) {
+          addToResults(typeCast);
+        }
+      }
+    }
+
+    private static boolean arrayAccessAtTheLeftSideOfAssignment(PsiElement element) {
+      PsiAssignmentExpression assignment = PsiTreeUtil.getParentOfType(element, PsiAssignmentExpression.class, false, PsiMember.class);
+      if (assignment == null) return false;
+      PsiExpression lExpression = assignment.getLExpression();
+      return PsiTreeUtil.isAncestor(lExpression, element, false) && lExpression instanceof PsiArrayAccessExpression;
+    }
+  }
+
+  private static boolean isCastRedundantInRefExpression (final PsiReferenceExpression refExpression, final PsiExpression castOperand) {
+    final PsiElement resolved = refExpression.resolve();
+    final Ref<Boolean> result = new Ref<Boolean>(Boolean.FALSE);
+    CodeStyleManager.getInstance(refExpression.getProject()).performActionWithFormatterDisabled(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          final PsiElementFactory elementFactory = JavaPsiFacade.getInstance(refExpression.getProject()).getElementFactory();
+          final PsiExpression copyExpression = elementFactory.createExpressionFromText(refExpression.getText(), refExpression);
+          if (copyExpression instanceof PsiReferenceExpression) {
+            final PsiReferenceExpression copy = (PsiReferenceExpression)copyExpression;
+            final PsiExpression qualifier = copy.getQualifierExpression();
+            if (qualifier != null) {
+              qualifier.replace(castOperand);
+              result.set(Boolean.valueOf(copy.resolve() == resolved));
+            }
+          }
+        }
+        catch (IncorrectOperationException ignore) { }
+      }
+    });
+    return result.get().booleanValue();
+  }
+
+  public static boolean isTypeCastSemantical(PsiTypeCastExpression typeCast) {
+    PsiExpression operand = typeCast.getOperand();
+    if (operand == null) return false;
+
+    if (isInPolymorphicCall(typeCast)) return true;
+
+    PsiType opType = operand.getType();
+    PsiTypeElement typeElement = typeCast.getCastType();
+    if (typeElement == null) return false;
+
+    PsiType castType = typeElement.getType();
+    if (castType instanceof PsiPrimitiveType) {
+      if (opType instanceof PsiPrimitiveType) {
+        return !opType.equals(castType); // let's suppose all not equal primitive casts are necessary
+      }
+      final PsiPrimitiveType unboxedOpType = PsiPrimitiveType.getUnboxedType(opType);
+      if (unboxedOpType != null && !unboxedOpType.equals(castType) ) {
+        return true;
+      }
+    }
+    else if (castType instanceof PsiClassType && ((PsiClassType)castType).hasParameters()) {
+      if (opType instanceof PsiClassType && ((PsiClassType)opType).isRaw()) return true;
+    } else if (castType instanceof PsiClassType && ((PsiClassType)castType).isRaw()) {
+      if (opType instanceof PsiClassType && ((PsiClassType)opType).hasParameters()) return true;
+    }
+
+    PsiElement parent = typeCast.getParent();
+    while(parent instanceof PsiParenthesizedExpression) parent = parent.getParent();
+
+    if (parent instanceof PsiBinaryExpression) {
+      PsiBinaryExpression expression = (PsiBinaryExpression)parent;
+      PsiExpression firstOperand = expression.getLOperand();
+      PsiExpression otherOperand = expression.getROperand();
+      if (PsiTreeUtil.isAncestor(otherOperand, typeCast, false)) {
+        PsiExpression temp = otherOperand;
+        otherOperand = firstOperand;
+        firstOperand = temp;
+      }
+      if (firstOperand != null && otherOperand != null && wrapperCastChangeSemantics(firstOperand, otherOperand, operand)) {
+        return true;
+      }
+    }
+    return false;
+  }
+
+  private static boolean wrapperCastChangeSemantics(PsiExpression operand, PsiExpression otherOperand, PsiExpression toCast) {
+    boolean isPrimitiveComparisonWithCast = TypeConversionUtil.isPrimitiveAndNotNull(operand.getType()) ||
+                                            TypeConversionUtil.isPrimitiveAndNotNull(otherOperand.getType());
+    boolean isPrimitiveComparisonWithoutCast = TypeConversionUtil.isPrimitiveAndNotNull(toCast.getType()) ||
+                                               TypeConversionUtil.isPrimitiveAndNotNull(otherOperand.getType());
+    // wrapper casted to primitive vs wrapper comparison
+    return isPrimitiveComparisonWithCast != isPrimitiveComparisonWithoutCast;
+  }
+
+  // see http://download.java.net/jdk7/docs/api/java/lang/invoke/MethodHandle.html#sigpoly
+  public static boolean isInPolymorphicCall(final PsiTypeCastExpression typeCast) {
+    if (!PsiUtil.isLanguageLevel7OrHigher(typeCast)) return false;
+
+    // return type
+    final PsiExpression operand = typeCast.getOperand();
+    if (operand instanceof PsiMethodCallExpression) {
+      if (isPolymorphicMethod((PsiMethodCallExpression)operand)) return true;
+    }
+
+    // argument type
+    final PsiElement exprList = typeCast.getParent();
+    if (exprList instanceof PsiExpressionList) {
+      final PsiElement methodCall = exprList.getParent();
+      if (methodCall instanceof PsiMethodCallExpression) {
+        if (isPolymorphicMethod((PsiMethodCallExpression)methodCall)) return true;
+      }
+    }
+
+    return false;
+  }
+
+  private static boolean isPolymorphicMethod(PsiMethodCallExpression expression) {
+    final PsiElement method = expression.getMethodExpression().resolve();
+    return method instanceof PsiMethod &&
+           AnnotationUtil.isAnnotated((PsiMethod)method, CommonClassNames.JAVA_LANG_INVOKE_MH_POLYMORPHIC, false, true);
+  }
+}
diff --git a/java/openapi/src/com/intellij/psi/util/package.html b/java/openapi/src/com/intellij/psi/util/package.html
new file mode 100644
index 0000000..879ab75
--- /dev/null
+++ b/java/openapi/src/com/intellij/psi/util/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides utility classes for working with the PSI.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java b/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java
new file mode 100644
index 0000000..5e85056
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/ConvertToInstanceMethodRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+
+/**
+ * @author dsl
+ */
+public interface ConvertToInstanceMethodRefactoring extends Refactoring {
+  PsiMethod getMethod();
+  PsiParameter getTargetParameter();
+  PsiClass getTargetClass();
+}
+
diff --git a/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java b/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java
new file mode 100644
index 0000000..9f61de9
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/IntroduceParameterRefactoring.java
@@ -0,0 +1,33 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * @author dsl
+ */
+public interface IntroduceParameterRefactoring extends Refactoring {
+  int REPLACE_FIELDS_WITH_GETTERS_NONE = 0;
+  int REPLACE_FIELDS_WITH_GETTERS_INACCESSIBLE = 1;
+  int REPLACE_FIELDS_WITH_GETTERS_ALL = 2;
+
+  void enforceParameterType(PsiType forcedType);
+  void setFieldReplacementPolicy(int policy);
+
+  PsiType getForcedType();
+  int getFieldReplacementPolicy();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java b/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java
new file mode 100644
index 0000000..de1f07a
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRefactoringActionHandlerFactory.java
@@ -0,0 +1,203 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.openapi.components.ServiceManager;
+
+public abstract class JavaRefactoringActionHandlerFactory {
+  public static JavaRefactoringActionHandlerFactory getInstance() {
+    return ServiceManager.getService(JavaRefactoringActionHandlerFactory.class);
+  }
+
+  /**
+   * Creates handler for Anonymous To Inner refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * is not implemented.
+   * @return
+   */
+  public abstract RefactoringActionHandler createAnonymousToInnerHandler();
+
+  /**
+   * Creates handler for Pull Members Up refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either a {@link com.intellij.psi.PsiClass}, {@link com.intellij.psi.PsiField} or {@link com.intellij.psi.PsiMethod}.
+   * In latter two cases, <code>elements[0]</code> is a member that will be preselected.
+   */
+  public abstract RefactoringActionHandler createPullUpHandler();
+
+  /**
+   * Creates handler for Push Members Down refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either a {@link com.intellij.psi.PsiClass}, {@link com.intellij.psi.PsiField} or {@link com.intellij.psi.PsiMethod}.
+   * In latter two cases, <code>elements[0]</code> is a member that will be preselected.
+   */
+  public abstract RefactoringActionHandler createPushDownHandler();
+
+  /**
+   * Creates handler for Use Interface Where Possible refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiClass</code>.
+   * @return
+   */
+  public abstract RefactoringActionHandler createTurnRefsToSuperHandler();
+
+  /**
+   * Creates handler for Replace Temp With Query refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * is not implemented.
+   */
+  public abstract RefactoringActionHandler createTempWithQueryHandler();
+
+  /**
+   * Creates handler for Introduce Parameter refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced parameter,
+   * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced parameter.
+   */
+  public abstract RefactoringActionHandler createIntroduceParameterHandler();
+
+  /**
+   * Creates handler for Make Method Static refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiMethod</code>.
+   */
+  public abstract RefactoringActionHandler createMakeMethodStaticHandler();
+
+  /**
+   * Creates handler for Convert To Instance Method refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiMethod</code>.
+   */
+  public abstract RefactoringActionHandler createConvertToInstanceMethodHandler();
+
+  /**
+   * Creates handler for Replace Constructor With Factory Method refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either a <code>PsiMethod</code> that is a constructor, or a <code>PsiClass</code>
+   * with implicit default constructor.
+   */
+  public abstract RefactoringActionHandler createReplaceConstructorWithFactoryHandler();
+
+
+  /**
+   * Creates handler for Replace Constructor With Factory Method refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either a <code>PsiClass</code> or any number of <code>PsiField</code>s.
+   */
+  public abstract RefactoringActionHandler createEncapsulateFieldsHandler();
+
+  /**
+   * Creates handler for Replace Method Code Duplicates refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts one <code>PsiMethod</code>.
+   */
+  public abstract RefactoringActionHandler createMethodDuplicatesHandler();
+
+  /**
+   * Creates handler for Change Method/Class Signature refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either 1 <code>PsiMethod</code> or 1 <code>PsiClass</code>
+   */
+  public abstract RefactoringActionHandler createChangeSignatureHandler();
+
+  /**
+   * Creates handler for Extract Superclass refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiClass</code>.
+   */
+  public abstract RefactoringActionHandler createExtractSuperclassHandler();
+
+  /**
+   * Creates handler for Generify (aka Type Cook) refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts any number of arbitrary <code>PsiElement</code>s. All code inside these elements will be generified.
+   */
+  public abstract RefactoringActionHandler createTypeCookHandler();
+
+  /**
+   * Creates handler for Inline refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 inlinable <code>PsiElement</code> (method, local variable or constant).
+   */
+  public abstract RefactoringActionHandler createInlineHandler();
+
+  /**
+   * Creates handler for Extract Method refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * is not implemented.
+   */
+  public abstract RefactoringActionHandler createExtractMethodHandler();
+
+  public abstract RefactoringActionHandler createInheritanceToDelegationHandler();
+
+  /**
+   * Creates handler for Extract Interface refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiClass</code>.
+   */
+  public abstract RefactoringActionHandler createExtractInterfaceHandler();
+
+  /**
+   * Creates handler for Introduce Field refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced field,
+   * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced field.
+   */
+  public abstract RefactoringActionHandler createIntroduceFieldHandler();
+
+  /**
+   * Creates handler for Introduce Variable refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiExpression</code>, that will be an initialzier for introduced variable.
+   */
+  public abstract RefactoringActionHandler createIntroduceVariableHandler();
+
+  /**
+   * Creates handler for Introduce Constant refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts either 1 <code>PsiExpression</code>, that will be an initialzier for introduced constant,
+   * or 1 <code>PsiLocalVariable</code>, that will be replaced with introduced constant.
+   */
+  public abstract RefactoringActionHandler createIntroduceConstantHandler();
+
+  /**
+   * Creates handler for Invert Boolean refactoring.<p>
+   *
+   * {@link RefactoringActionHandler#invoke(com.intellij.openapi.project.Project, com.intellij.psi.PsiElement[], com.intellij.openapi.actionSystem.DataContext)}
+   * accepts 1 <code>PsiMethod</code>, that will be inverted
+   */
+  public abstract RefactoringActionHandler createInvertBooleanHandler();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java b/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java
new file mode 100644
index 0000000..0713b41
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRefactoringFactory.java
@@ -0,0 +1,128 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author dsl
+ */
+public abstract class JavaRefactoringFactory extends RefactoringFactory {
+  public static JavaRefactoringFactory getInstance(Project project) {
+    return (JavaRefactoringFactory) ServiceManager.getService(project, RefactoringFactory.class);
+  }
+
+  public abstract JavaRenameRefactoring createRename(PsiElement element, String newName);
+
+  @Nullable("in case the source file is not located under any source root")
+  public abstract MoveInnerRefactoring createMoveInner(PsiClass innerClass, String newName,
+                                                       boolean passOuterClass, String parameterName);
+
+  /**
+   * Creates move destination for a specified package that preserves source folders for moved items.
+   */
+  public abstract MoveDestination createSourceFolderPreservingMoveDestination(@NotNull String targetPackageQualifiedName);
+
+  /**
+   * Creates move destination for a specified package that moves all items to a specifed source folder
+   */
+  public abstract MoveDestination createSourceRootMoveDestination(@NotNull String targetPackageQualifiedName, @NotNull VirtualFile sourceRoot);
+
+  public abstract MoveClassesOrPackagesRefactoring createMoveClassesOrPackages(PsiElement[] elements, MoveDestination moveDestination);
+
+  public abstract MoveMembersRefactoring createMoveMembers(PsiMember[] elements,
+                                                           String targetClassQualifiedName,
+                                                           String newVisibility);
+
+  public abstract MoveMembersRefactoring createMoveMembers(PsiMember[] elements,
+                                                           String targetClassQualifiedName,
+                                                           String newVisibility,
+                                                           boolean makeEnumConstants);
+
+  public abstract MakeStaticRefactoring<PsiMethod> createMakeMethodStatic(PsiMethod method,
+                                                                          boolean replaceUsages,
+                                                                          String classParameterName,
+                                                                          PsiField[] fields,
+                                                                          String[] names);
+
+  public abstract MakeStaticRefactoring<PsiClass> createMakeClassStatic(PsiClass aClass,
+                                                                        boolean replaceUsages,
+                                                                        String classParameterName,
+                                                                        PsiField[] fields,
+                                                                        String[] names);
+
+  public abstract ConvertToInstanceMethodRefactoring createConvertToInstanceMethod(PsiMethod method,
+                                                                                   PsiParameter targetParameter);
+
+  public abstract TurnRefsToSuperRefactoring createTurnRefsToSuper(PsiClass aClass,
+                                                                   PsiClass aSuper,
+                                                                   boolean replaceInstanceOf);
+
+  public abstract ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiMethod method,
+                                                                                               PsiClass targetClass,
+                                                                                               String factoryName);
+
+  public abstract ReplaceConstructorWithFactoryRefactoring createReplaceConstructorWithFactory(PsiClass originalClass,
+                                                                                               PsiClass targetClass,
+                                                                                               String factoryName);
+
+  public abstract TypeCookRefactoring createTypeCook(PsiElement[] elements,
+                                                     boolean dropObsoleteCasts,
+                                                     boolean leaveObjectsRaw,
+                                                     boolean preserveRawArrays,
+                                                     boolean exhaustive,
+                                                     boolean cookObjects,
+                                                     boolean cookToWildcards);
+
+  /**
+   * Creates Introduce Parameter refactoring that replaces local variable with parameter.
+   * @param methodToReplaceIn Method that the local variable should be replaced in.
+   * @param methodToSearchFor Method that usages of should be updated (for overriding methods)
+   * @param parameterName Name of new parameter.
+   * @param parameterInitializer Initializer to use in method calls.
+   * @param localVariable local variable that will be replaced
+   * @param removeLocalVariable should local variable be removed
+   * @param declareFinal should created parameter be declared <code>final</code>
+   */
+  public abstract IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn,
+                                                                                    PsiMethod methodToSearchFor,
+                                                                                    String parameterName, PsiExpression parameterInitializer,
+                                                                                    PsiLocalVariable localVariable,
+                                                                                    boolean removeLocalVariable, boolean declareFinal);
+
+  /**
+   * Creates Introduce Parameter refactoring that replaces expression with parameter.
+   * @param methodToReplaceIn Method that the local variable should be replaced in.
+   * @param methodToSearchFor Method that usages of should be updated (for overriding methods)
+   * @param parameterName Name of new parameter.
+   * @param parameterInitializer Initializer to use in method calls.
+   * @param expressionToSearchFor expression that should be replaced with parameters
+   * @param declareFinal should created parameter be declared <code>final</code>
+   * @param replaceAllOccurences should all occurences of expression be replaced
+   */
+  public abstract IntroduceParameterRefactoring createIntroduceParameterRefactoring(PsiMethod methodToReplaceIn,
+                                                                                    PsiMethod methodToSearchFor,
+                                                                                    String parameterName,
+                                                                                    PsiExpression parameterInitializer,
+                                                                                    PsiExpression expressionToSearchFor,
+                                                                                    boolean declareFinal,
+                                                                                    final boolean replaceAllOccurences);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java b/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java
new file mode 100644
index 0000000..1bc9994
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/JavaRenameRefactoring.java
@@ -0,0 +1,25 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+/**
+ * @author yole
+ */
+public interface JavaRenameRefactoring extends RenameRefactoring {
+  void setShouldRenameVariables(boolean value);
+
+  void setShouldRenameInheritors(boolean value);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java b/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java
new file mode 100644
index 0000000..5460e5c
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MakeStaticRefactoring.java
@@ -0,0 +1,39 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiField;
+import com.intellij.psi.PsiTypeParameterListOwner;
+
+import java.util.List;
+
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author ven
+ */
+public interface MakeStaticRefactoring<T extends PsiTypeParameterListOwner> extends Refactoring {
+  T getMember();
+
+  boolean isReplaceUsages();
+
+  String getClassParameterName();
+
+  List<PsiField> getFields();
+
+  @Nullable
+  String getParameterNameForField(PsiField field);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java
new file mode 100644
index 0000000..41905e1
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveClassesOrPackagesRefactoring.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface MoveClassesOrPackagesRefactoring extends Refactoring {
+  List<PsiElement> getElements();
+
+  PackageWrapper getTargetPackage();
+
+  void setSearchInComments(boolean value);
+
+  void setSearchInNonJavaFiles(boolean value);
+
+  boolean isSearchInComments();
+
+  boolean isSearchInNonJavaFiles();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveDestination.java b/java/openapi/src/com/intellij/refactoring/MoveDestination.java
new file mode 100644
index 0000000..229a5dc
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveDestination.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleUtil;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.usageView.UsageInfo;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.containers.MultiMap;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * Represents a destination of Move Classes/Packages refactoring.
+ * Destination of Move refactoring is generally a single package,
+ * and various <code>MoveDestination</code>s control how moved items
+ * will be layouted in directories corresponding to target packages.
+ *
+ * Instances of this interface can be obtained via methods of {@link RefactoringFactory}.
+ *
+ * @see JavaRefactoringFactory#createSourceFolderPreservingMoveDestination(String) 
+ * @see JavaRefactoringFactory#createSourceRootMoveDestination(java.lang.String, com.intellij.openapi.vfs.VirtualFile)
+ *  @author dsl
+ */
+public interface MoveDestination {
+  /**
+   * Invoked in command & write action
+   */
+  PsiDirectory getTargetDirectory(PsiDirectory source) throws IncorrectOperationException;
+  /**
+   * Invoked in command & write action
+   */
+  PsiDirectory getTargetDirectory(PsiFile source) throws IncorrectOperationException;
+
+  PackageWrapper getTargetPackage();
+
+  PsiDirectory getTargetIfExists(PsiDirectory source);
+  PsiDirectory getTargetIfExists(PsiFile source);
+
+  @Nullable
+  String verify(PsiFile source);
+  @Nullable
+  String verify(PsiDirectory source);
+  @Nullable
+  String verify(PsiPackage source);
+
+  void analyzeModuleConflicts(final Collection<PsiElement> elements, MultiMap<PsiElement,String> conflicts, final UsageInfo[] usages);
+
+  boolean isTargetAccessible(Project project, VirtualFile place);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java
new file mode 100644
index 0000000..a22b890
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveInnerRefactoring.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+
+/**
+ * @author dsl
+ */
+public interface MoveInnerRefactoring extends Refactoring {
+
+  PsiClass getInnerClass();
+
+  String getNewClassName();
+
+  boolean shouldPassParameter();
+
+  String getParameterName();
+
+  void setSearchInComments(boolean value);
+
+  void setSearchInNonJavaFiles(boolean value);
+
+  boolean isSearchInComments();
+
+  boolean isSearchInNonJavaFiles();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java
new file mode 100644
index 0000000..9cd9570
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveInstanceMethodRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiVariable;
+
+/**
+ * @author ven
+ */
+public interface MoveInstanceMethodRefactoring extends Refactoring {
+  PsiMethod getMethod();
+  PsiVariable getTargetVariable();
+  PsiClass getTargetClass();
+}
+
diff --git a/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java b/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java
new file mode 100644
index 0000000..3beafce
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/MoveMembersRefactoring.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface MoveMembersRefactoring extends Refactoring {
+  List<PsiElement> getMembers();
+
+  PsiClass getTargetClass();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/PackageWrapper.java b/java/openapi/src/com/intellij/refactoring/PackageWrapper.java
new file mode 100644
index 0000000..7fd5de5
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/PackageWrapper.java
@@ -0,0 +1,74 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.PsiPackage;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * Represents a package. 
+ *  @author dsl
+ */
+public class PackageWrapper {
+  private final PsiManager myManager;
+  @NotNull private final String myQualifiedName;
+
+  public PackageWrapper(PsiManager manager, @NotNull String qualifiedName) {
+    myManager = manager;
+    myQualifiedName = qualifiedName;
+  }
+
+  public PackageWrapper(PsiPackage aPackage) {
+    myManager = aPackage.getManager();
+    myQualifiedName = aPackage.getQualifiedName();
+  }
+
+  public PsiManager getManager() { return myManager; }
+
+  public PsiDirectory[] getDirectories() {
+    String qName = myQualifiedName;
+    while (qName.endsWith(".")) {
+      qName = StringUtil.trimEnd(qName, ".");
+    }
+    final PsiPackage aPackage = JavaPsiFacade.getInstance(myManager.getProject()).findPackage(qName);
+    if (aPackage != null) {
+      return aPackage.getDirectories();
+    } else {
+      return PsiDirectory.EMPTY_ARRAY;
+    }
+  }
+
+  public boolean exists() {
+    return JavaPsiFacade.getInstance(myManager.getProject()).findPackage(myQualifiedName) != null;
+  }
+
+  @NotNull
+  public String getQualifiedName() {
+    return myQualifiedName;
+  }
+
+  public boolean equalToPackage(PsiPackage aPackage) {
+    return aPackage != null && myQualifiedName.equals(aPackage.getQualifiedName());
+  }
+
+  public static PackageWrapper create(PsiPackage aPackage) {
+    return new PackageWrapper(aPackage);
+  }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java b/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java
new file mode 100644
index 0000000..4b488f6
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/ReplaceConstructorWithFactoryRefactoring.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMethod;
+
+/**
+ * @author dsl
+ */
+public interface ReplaceConstructorWithFactoryRefactoring extends Refactoring {
+  PsiClass getOriginalClass();
+  PsiClass getTargetClass();
+
+  /**
+   * @return null if applied to implicit default constructor
+   */
+  PsiMethod getConstructor();
+
+  String getFactoryName();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java b/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java
new file mode 100644
index 0000000..90b15a9
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/TurnRefsToSuperRefactoring.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiClass;
+
+/**
+ * @author dsl
+ */
+public interface TurnRefsToSuperRefactoring extends Refactoring {
+  PsiClass getSuper();
+  PsiClass getTarget();
+  boolean isReplaceInstanceOf();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java b/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java
new file mode 100644
index 0000000..f5ed79d
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/TypeCookRefactoring.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.psi.PsiElement;
+
+import java.util.List;
+
+/**
+ * @author dsl
+ */
+public interface TypeCookRefactoring extends Refactoring {
+  List<PsiElement> getElements();
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java b/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java
new file mode 100644
index 0000000..095f6b1
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/JavaRefactoringListenerManager.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.listeners;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.components.ServiceManager;
+
+/**
+ * @author yole
+ */
+public abstract class JavaRefactoringListenerManager {
+  /**
+   * Registers a listener for moving member by pull up, push down and extract super class/interface refactorings.
+   * @param moveMembersListener listener to register
+   */
+  public abstract void addMoveMembersListener(MoveMemberListener moveMembersListener);
+
+  /**
+   * Unregisters a previously registered listener.
+   * @param moveMembersListener listener to unregister
+   */
+  public abstract void removeMoveMembersListener(MoveMemberListener moveMembersListener);
+
+  public static JavaRefactoringListenerManager getInstance(Project project) {
+    return ServiceManager.getService(project, JavaRefactoringListenerManager.class);
+  }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java b/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java
new file mode 100644
index 0000000..88f3022
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/MoveMemberListener.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.refactoring.listeners;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiMember;
+
+/**
+ * Notifies that a certain member has been moved.
+ * This listener is invoked by pull up, push down and extract super refactorings.
+ * To subscribe to move refactoring use {@link com.intellij.refactoring.listeners.RefactoringElementListener} class.
+ * @author ven
+ */
+public interface MoveMemberListener {
+  /**
+   * @param sourceClass the class member was in before the refactoring
+   * @param member the member that has been moved. To obtain target class use
+   * {@link com.intellij.psi.PsiMember#getContainingClass()}. In all cases but
+   * "Move inner to upper level" target class wil be non null.
+   */
+  void memberMoved (PsiClass sourceClass, PsiMember member);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/listeners/package.html b/java/openapi/src/com/intellij/refactoring/listeners/package.html
new file mode 100644
index 0000000..2be93a0
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/listeners/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for receiving notifications when elements are renamed or moved by
+refactoring operations.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/package.html b/java/openapi/src/com/intellij/refactoring/package.html
new file mode 100644
index 0000000..a61221c
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for invoking IDEA refactorings.
+</body></html>
diff --git a/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java b/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java
new file mode 100644
index 0000000..e75e9c7
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/rename/RegExpValidator.java
@@ -0,0 +1,36 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.refactoring.rename;
+
+import com.intellij.openapi.util.Condition;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public class RegExpValidator implements Condition<String> {
+
+  private final String myPattern;
+
+  public RegExpValidator(@NonNls String pattern) {
+    myPattern = pattern;
+  }
+
+  public boolean value(final String object) {
+    return object.matches(myPattern);
+  }
+}
diff --git a/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java
new file mode 100644
index 0000000..af731fb
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/safeDelete/JavaSafeDeleteDelegate.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.safeDelete;
+
+import com.intellij.lang.LanguageExtension;
+import com.intellij.psi.PsiMethod;
+import com.intellij.psi.PsiParameter;
+import com.intellij.psi.PsiReference;
+import com.intellij.usageView.UsageInfo;
+
+import java.util.List;
+
+/**
+ * @author Max Medvedev
+ */
+public interface JavaSafeDeleteDelegate {
+  LanguageExtension<JavaSafeDeleteDelegate> EP =
+    new LanguageExtension<JavaSafeDeleteDelegate>("com.intellij.refactoring.safeDelete.JavaSafeDeleteDelegate");
+
+  void createUsageInfoForParameter(final PsiReference reference,
+                                   final List<UsageInfo> usages,
+                                   final PsiParameter parameter,
+                                   final PsiMethod method);
+}
diff --git a/java/openapi/src/com/intellij/refactoring/util/package.html b/java/openapi/src/com/intellij/refactoring/util/package.html
new file mode 100644
index 0000000..7f7b2f6
--- /dev/null
+++ b/java/openapi/src/com/intellij/refactoring/util/package.html
@@ -0,0 +1,21 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides classes which represent usages of elements affected by refactoring.
+Provides common utility methods used by refactorings
+</body></html>
diff --git a/java/openapi/src/com/intellij/ui/UIHelper.java b/java/openapi/src/com/intellij/ui/UIHelper.java
new file mode 100644
index 0000000..977e897
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/UIHelper.java
@@ -0,0 +1,76 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.PackageChooser;
+import com.intellij.openapi.ui.SplitterProportionsData;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiType;
+import com.intellij.util.Function;
+import com.intellij.util.containers.Convertor;
+import com.intellij.util.ui.Table;
+import com.intellij.ui.treeStructure.treetable.TreeTable;
+
+import javax.swing.*;
+import javax.swing.table.TableCellRenderer;
+import javax.swing.tree.TreeCellRenderer;
+import javax.swing.tree.TreePath;
+import java.awt.*;
+
+/** @deprecated to remove in IDEA 13 */
+@SuppressWarnings({"UnusedDeclaration", "deprecation"})
+public interface UIHelper {
+  void installToolTipHandler(JTree tree);
+
+  void installToolTipHandler(JTable table);
+
+  void installEditSourceOnDoubleClick(JTree tree);
+
+  void installEditSourceOnDoubleClick(TreeTable tree);
+
+  void installEditSourceOnDoubleClick(Table table);
+
+  void installTreeTableSpeedSearch(TreeTable treeTable);
+
+  void installTreeTableSpeedSearch(TreeTable treeTable, Convertor<TreePath, String> convertor);
+
+  void installTreeSpeedSearch(JTree tree);
+
+  void installTreeSpeedSearch(JTree tree, Convertor<TreePath, String> convertor);
+
+  void installListSpeedSearch(JList list);
+
+  void installListSpeedSearch(JList list, Function<Object, String> elementTextDelegate);
+
+  void installEditSourceOnEnterKeyHandler(JTree tree);
+
+  SplitterProportionsData createSplitterProportionsData();
+
+  TableCellRenderer createPsiElementRenderer(PsiElement psiElement, Project project);
+
+  TreeCellRenderer createHighlightableTreeCellRenderer();
+
+  void drawDottedRectangle(Graphics g, int x, int y, int i, int i1);
+
+  void installSmartExpander(JTree tree);
+
+  void installSelectionSaver(JTree tree);
+
+  TextComponent createTypedTextField(final String text, PsiType type, PsiElement context, final Project project);
+
+  PackageChooser createPackageChooser(String title, Project project);
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
new file mode 100644
index 0000000..2749c34
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilter.java
@@ -0,0 +1,117 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.ui.classFilter;
+
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.InvalidDataException;
+import com.intellij.openapi.util.JDOMExternalizable;
+import com.intellij.openapi.util.WriteExternalException;
+import org.jdom.Element;
+
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public class ClassFilter implements JDOMExternalizable, Cloneable{
+  private static final Logger LOG = Logger.getInstance("#com.intellij.ui.classFilter.ClassFilter");
+  public static final ClassFilter[] EMPTY_ARRAY = new ClassFilter[0];
+
+  public String PATTERN = "";
+  public boolean ENABLED = true;
+  private Matcher myMatcher;  // to speedup matching
+
+  public ClassFilter() {
+  }
+
+  public ClassFilter(String pattern) {
+    PATTERN = pattern;
+    ENABLED = true;
+  }
+
+  public String getPattern() {
+    return PATTERN;
+  }
+  public boolean isEnabled() {
+    return ENABLED;
+  }
+
+  public void setPattern(String pattern) {
+    if (pattern != null && !pattern.equals(PATTERN)) {
+      PATTERN = pattern;
+      myMatcher = null;
+    }
+  }
+  public void setEnabled(boolean value) {
+    ENABLED = value;
+  }
+
+  public String toString() {
+    return getPattern();
+  }
+
+  public void readExternal(Element element) throws InvalidDataException {
+    DefaultJDOMExternalizer.readExternal(this, element);
+  }
+
+  public void writeExternal(Element element) throws WriteExternalException {
+    DefaultJDOMExternalizer.writeExternal(this, element);
+  }
+
+  public boolean equals(Object o) {
+    if (this == o) return true;
+    if (!(o instanceof ClassFilter)) return false;
+
+    ClassFilter classFilter = (ClassFilter)o;
+
+    if (isEnabled() != classFilter.isEnabled()) return false;
+    if (!getPattern().equals(classFilter.getPattern())) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = PATTERN.hashCode();
+    result = 29 * result + (ENABLED ? 1 : 0);
+    return result;
+  }
+
+  public ClassFilter clone() {
+    try {
+      return (ClassFilter) super.clone();
+    } catch (CloneNotSupportedException e) {
+      LOG.error(e);
+      return null;
+    }
+  }
+
+  public boolean matches(String name) {
+    return getMatcher(name).matches();
+  }
+
+  private Matcher getMatcher(final String name) {
+    if (myMatcher == null) {
+      // need to quote dots and dollars
+      final String regex = getPattern().replaceAll("\\.", "\\\\.").replaceAll("\\$", "\\\\\\$").replaceAll("\\*", ".*");
+      final Pattern pattern = Pattern.compile(regex);
+      myMatcher = pattern.matcher("");
+    }
+    myMatcher.reset(name);
+    return myMatcher;
+  }
+
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
new file mode 100644
index 0000000..85d92f5
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditor.java
@@ -0,0 +1,349 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Class ClassFilterEditor
+ * @author Jeka
+ */
+package com.intellij.ui.classFilter;
+
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.util.PsiTreeUtil;
+import com.intellij.ui.*;
+import com.intellij.ui.table.JBTable;
+import com.intellij.util.IconUtil;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.ComponentWithEmptyText;
+import com.intellij.util.ui.ItemRemovable;
+import com.intellij.util.ui.StatusText;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import javax.swing.table.*;
+import java.awt.*;
+import java.util.Iterator;
+import java.util.LinkedList;
+import java.util.List;
+
+public class ClassFilterEditor extends JPanel implements ComponentWithEmptyText {
+  protected JBTable myTable = null;
+  protected FilterTableModel myTableModel = null;
+  protected final Project myProject;
+  private final ClassFilter myChooserFilter;
+  @Nullable
+  private final String myPatternsHelpId;
+
+  public ClassFilterEditor(Project project) {
+    this(project, null);
+  }
+
+  public ClassFilterEditor(Project project, ClassFilter classFilter) {
+    this(project, classFilter, null);
+  }
+
+  public ClassFilterEditor(Project project, ClassFilter classFilter, @Nullable String patternsHelpId) {
+    super(new BorderLayout());
+    myPatternsHelpId = patternsHelpId;
+    myTable = new JBTable();
+
+    final ToolbarDecorator decorator = ToolbarDecorator.createDecorator(myTable)
+      .addExtraAction(new AnActionButton(getAddButtonText(), getAddButtonIcon()) {
+        @Override
+        public void actionPerformed(AnActionEvent e) {
+          addClassFilter();
+        }
+
+        @Override
+        public void updateButton(AnActionEvent e) {
+          super.updateButton(e);
+          setEnabled(!myProject.isDefault());
+        }
+      });
+    if (addPatternButtonVisible()) {
+      decorator.addExtraAction(new AnActionButton(getAddPatternButtonText(), getAddPatternButtonIcon()) {
+        @Override
+        public void actionPerformed(AnActionEvent e) {
+          addPatternFilter();
+        }
+
+        @Override
+        public void updateButton(AnActionEvent e) {
+          super.updateButton(e);
+          setEnabled(!myProject.isDefault());
+        }
+      });
+    }
+    add(decorator.setRemoveAction(new AnActionButtonRunnable() {
+      @Override
+      public void run(AnActionButton button) {
+        TableUtil.removeSelectedItems(myTable);
+      }
+    }).setButtonComparator(getAddButtonText(), getAddPatternButtonText(), "Remove")
+          .disableUpDownActions().createPanel(), BorderLayout.CENTER);
+
+    myChooserFilter = classFilter;
+    myProject = project;
+
+    myTableModel = new FilterTableModel();
+    myTable.setModel(myTableModel);
+    myTable.setShowGrid(false);
+    myTable.setIntercellSpacing(new Dimension(0, 0));
+    myTable.setTableHeader(null);
+    myTable.setAutoResizeMode(JTable.AUTO_RESIZE_LAST_COLUMN);
+    myTable.setColumnSelectionAllowed(false);
+    myTable.setPreferredScrollableViewportSize(new Dimension(200, 100));
+
+    TableColumnModel columnModel = myTable.getColumnModel();
+    TableColumn column = columnModel.getColumn(FilterTableModel.CHECK_MARK);
+    int width = new JCheckBox().getPreferredSize().width;
+    column.setPreferredWidth(width);
+    column.setMaxWidth(width);
+    column.setCellRenderer(new EnabledCellRenderer(myTable.getDefaultRenderer(Boolean.class)));
+    columnModel.getColumn(FilterTableModel.FILTER).setCellRenderer(new FilterCellRenderer());
+
+    getEmptyText().setText(UIBundle.message("no.patterns"));
+  }
+
+  @NotNull
+  @Override
+  public StatusText getEmptyText() {
+    return myTable.getEmptyText();
+  }
+
+  protected String getAddButtonText() {
+    return UIBundle.message("button.add.class");
+  }
+
+  protected String getAddPatternButtonText() {
+    return UIBundle.message("button.add.pattern");
+  }
+
+  protected Icon getAddButtonIcon() {
+    return IconUtil.getAddClassIcon();
+  }
+
+  protected Icon getAddPatternButtonIcon() {
+    return IconUtil.getAddPatternIcon();
+  }
+
+  protected boolean addPatternButtonVisible() {
+    return true;
+  }
+
+  public void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
+    myTableModel.setFilters(filters);
+  }
+
+  public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
+    return myTableModel.getFilters();
+  }
+
+  public void setEnabled(boolean enabled) {
+    super.setEnabled(enabled);
+    myTable.setEnabled(enabled);
+    myTable.setRowSelectionAllowed(enabled);
+    myTableModel.fireTableDataChanged();
+  }
+
+  public void stopEditing() {
+    TableCellEditor editor = myTable.getCellEditor();
+    if (editor != null) {
+      editor.stopCellEditing();
+    }
+  }
+
+  protected final class FilterTableModel extends AbstractTableModel implements ItemRemovable {
+    private final List<com.intellij.ui.classFilter.ClassFilter> myFilters = new LinkedList<com.intellij.ui.classFilter.ClassFilter>();
+    public static final int CHECK_MARK = 0;
+    public static final int FILTER = 1;
+
+    public final void setFilters(com.intellij.ui.classFilter.ClassFilter[] filters) {
+      myFilters.clear();
+      if (filters != null) {
+        ContainerUtil.addAll(myFilters, filters);
+      }
+      fireTableDataChanged();
+    }
+
+    public com.intellij.ui.classFilter.ClassFilter[] getFilters() {
+      for (Iterator<com.intellij.ui.classFilter.ClassFilter> it = myFilters.iterator(); it.hasNext(); ) {
+        com.intellij.ui.classFilter.ClassFilter filter = it.next();
+        String pattern = filter.getPattern();
+        if (pattern == null || "".equals(pattern)) {
+          it.remove();
+        }
+      }
+      return myFilters.toArray(new com.intellij.ui.classFilter.ClassFilter[myFilters.size()]);
+    }
+
+    public com.intellij.ui.classFilter.ClassFilter getFilterAt(int index) {
+      return myFilters.get(index);
+    }
+
+    public int getFilterIndex(com.intellij.ui.classFilter.ClassFilter filter) {
+      return myFilters.indexOf(filter);
+    }
+
+    public void addRow(com.intellij.ui.classFilter.ClassFilter filter) {
+      myFilters.add(filter);
+      int row = myFilters.size() - 1;
+      fireTableRowsInserted(row, row);
+    }
+
+    public int getRowCount() {
+      return myFilters.size();
+    }
+
+    public int getColumnCount() {
+      return 2;
+    }
+
+    public Object getValueAt(int rowIndex, int columnIndex) {
+      com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
+      if (columnIndex == FILTER) {
+        return filter;
+      }
+      if (columnIndex == CHECK_MARK) {
+        return filter.isEnabled() ? Boolean.TRUE : Boolean.FALSE;
+      }
+      return null;
+    }
+
+    public void setValueAt(Object aValue, int rowIndex, int columnIndex) {
+      com.intellij.ui.classFilter.ClassFilter filter = myFilters.get(rowIndex);
+      if (columnIndex == FILTER) {
+        filter.setPattern(aValue != null ? aValue.toString() : "");
+      }
+      else if (columnIndex == CHECK_MARK) {
+        filter.setEnabled(aValue == null || ((Boolean)aValue).booleanValue());
+      }
+//      fireTableCellUpdated(rowIndex, columnIndex);
+      fireTableRowsUpdated(rowIndex, rowIndex);
+    }
+
+    public Class getColumnClass(int columnIndex) {
+      if (columnIndex == CHECK_MARK) {
+        return Boolean.class;
+      }
+      return super.getColumnClass(columnIndex);
+    }
+
+    public boolean isCellEditable(int rowIndex, int columnIndex) {
+      return isEnabled() && (columnIndex == CHECK_MARK);
+    }
+
+    public void removeRow(final int idx) {
+      myFilters.remove(idx);
+      fireTableDataChanged();
+    }
+  }
+
+  private class FilterCellRenderer extends DefaultTableCellRenderer {
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected, boolean hasFocus, int row, int column) {
+      Color color = UIUtil.getTableFocusCellBackground();
+      UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, table.getSelectionBackground());
+      Component component = super.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      if (component instanceof JLabel) {
+        ((JLabel)component).setBorder(noFocusBorder);
+      }
+      UIManager.put(UIUtil.TABLE_FOCUS_CELL_BACKGROUND_PROPERTY, color);
+      com.intellij.ui.classFilter.ClassFilter filter =
+        (com.intellij.ui.classFilter.ClassFilter)table.getValueAt(row, FilterTableModel.FILTER);
+      component.setEnabled(ClassFilterEditor.this.isEnabled() && filter.isEnabled());
+      return component;
+    }
+  }
+
+  private class EnabledCellRenderer extends DefaultTableCellRenderer {
+    private final TableCellRenderer myDelegate;
+
+    public EnabledCellRenderer(TableCellRenderer delegate) {
+      myDelegate = delegate;
+    }
+
+    public Component getTableCellRendererComponent(JTable table, Object value,
+                                                   boolean isSelected, boolean hasFocus, int row, int column) {
+      Component component = myDelegate.getTableCellRendererComponent(table, value, isSelected, hasFocus, row, column);
+      component.setEnabled(ClassFilterEditor.this.isEnabled());
+      return component;
+    }
+  }
+
+  @NotNull
+  protected com.intellij.ui.classFilter.ClassFilter createFilter(String pattern) {
+    return new com.intellij.ui.classFilter.ClassFilter(pattern);
+  }
+
+  protected void addPatternFilter() {
+    ClassFilterEditorAddDialog dialog = new ClassFilterEditorAddDialog(myProject, myPatternsHelpId);
+    dialog.show();
+    if (dialog.isOK()) {
+      String pattern = dialog.getPattern();
+      if (pattern != null) {
+        com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
+        myTableModel.addRow(filter);
+        int row = myTableModel.getRowCount() - 1;
+        myTable.getSelectionModel().setSelectionInterval(row, row);
+        myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+
+        myTable.requestFocus();
+      }
+    }
+  }
+
+  protected void addClassFilter() {
+    TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
+      UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), myChooserFilter, null);
+    chooser.showDialog();
+    PsiClass selectedClass = chooser.getSelected();
+    if (selectedClass != null) {
+      com.intellij.ui.classFilter.ClassFilter filter = createFilter(getJvmClassName(selectedClass));
+      myTableModel.addRow(filter);
+      int row = myTableModel.getRowCount() - 1;
+      myTable.getSelectionModel().setSelectionInterval(row, row);
+      myTable.scrollRectToVisible(myTable.getCellRect(row, 0, true));
+
+      myTable.requestFocus();
+    }
+  }
+
+  @Nullable
+  private static String getJvmClassName(PsiClass aClass) {
+    PsiClass parentClass = PsiTreeUtil.getParentOfType(aClass, PsiClass.class, true);
+    if (parentClass != null) {
+      final String parentName = getJvmClassName(parentClass);
+      if (parentName == null) {
+        return null;
+      }
+      return parentName + "$" + aClass.getName();
+    }
+    return aClass.getQualifiedName();
+  }
+
+  public void addPattern(String pattern) {
+    com.intellij.ui.classFilter.ClassFilter filter = createFilter(pattern);
+    myTableModel.addRow(filter);
+  }
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java
new file mode 100644
index 0000000..693f359
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/ClassFilterEditorAddDialog.java
@@ -0,0 +1,116 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * @author: Eugene Zhuravlev
+ * Date: Sep 11, 2002
+ * Time: 5:23:47 PM
+ */
+package com.intellij.ui.classFilter;
+
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.ui.DialogWrapper;
+import com.intellij.openapi.ui.Messages;
+import com.intellij.openapi.ui.TextFieldWithBrowseButton;
+import com.intellij.psi.*;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.ui.UIBundle;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.awt.event.ActionEvent;
+import java.awt.event.ActionListener;
+
+class ClassFilterEditorAddDialog extends DialogWrapper {
+  private final Project myProject;
+  private TextFieldWithBrowseButton myClassName;
+  @Nullable
+  private final String myHelpId;
+
+  public ClassFilterEditorAddDialog(Project project, @Nullable String helpId) {
+    super(project, true);
+    myProject = project;
+    myHelpId = helpId;
+    setTitle(UIBundle.message("class.filter.editor.add.dialog.title"));
+    init();
+  }
+
+  protected JComponent createCenterPanel() {
+    final JPanel panel = new JPanel(new GridBagLayout());
+    final JLabel header = new JLabel(UIBundle.message("label.class.filter.editor.add.dialog.filter.pattern"));
+    myClassName = new TextFieldWithBrowseButton(new JTextField(35));
+    final JLabel iconLabel = new JLabel(Messages.getQuestionIcon());
+    
+    panel.add(header, new GridBagConstraints(1, 0, 1, 1, 1.0, 0.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
+    panel.add(myClassName, new GridBagConstraints(1, 1, 1, 1, 1.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.HORIZONTAL, new Insets(5, 10, 0, 0), 0, 0));
+    panel.add(iconLabel, new GridBagConstraints(0, 0, 1, 2, 0.0, 1.0, GridBagConstraints.NORTHWEST, GridBagConstraints.NONE, new Insets(15, 0, 0, 0), 0, 0));
+
+    myClassName.addActionListener(new ActionListener() {
+      public void actionPerformed(ActionEvent e) {
+        PsiClass currentClass = getSelectedClass();
+        TreeClassChooser chooser = TreeClassChooserFactory.getInstance(myProject).createNoInnerClassesScopeChooser(
+          UIBundle.message("class.filter.editor.choose.class.title"), GlobalSearchScope.allScope(myProject), null, null);
+        if (currentClass != null) {
+          PsiFile containingFile = currentClass.getContainingFile();
+          if (containingFile != null) {
+            PsiDirectory containingDirectory = containingFile.getContainingDirectory();
+            if (containingDirectory != null) {
+              chooser.selectDirectory(containingDirectory);
+            }
+          }
+        }
+        chooser.showDialog();
+        PsiClass selectedClass = chooser.getSelected();
+        if (selectedClass != null) {
+          myClassName.setText(selectedClass.getQualifiedName());
+        }
+      }
+    });
+
+    myClassName.setEnabled(myProject != null);
+
+    return panel;
+  }
+
+  private PsiClass getSelectedClass() {
+    final PsiManager psiManager = PsiManager.getInstance(myProject);
+    String classQName = myClassName.getText();
+    if ("".equals(classQName)) {
+      return null;
+    }
+    return JavaPsiFacade.getInstance(psiManager.getProject()).findClass(classQName, GlobalSearchScope.allScope(myProject));
+  }
+
+  public JComponent getPreferredFocusedComponent() {
+    return myClassName.getTextField();
+  }
+
+  public String getPattern() {
+    return myClassName.getText();
+  }
+
+  protected String getDimensionServiceKey(){
+    return "#com.intellij.debugger.ui.breakpoints.BreakpointsConfigurationDialogFactory.BreakpointsConfigurationDialog.AddFieldBreakpointDialog";
+  }
+
+  @Override @Nullable
+  protected String getHelpId() {
+    return myHelpId;
+  }
+}
diff --git a/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java b/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java
new file mode 100644
index 0000000..115d57f
--- /dev/null
+++ b/java/openapi/src/com/intellij/ui/classFilter/DebuggerClassFilterProvider.java
@@ -0,0 +1,30 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.ui.classFilter;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+
+import java.util.List;
+
+/**
+ * @author Eugene Zhuravlev
+ *         Date: Oct 22, 2008
+ */
+public interface DebuggerClassFilterProvider {
+  ExtensionPointName<DebuggerClassFilterProvider> EP_NAME = new ExtensionPointName<DebuggerClassFilterProvider>("com.intellij.debuggerClassFilterProvider");
+
+  List<ClassFilter> getFilters();
+}
diff --git a/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java b/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java
new file mode 100644
index 0000000..0035c60
--- /dev/null
+++ b/java/openapi/src/com/intellij/unscramble/UnscrambleSupport.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.unscramble;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.extensions.ExtensionPointName;
+import org.jetbrains.annotations.Nullable;
+
+public interface UnscrambleSupport {
+  ExtensionPointName<UnscrambleSupport> EP_NAME = ExtensionPointName.create("com.intellij.unscrambleSupport");
+
+  @Nullable
+  String unscramble(Project project, String text, String logName);
+  String getPresentableName();
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/unscramble/package.html b/java/openapi/src/com/intellij/unscramble/package.html
new file mode 100644
index 0000000..e24ba98
--- /dev/null
+++ b/java/openapi/src/com/intellij/unscramble/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides interfaces for integrating custom stacktrace unscramblers with IDEA.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/VisibilityUtil.java b/java/openapi/src/com/intellij/util/VisibilityUtil.java
new file mode 100644
index 0000000..ed44304
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/VisibilityUtil.java
@@ -0,0 +1,155 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+/*
+ * Created by IntelliJ IDEA.
+ * User: dsl
+ * Date: 07.06.2002
+ * Time: 18:48:01
+ * To change template for new class use 
+ * Code Style | Class Templates options (Tools | IDE Options).
+ */
+package com.intellij.util;
+
+import com.intellij.psi.*;
+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;
+
+
+public class VisibilityUtil  {
+  @NonNls public static final String ESCALATE_VISIBILITY = "EscalateVisible";
+  private static final String[] visibilityModifiers = {
+    PsiModifier.PRIVATE,
+    PsiModifier.PACKAGE_LOCAL,
+    PsiModifier.PROTECTED,
+    PsiModifier.PUBLIC
+  };
+
+  private VisibilityUtil() {
+  }
+
+  public static int compare(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
+    return ArrayUtil.find(visibilityModifiers, v2) - ArrayUtil.find(visibilityModifiers, v1);
+  }
+
+  @PsiModifier.ModifierConstant
+  public static String getHighestVisibility(@PsiModifier.ModifierConstant String v1, @PsiModifier.ModifierConstant String v2) {
+    if(v1.equals(v2)) return v1;
+
+    if(PsiModifier.PRIVATE.equals(v1)) return v2;
+    if(PsiModifier.PUBLIC.equals(v1)) return PsiModifier.PUBLIC;
+    if(PsiModifier.PRIVATE.equals(v2)) return v1;
+
+    return PsiModifier.PUBLIC;
+  }
+
+  public static void escalateVisibility(PsiMember modifierListOwner, PsiElement place) throws IncorrectOperationException {
+    final String visibilityModifier = getVisibilityModifier(modifierListOwner.getModifierList());
+    int index;
+    for (index = 0; index < visibilityModifiers.length; index++) {
+      String modifier = visibilityModifiers[index];
+      if(modifier.equals(visibilityModifier)) break;
+    }
+    for(;index < visibilityModifiers.length && !PsiUtil.isAccessible(modifierListOwner, place, null); index++) {
+      @PsiModifier.ModifierConstant String modifier = visibilityModifiers[index];
+      PsiUtil.setModifierProperty(modifierListOwner, modifier, true);
+    }
+  }
+
+
+  @PsiModifier.ModifierConstant
+  public static String getPossibleVisibility(final PsiMember psiMethod, final PsiElement place) {
+    if (PsiUtil.isAccessible(psiMethod, place, null)) return getVisibilityModifier(psiMethod.getModifierList());
+    if (JavaPsiFacade.getInstance(psiMethod.getProject()).arePackagesTheSame(psiMethod, place)) {
+      return PsiModifier.PACKAGE_LOCAL;
+    }
+    if (InheritanceUtil.isInheritorOrSelf(PsiTreeUtil.getParentOfType(place, PsiClass.class),
+                                          psiMethod.getContainingClass(), true)) {
+      return PsiModifier.PROTECTED;
+    }
+    return PsiModifier.PUBLIC;
+  }
+
+  @PsiModifier.ModifierConstant
+  public static String getVisibilityModifier(PsiModifierList list) {
+    if (list == null) return PsiModifier.PACKAGE_LOCAL;
+    for (@PsiModifier.ModifierConstant String modifier : visibilityModifiers) {
+      if (list.hasModifierProperty(modifier)) {
+        return modifier;
+      }
+    }
+    return PsiModifier.PACKAGE_LOCAL;
+  }
+
+  public static String getVisibilityString(@PsiModifier.ModifierConstant String visibilityModifier) {
+    if(PsiModifier.PACKAGE_LOCAL.equals(visibilityModifier)) {
+      return "";
+    }
+    return visibilityModifier;
+  }
+
+  @Nls
+  public static String getVisibilityStringToDisplay(PsiMember member) {
+    if (member.hasModifierProperty(PsiModifier.PUBLIC)) {
+      return toPresentableText(PsiModifier.PUBLIC);
+    }
+    if (member.hasModifierProperty(PsiModifier.PROTECTED)) {
+      return toPresentableText(PsiModifier.PROTECTED);
+    }
+    if (member.hasModifierProperty(PsiModifier.PRIVATE)) {
+      return toPresentableText(PsiModifier.PRIVATE);
+    }
+    return toPresentableText(PsiModifier.PACKAGE_LOCAL);
+  }
+
+  public static String toPresentableText(@PsiModifier.ModifierConstant String modifier) {
+    return PsiBundle.visibilityPresentation(modifier);
+  }
+
+  public static void fixVisibility(UsageInfo[] usageInfos, PsiMember member, @PsiModifier.ModifierConstant String newVisibility) {
+    if (newVisibility == null) return;
+    if (ESCALATE_VISIBILITY.equals(newVisibility)) {
+      for (UsageInfo info : usageInfos) {
+        final PsiElement element = info.getElement();
+        if (element != null) {
+          escalateVisibility(member, element);
+        }
+      }
+    } else {
+       setVisibility(member.getModifierList(), newVisibility);
+    }
+  }
+
+  public static void setVisibility(PsiModifierList modifierList, @PsiModifier.ModifierConstant String newVisibility) throws IncorrectOperationException {
+    modifierList.setModifierProperty(newVisibility, true);
+  }
+
+  public static void fixVisibility(PsiExpression[] expressions, PsiMember member, String newVisibility) {
+    if (newVisibility == null) return;
+    if (ESCALATE_VISIBILITY.equals(newVisibility)) {
+      for (PsiExpression element : expressions) {
+        escalateVisibility(member, element);
+      }
+    }
+    else {
+      setVisibility(member.getModifierList(), newVisibility);
+    }
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java
new file mode 100644
index 0000000..25fb330
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFile.java
@@ -0,0 +1,52 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.util.ModificationTracker;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.xml.XmlFile;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ConfigFile extends Disposable, ModificationTracker {
+  ConfigFile[] EMPTY_ARRAY = new ConfigFile[0];
+ 
+  String getUrl();
+
+  @Nullable
+  VirtualFile getVirtualFile();
+
+  @Nullable
+  PsiFile getPsiFile();
+
+  @Nullable
+  XmlFile getXmlFile();
+
+
+  @NotNull
+  ConfigFileMetaData getMetaData();
+
+  @NotNull
+  ConfigFileInfo getInfo();
+
+  boolean isValid();
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java
new file mode 100644
index 0000000..b8b016d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileAdapter.java
@@ -0,0 +1,37 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+/**
+ * @author Gregory.Shrago
+ */
+public abstract class ConfigFileAdapter implements ConfigFileListener {
+  protected void configChanged(ConfigFile configFile) {
+  }
+
+  public void configFileAdded(ConfigFile configFile) {
+    configChanged(configFile);
+  }
+
+  public void configFileRemoved(ConfigFile configFile) {
+    configChanged(configFile);
+  }
+
+  public void configFileChanged(ConfigFile configFile) {
+    configChanged(configFile);
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java
new file mode 100644
index 0000000..adfd415
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileContainer.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.Disposable;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileContainer extends Disposable {
+  Project getProject();
+
+  void addListener(ConfigFileListener listener, Disposable parentDisposable);
+
+  void addListener(ConfigFileListener listener);
+
+  void removeListener(ConfigFileListener listener);
+
+  ConfigFile[] getConfigFiles();
+
+  ConfigFileInfoSet getConfiguration();
+
+  @Nullable
+  ConfigFile getConfigFile(ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java
new file mode 100644
index 0000000..34690fe
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileFactory.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.vfs.VirtualFile;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author nik
+ */
+public abstract class ConfigFileFactory {
+
+  public static ConfigFileFactory getInstance() {
+    return ServiceManager.getService(ConfigFileFactory.class);
+  }
+
+
+  public abstract ConfigFileMetaDataProvider createMetaDataProvider(ConfigFileMetaData... metaDatas);
+
+  public abstract ConfigFileInfoSet createConfigFileInfoSet(ConfigFileMetaDataProvider metaDataProvider);
+
+  public abstract ConfigFileContainer createConfigFileContainer(Project project, ConfigFileMetaDataProvider metaDataProvider,
+                                                              ConfigFileInfoSet configuration);
+
+  public abstract ConfigFileMetaDataRegistry createMetaDataRegistry();
+
+  @Nullable
+  public abstract VirtualFile createFile(@Nullable Project project, String url, ConfigFileVersion version, final boolean forceNew);
+
+  public abstract ConfigFileContainer createSingleFileContainer(Project project, ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java
new file mode 100644
index 0000000..0814871
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfo.java
@@ -0,0 +1,63 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ConfigFileInfo {
+  @NotNull private final ConfigFileMetaData myMetaData;
+  @NotNull private final String myUrl;
+
+
+  public ConfigFileInfo(@NotNull final ConfigFileMetaData metaData, @NotNull final String url) {
+    myMetaData = metaData;
+    myUrl = url;
+  }
+
+  @NotNull
+  public ConfigFileMetaData getMetaData() {
+    return myMetaData;
+  }
+
+  @NotNull
+  public String getUrl() {
+    return myUrl;
+  }
+
+
+  public boolean equals(final Object o) {
+    if (this == o) return true;
+    if (o == null || getClass() != o.getClass()) return false;
+
+    final ConfigFileInfo that = (ConfigFileInfo)o;
+
+    if (!myMetaData.equals(that.myMetaData)) return false;
+    if (!myUrl.equals(that.myUrl)) return false;
+
+    return true;
+  }
+
+  public int hashCode() {
+    int result;
+    result = myMetaData.hashCode();
+    result = 31 * result + myUrl.hashCode();
+    return result;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java
new file mode 100644
index 0000000..862389b
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileInfoSet.java
@@ -0,0 +1,47 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import com.intellij.openapi.util.JDOMExternalizable;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileInfoSet extends JDOMExternalizable {
+  void addConfigFile(ConfigFileInfo descriptor);
+
+  void addConfigFile(ConfigFileMetaData metaData, @NonNls String url);
+
+  void removeConfigFile(ConfigFileInfo descriptor);
+
+  void replaceConfigFile(ConfigFileMetaData metaData, @NonNls String newUrl);
+
+  void removeConfigFiles(ConfigFileMetaData... metaData);
+
+  ConfigFileInfo[] getConfigFileInfos();
+
+  void setConfigFileInfos(Collection<ConfigFileInfo> descriptors);
+
+  ConfigFileMetaDataProvider getMetaDataProvider();
+
+  @Nullable
+  ConfigFileInfo getConfigFileInfo(ConfigFileMetaData metaData);
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java
new file mode 100644
index 0000000..2d1e778
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileListener.java
@@ -0,0 +1,32 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import java.util.EventListener;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileListener extends EventListener {
+
+  void configFileAdded(ConfigFile configFile);
+
+  void configFileRemoved(ConfigFile configFile);
+
+  void configFileChanged(ConfigFile descriptor);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java
new file mode 100644
index 0000000..c3b1d0c
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaData.java
@@ -0,0 +1,113 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+import com.intellij.openapi.diagnostic.Logger;
+
+import java.util.Arrays;
+
+/**
+ * @author nik
+ */
+public class ConfigFileMetaData {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.util.descriptors.ConfigFileMetaData");
+  private final String myTitle;
+  private final String myId;
+  private final String myFileName;
+  private final String myDirectoryPath;
+  private final ConfigFileVersion[] myVersions;
+  private final ConfigFileVersion myDefaultVersion;
+  private final boolean myOptional;
+  private final boolean myFileNameFixed;
+  private final boolean myUnique;
+
+  public ConfigFileMetaData(final String title,
+                            final @NonNls String id,
+                            final @NonNls String fileName,
+                            final @NonNls String directoryPath,
+                            final ConfigFileVersion[] versions,
+                            final @Nullable ConfigFileVersion defaultVersion,
+                            final boolean optional,
+                            final boolean fileNameFixed,
+                            final boolean unique) {
+    myTitle = title;
+    myId = id;
+    myFileName = fileName;
+    myDirectoryPath = directoryPath;
+    myFileNameFixed = fileNameFixed;
+    myUnique = unique;
+    LOG.assertTrue(versions.length > 0);
+    myVersions = versions;
+    myOptional = optional;
+    myDefaultVersion = defaultVersion != null ? defaultVersion : myVersions[myVersions.length - 1];
+    LOG.assertTrue(Arrays.asList(myVersions).contains(myDefaultVersion));
+  }
+
+  public ConfigFileMetaData(final String title,
+                            final @NonNls String fileName,
+                            final @NonNls String directoryPath,
+                            final ConfigFileVersion[] versions,
+                            ConfigFileVersion defaultVersion,
+                            boolean optional,
+                            final boolean fileNameFixed,
+                            final boolean unique) {
+    this(title, fileName, fileName, directoryPath, versions, defaultVersion, optional, fileNameFixed, unique);
+  }
+
+  public String getTitle() {
+    return myTitle;
+  }
+
+  public String getId() {
+    return myId;
+  }
+
+  public String getFileName() {
+    return myFileName;
+  }
+
+  public String getDirectoryPath() {
+    return myDirectoryPath;
+  }
+
+  public boolean isOptional() {
+    return myOptional;
+  }
+
+  public ConfigFileVersion[] getVersions() {
+    return myVersions;
+  }
+
+
+  public String toString() {
+    return myTitle;
+  }
+
+  public ConfigFileVersion getDefaultVersion() {
+    return myDefaultVersion;
+  }
+
+  public boolean isFileNameFixed() {
+    return myFileNameFixed;
+  }
+
+  public boolean isUnique() {
+    return myUnique;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java
new file mode 100644
index 0000000..3ba20c2
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataProvider.java
@@ -0,0 +1,34 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.Nullable;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileMetaDataProvider {
+
+  @NotNull
+  ConfigFileMetaData[] getMetaData();
+
+  @Nullable
+  ConfigFileMetaData findMetaData(@NonNls @NotNull String id);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java
new file mode 100644
index 0000000..aaba2c4
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileMetaDataRegistry.java
@@ -0,0 +1,28 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public interface ConfigFileMetaDataRegistry extends ConfigFileMetaDataProvider {
+
+  void registerMetaData(@NotNull ConfigFileMetaData... metaData);
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java
new file mode 100644
index 0000000..43c028d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileUtil.java
@@ -0,0 +1,38 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author nik
+ */
+public class ConfigFileUtil {
+  private ConfigFileUtil() {
+  }
+
+  @NotNull
+  public static ConfigFileVersion getVersionByName(ConfigFileMetaData metaData, String name) {
+    for (ConfigFileVersion version : metaData.getVersions()) {
+      if (name.equals(version.getName())) {
+        return version;
+      }
+    }
+    return metaData.getDefaultVersion();
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java b/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java
new file mode 100644
index 0000000..1f03b7e
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/descriptors/ConfigFileVersion.java
@@ -0,0 +1,41 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.descriptors;
+
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author nik
+ */
+public class ConfigFileVersion {
+  private final String myName;
+  private @NonNls final String myTemplateName;
+
+  public ConfigFileVersion(final String name, final @NonNls String templateName) {
+    myName = name;
+    myTemplateName = templateName;
+  }
+
+
+  public String getName() {
+    return myName;
+  }
+
+  public String getTemplateName() {
+    return myTemplateName;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/net/LockException.java b/java/openapi/src/com/intellij/util/net/LockException.java
new file mode 100644
index 0000000..4213e65
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/net/LockException.java
@@ -0,0 +1,29 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.net;
+
+/**
+ * Created by IntelliJ IDEA.
+ * User: stathik
+ * Date: Dec 16, 2003
+ * Time: 9:47:01 PM
+ * To change this template use Options | File Templates.
+ */
+public class LockException extends Exception {
+  public LockException(int port) {
+    super (Integer.toString(port));
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/net/package.html b/java/openapi/src/com/intellij/util/net/package.html
new file mode 100644
index 0000000..e848fb4
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/net/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides user interface components for configuring HTTP settings.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/package.html b/java/openapi/src/com/intellij/util/package.html
new file mode 100644
index 0000000..bc7cbd7
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/package.html
@@ -0,0 +1,20 @@
+<!--
+  ~ Copyright 2000-2007 JetBrains s.r.o.
+  ~
+  ~ Licensed under the Apache License, Version 2.0 (the "License");
+  ~ you may not use this file except in compliance with the License.
+  ~ You may obtain a copy of the License at
+  ~
+  ~ http://www.apache.org/licenses/LICENSE-2.0
+  ~
+  ~ Unless required by applicable law or agreed to in writing, software
+  ~ distributed under the License is distributed on an "AS IS" BASIS,
+  ~ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+  ~ See the License for the specific language governing permissions and
+  ~ limitations under the License.
+  -->
+
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides assorted utility classes.
+</body></html>
diff --git a/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java b/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java
new file mode 100644
index 0000000..093fac1
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/CanonicalPsiTypeConverter.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * Converter for {@link com.intellij.psi.PsiType} that uses {@link com.intellij.psi.PsiType#getCanonicalText()}
+ * as string representation
+ *
+ * @author peter
+ */
+public abstract class CanonicalPsiTypeConverter extends Converter<PsiType> {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java
new file mode 100644
index 0000000..3c81020
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ClassMappingNameConverter.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import com.intellij.openapi.util.Condition;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiClassType;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.codeStyle.JavaCodeStyleManager;
+import com.intellij.psi.codeStyle.SuggestedNameInfo;
+import com.intellij.psi.codeStyle.VariableKind;
+import com.intellij.psi.util.PsiTypesUtil;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.Arrays;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.List;
+
+/**
+ * @see com.intellij.util.xml.MappingClass
+ * @author Dmitry Avdeev
+ */
+public class ClassMappingNameConverter extends ResolvingConverter.StringConverter {
+
+  @NotNull
+  @Override
+  public Collection<? extends String> getVariants(ConvertContext context) {
+    DomElement parent = context.getInvocationElement().getParent();
+    assert parent != null;
+    List<DomElement> children = DomUtil.getDefinedChildren(parent, true, true);
+    DomElement classElement = ContainerUtil.find(children, new Condition<DomElement>() {
+      @Override
+      public boolean value(DomElement domElement) {
+        return domElement.getAnnotation(MappingClass.class) != null;
+      }
+    });
+    if (classElement == null) return Collections.emptyList();
+    Object value = ((GenericDomValue)classElement).getValue();
+    if (value == null) return Collections.emptyList();
+    assert value instanceof PsiClass : classElement + " should have PsiClass type";
+    PsiClass psiClass = (PsiClass)value;
+
+    JavaCodeStyleManager codeStyleManager = JavaCodeStyleManager.getInstance(context.getProject());
+    PsiClassType classType = PsiTypesUtil.getClassType(psiClass);
+    SuggestedNameInfo info = codeStyleManager.suggestVariableName(VariableKind.LOCAL_VARIABLE, null, null, classType);
+    return Arrays.asList(info.names);
+  }
+
+  @Override
+  public PsiElement resolve(String o, ConvertContext context) {
+    DomElement parent = context.getInvocationElement().getParent();
+    assert parent != null;
+    return parent.getXmlElement();
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ClassTemplate.java b/java/openapi/src/com/intellij/util/xml/ClassTemplate.java
new file mode 100644
index 0000000..8d256bb
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ClassTemplate.java
@@ -0,0 +1,40 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import com.intellij.psi.util.ClassKind;
+import org.jetbrains.annotations.NonNls;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * To be used together with {@link com.intellij.util.xml.ExtendClass}.
+ *
+ * If specified, a 'create from usage' quick fix will create class based on the {@link #value()} template.
+ *
+ * @author peter
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ClassTemplate {
+  @NonNls String value() default "";
+
+  /**
+   * @return affects the quick fix presentable text, 'Create class ...' or 'Create interface ...', etc.
+   */
+  ClassKind kind() default ClassKind.CLASS;
+
+}
diff --git a/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java
new file mode 100644
index 0000000..a246206
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/DomJavaUtil.java
@@ -0,0 +1,82 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ProjectFileIndex;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.xml.XmlElement;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class DomJavaUtil {
+  private DomJavaUtil() {
+  }
+
+  @Nullable
+  public static PsiClass findClass(@Nullable String name, @NotNull PsiFile file, @Nullable final Module module, @Nullable final GlobalSearchScope searchScope) {
+    if (name == null) return null;
+    if (name.indexOf('$')>=0) name = name.replace('$', '.');
+
+    final GlobalSearchScope scope;
+    if (searchScope == null) {
+
+      if (module != null) {
+        file = file.getOriginalFile();
+        VirtualFile virtualFile = file.getVirtualFile();
+        if (virtualFile == null) {
+          scope = GlobalSearchScope.moduleRuntimeScope(module, true);
+        }
+        else {
+          ProjectFileIndex fileIndex = ProjectRootManager.getInstance(file.getProject()).getFileIndex();
+          boolean tests = fileIndex.isInTestSourceContent(virtualFile);
+          scope = module.getModuleRuntimeScope(tests);
+        }
+      }
+      else {
+        scope = file.getResolveScope();
+      }
+    }
+    else {
+      scope = searchScope;
+    }
+
+    final PsiClass aClass = JavaPsiFacade.getInstance(file.getProject()).findClass(name, scope);
+    if (aClass != null) {
+      assert aClass.isValid() : name;
+    }
+    return aClass;
+  }
+
+  @Nullable
+  public static PsiClass findClass(@Nullable String name, @NotNull DomElement element) {
+    assert element.isValid();
+    XmlElement xmlElement = element.getXmlElement();
+    if (xmlElement != null) {
+      assert xmlElement.isValid();
+      return findClass(name, xmlElement.getContainingFile(), element.getModule(), element.getResolveScope());
+    }
+    return null;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ExtendClass.java b/java/openapi/src/com/intellij/util/xml/ExtendClass.java
new file mode 100644
index 0000000..c207b12
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ExtendClass.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.xml;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Annotates DOM methods that return either {@link com.intellij.psi.PsiClass} or
+ * {@link com.intellij.util.xml.GenericDomValue}<{@link com.intellij.psi.PsiClass}>.
+ * Specifies that the references class should extend some other class (or implement interface).
+ * If this doesn't happen, error will appear.
+ *
+ * @see com.intellij.util.xml.ClassTemplate
+ * @author Dmitry Avdeev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface ExtendClass {
+
+  /**
+   * @return qualified name of the base class
+   */
+  String value() default "";
+
+  /**
+   * @return states that the class should be concrete and have public default constructor.
+   */
+  boolean instantiatable() default true;
+
+  /**
+   * @return states that the class implements "decorator" pattern, i.e. it should have constructor with
+   * one parameter of the same type
+   */
+  boolean canBeDecorator() default false;
+
+  boolean allowEmpty() default false;
+
+  boolean allowNonPublic() default false;
+
+  boolean allowAbstract() default true;
+
+  boolean allowInterface() default true;
+
+  boolean allowEnum() default true;
+
+  boolean jvmFormat() default true;
+}
diff --git a/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java b/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java
new file mode 100644
index 0000000..864e434
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/ExtendClassImpl.java
@@ -0,0 +1,61 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import java.lang.annotation.Annotation;
+
+/**
+ * @author peter
+*/
+@SuppressWarnings({"ClassExplicitlyAnnotation"})
+public abstract class ExtendClassImpl implements ExtendClass {
+
+  public boolean instantiatable() {
+    return false;
+  }
+
+  public boolean canBeDecorator() {
+    return false;
+  }
+
+  public boolean allowEmpty() {
+    return false;
+  }
+
+  public boolean allowNonPublic() {
+    return false;
+  }
+
+  public boolean allowAbstract() {
+    return true;
+  }
+
+  public boolean allowInterface() {
+    return true;
+  }
+
+  public boolean allowEnum() {
+    return true;
+  }
+
+  public Class<? extends Annotation> annotationType() {
+    return ExtendClass.class;
+  }
+
+  public boolean jvmFormat() {
+    return true;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java b/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java
new file mode 100644
index 0000000..40de5f8
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/JvmPsiTypeConverter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import com.intellij.psi.PsiType;
+
+/**
+ * Converter for {@link com.intellij.psi.PsiType} that uses JVM internal representation. See {@link Class#getName()}  
+ *
+ * @author peter
+ */
+public abstract class JvmPsiTypeConverter extends Converter<PsiType> {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/MappingClass.java b/java/openapi/src/com/intellij/util/xml/MappingClass.java
new file mode 100644
index 0000000..1267a6a
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/MappingClass.java
@@ -0,0 +1,27 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml;
+
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+
+/**
+ * Marks a DomElement as containing class fqn for {@link com.intellij.util.xml.ClassMappingNameConverter}
+ * @author Dmitry Avdeev
+ */
+@Retention(RetentionPolicy.RUNTIME)
+public @interface MappingClass {
+}
diff --git a/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java b/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java
new file mode 100644
index 0000000..80b5ede
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/actions/CreateClassMappingAction.java
@@ -0,0 +1,109 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml.actions;
+
+import com.intellij.ide.util.ClassFilter;
+import com.intellij.ide.util.TreeClassChooser;
+import com.intellij.ide.util.TreeClassChooserFactory;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+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.search.GlobalSearchScope;
+import com.intellij.util.containers.HashMap;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.actions.generate.DomTemplateRunner;
+import com.intellij.util.xml.ui.actions.generate.CreateDomElementAction;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Map;
+
+/**
+ * @author Dmitry Avdeev
+ */
+public abstract class CreateClassMappingAction<T extends DomElement> extends CreateDomElementAction<T> {
+
+  @Nullable private final String myBaseClass;
+  private final String myTemplate;
+
+  public CreateClassMappingAction(Class<T> contextClass, @Nullable String baseClass, String template) {
+    super(contextClass);
+    myBaseClass = baseClass;
+    myTemplate = template;
+  }
+
+  @Override
+  protected DomElement createElement(final T context, final Editor editor, PsiFile file, final Project project) {
+    PsiClass selectedClass;
+    if (!ApplicationManager.getApplication().isUnitTestMode()) {
+      PsiClass baseClass = getBaseClass(context, project, myBaseClass);
+      TreeClassChooser chooser = TreeClassChooserFactory.getInstance(project)
+        .createInheritanceClassChooser(getChooserTitle(), GlobalSearchScope.allScope(project), baseClass, null, new ClassFilter() {
+          @Override
+          public boolean isAccepted(PsiClass aClass) {
+            return !aClass.isInterface() && !aClass.hasModifierProperty(PsiModifier.ABSTRACT);
+          }
+        });
+      chooser.showDialog();
+      selectedClass = chooser.getSelected();
+    }
+    else {
+      selectedClass = getBaseClass(context, project, myBaseClass == null ? CommonClassNames.JAVA_LANG_OBJECT : myBaseClass);
+    }
+    if (selectedClass == null) return null;
+
+    return createElement(context, editor, file, project, selectedClass);
+  }
+
+  @Nullable
+  protected DomElement createElement(final T context,
+                                     final Editor editor,
+                                     final PsiFile file,
+                                     final Project project,
+                                     PsiClass selectedClass) {
+    final Map<String,String> map = new HashMap<String, String>();
+    map.put("CLASS_NAME", selectedClass.getQualifiedName());
+    new WriteCommandAction.Simple(project, file) {
+      @Override
+      protected void run() throws Throwable {
+        DomTemplateRunner.getInstance(project).runTemplate(createElement(context), myTemplate, editor, map);
+      }
+    }.execute();
+    return null;
+  }
+
+  protected String getChooserTitle() {
+    String text = getTemplatePresentation().getText();
+    if (text.endsWith("...")) {
+      text = StringUtil.trimEnd(text, "...");
+    }
+    return "Choose " + text + " Class";
+  }
+
+  protected abstract DomElement createElement(T context);
+
+  @Nullable
+  protected PsiClass getBaseClass(T context, Project project, String baseClass) {
+    return baseClass == null ? null : JavaPsiFacade.getInstance(project).findClass(baseClass, GlobalSearchScope.allScope(project));
+  }
+
+  @Override
+  public boolean startInWriteAction() {
+    return false;
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
new file mode 100644
index 0000000..230fa14
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMemberResolveConverter.java
@@ -0,0 +1,142 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.xml.converters;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.QuickFixFactory;
+import com.intellij.codeInspection.LocalQuickFix;
+import com.intellij.ide.TypePresentationService;
+import com.intellij.psi.*;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.psi.util.PropertyMemberType;
+import com.intellij.psi.util.PropertyUtil;
+import com.intellij.util.xml.*;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+
+/**
+ * @author Gregory.Shrago
+ */
+public abstract class AbstractMemberResolveConverter extends ResolvingConverter<PsiMember> {
+  @Nullable
+  protected abstract PsiClass getTargetClass(final ConvertContext context);
+
+  @NotNull
+  protected abstract PropertyMemberType[] getMemberTypes(final ConvertContext context);
+
+  @NotNull
+  protected PsiType getPsiType(final ConvertContext context) {
+    return PsiType.getJavaLangObject(context.getPsiManager(), ProjectScope.getAllScope(context.getPsiManager().getProject()));
+  }
+
+  protected boolean isLookDeep() {
+    return true;
+  }
+
+  protected String getPropertyName(final String s, final ConvertContext context) {
+    return s;
+  }
+
+  public PsiMember fromString(final String s, final ConvertContext context) {
+    if (s == null) return null;
+    final PsiClass psiClass = getTargetClass(context);
+    if (psiClass == null) return null;
+    for (PropertyMemberType type : getMemberTypes(context)) {
+      switch (type) {
+        case FIELD:
+          final PsiField field = psiClass.findFieldByName(s, isLookDeep());
+          if (field != null) return field;
+          break;
+        case GETTER:
+          final PsiMethod getter = PropertyUtil.findPropertyGetter(psiClass, getPropertyName(s, context), false, isLookDeep());
+          if (getter != null) return getter;
+          break;
+        case SETTER:
+          final PsiMethod setter = PropertyUtil.findPropertySetter(psiClass, getPropertyName(s, context), false, isLookDeep());
+          if (setter != null) return setter;
+          break;
+      }
+    }
+    return null;
+  }
+
+
+  public String toString(final PsiMember t, final ConvertContext context) {
+    return t == null? null : getPropertyName(t.getName(), context);
+  }
+
+  public String getErrorMessage(final String s, final ConvertContext context) {
+    final DomElement parent = context.getInvocationElement().getParent();
+    assert parent != null;
+    return CodeInsightBundle.message("error.cannot.resolve.0.1", TypePresentationService.getService().getTypeName(parent), s);
+  }
+
+  @NotNull
+  public Collection<? extends PsiMember> getVariants(final ConvertContext context) {
+    final PsiClass psiClass = getTargetClass(context);
+    if (psiClass == null) return Collections.emptyList();
+
+    final ArrayList<PsiMember> list = new ArrayList<PsiMember>();
+    for (PsiField psiField : isLookDeep()? psiClass.getAllFields() : psiClass.getFields()) {
+      if (fieldSuits(psiField)) {
+        list.add(psiField);
+      }
+    }
+    for (PsiMethod psiMethod : isLookDeep()? psiClass.getAllMethods() : psiClass.getMethods()) {
+      if (methodSuits(psiMethod)) {
+        list.add(psiMethod);
+      }
+    }
+    return list;
+  }
+
+  protected boolean methodSuits(final PsiMethod psiMethod) {
+    return !psiMethod.isConstructor() && !psiMethod.hasModifierProperty(PsiModifier.STATIC) && PropertyUtil.getPropertyName(psiMethod) != null;
+  }
+
+  protected boolean fieldSuits(final PsiField psiField) {
+    return !psiField.hasModifierProperty(PsiModifier.STATIC);
+  }
+
+  public LocalQuickFix[] getQuickFixes(final ConvertContext context) {
+    final String targetName = ((GenericValue)context.getInvocationElement()).getStringValue();
+    if (!JavaPsiFacade.getInstance(context.getProject()).getNameHelper().isIdentifier(targetName)) return super.getQuickFixes(context);
+    final PsiClass targetClass = getTargetClass(context);
+    if (targetClass == null) return super.getQuickFixes(context);
+    final PropertyMemberType memberType = getMemberTypes(context)[0];
+
+    final PsiType psiType = getPsiType(context);
+    final IntentionAction fix = QuickFixFactory.getInstance().createCreateFieldOrPropertyFix(targetClass, targetName, psiType, memberType);
+    return fix instanceof LocalQuickFix? new LocalQuickFix[] {(LocalQuickFix)fix} : super.getQuickFixes(context);
+  }
+
+  public void handleElementRename(final GenericDomValue<PsiMember> genericValue, final ConvertContext context, final String newElementName) {
+    super.handleElementRename(genericValue, context, getPropertyName(newElementName, context));
+  }
+
+  public void bindReference(final GenericDomValue<PsiMember> genericValue, final ConvertContext context, final PsiElement newTarget) {
+    if (newTarget instanceof PsiMember) {
+      final String elementName = ((PsiMember)newTarget).getName();
+      genericValue.setStringValue(getPropertyName(elementName, context));
+    }
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java
new file mode 100644
index 0000000..1f9ee82
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodParams.java
@@ -0,0 +1,31 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml.converters;
+
+import com.intellij.psi.PsiType;
+import com.intellij.util.xml.GenericDomValue;
+import com.intellij.util.xml.DomElement;
+
+import java.util.List;
+
+/**
+ * @author peter
+ */
+public interface AbstractMethodParams extends DomElement {
+  List<GenericDomValue<PsiType>> getMethodParams();
+
+  GenericDomValue<PsiType> addMethodParam();
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java
new file mode 100644
index 0000000..d917c15
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/AbstractMethodResolveConverter.java
@@ -0,0 +1,220 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml.converters;
+
+import com.intellij.codeInsight.CodeInsightBundle;
+import com.intellij.ide.IdeBundle;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Ref;
+import com.intellij.psi.*;
+import com.intellij.util.CommonProcessors;
+import com.intellij.util.Function;
+import com.intellij.util.Processor;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.xml.ConvertContext;
+import com.intellij.util.xml.DomElement;
+import com.intellij.util.xml.GenericDomValue;
+import com.intellij.util.xml.ResolvingConverter;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.*;
+
+/**
+ * @author peter
+ */
+public abstract class AbstractMethodResolveConverter<ParentType extends DomElement> extends ResolvingConverter<PsiMethod> {
+  public static final String ALL_METHODS = "*";
+  private final Class<ParentType> myDomMethodClass;
+
+  protected AbstractMethodResolveConverter(final Class<ParentType> domMethodClass) {
+    myDomMethodClass = domMethodClass;
+  }
+
+  @NotNull
+  protected abstract Collection<PsiClass> getPsiClasses(final ParentType parent, final ConvertContext context);
+
+  @Nullable
+  protected abstract AbstractMethodParams getMethodParams(@NotNull ParentType parent);
+
+  public void bindReference(final GenericDomValue<PsiMethod> genericValue, final ConvertContext context, final PsiElement element) {
+    assert element instanceof PsiMethod : "PsiMethod expected";
+    final PsiMethod psiMethod = (PsiMethod)element;
+    final ParentType parent = getParent(context);
+    final AbstractMethodParams methodParams = getMethodParams(parent);
+    genericValue.setStringValue(psiMethod.getName());
+    if (methodParams != null) {
+      methodParams.undefine();
+      for (PsiParameter parameter : psiMethod.getParameterList().getParameters()) {
+        methodParams.addMethodParam().setValue(parameter.getType());
+      }
+    }
+  }
+
+  public String getErrorMessage(final String s, final ConvertContext context) {
+    final ParentType parent = getParent(context);
+    return CodeInsightBundle
+      .message("error.cannot.resolve.0.1", IdeBundle.message("element.method"), getReferenceCanonicalText(s, getMethodParams(parent)));
+  }
+
+  @NotNull
+  protected final ParentType getParent(final ConvertContext context) {
+    ParentType parent = context.getInvocationElement().getParentOfType(myDomMethodClass, true);
+    assert parent != null: "Can't get parent of type " + myDomMethodClass + " for " + context.getInvocationElement();
+    return parent;
+  }
+
+  public boolean isReferenceTo(@NotNull final PsiElement element, final String stringValue, final PsiMethod resolveResult,
+                               final ConvertContext context) {
+    if (super.isReferenceTo(element, stringValue, resolveResult, context)) return true;
+
+    final Ref<Boolean> result = new Ref<Boolean>(Boolean.FALSE);
+    processMethods(context, new Processor<PsiMethod>() {
+      public boolean process(final PsiMethod method) {
+        if (method.equals(element)) {
+          result.set(Boolean.TRUE);
+          return false;
+        }
+        return true;
+      }
+    }, new Function<PsiClass, PsiMethod[]>() {
+      public PsiMethod[] fun(final PsiClass s) {
+        return s.findMethodsByName(stringValue, true);
+      }
+    });
+
+    return result.get();
+  }
+
+  @SuppressWarnings({"WeakerAccess"})
+  protected void processMethods(final ConvertContext context, Processor<PsiMethod> processor, Function<PsiClass, PsiMethod[]> methodGetter) {
+    for (PsiClass psiClass : getPsiClasses(getParent(context), context)) {
+      if (psiClass != null) {
+        for (PsiMethod psiMethod : methodGetter.fun(psiClass)) {
+          if (!processor.process(psiMethod)) {
+            return;
+          }
+        }
+      }
+    }
+  }
+
+  @NotNull
+  public Collection<? extends PsiMethod> getVariants(final ConvertContext context) {
+    LinkedHashSet<PsiMethod> methodList = new LinkedHashSet<PsiMethod>();
+    Processor<PsiMethod> processor = CommonProcessors.notNullProcessor(new CommonProcessors.CollectProcessor<PsiMethod>(methodList));
+    processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+      public PsiMethod[] fun(final PsiClass s) {
+        final List<PsiMethod> list = ContainerUtil.findAll(getVariants(s), new Condition<PsiMethod>() {
+          public boolean value(final PsiMethod object) {
+            return acceptMethod(object, context);
+          }
+        });
+        return list.toArray(new PsiMethod[list.size()]);
+      }
+    });
+    return methodList;
+  }
+
+  protected Collection<PsiMethod> getVariants(final PsiClass s) {
+    return Arrays.asList(s.getAllMethods());
+  }
+
+  protected boolean acceptMethod(final PsiMethod psiMethod, final ConvertContext context) {
+    return methodSuits(psiMethod);
+  }
+
+  public static boolean methodSuits(final PsiMethod psiMethod) {
+    if (psiMethod.isConstructor()) return false;
+    return psiMethod.getContainingClass().isInterface() || (!psiMethod.hasModifierProperty(PsiModifier.FINAL) && !psiMethod.hasModifierProperty(PsiModifier.STATIC));
+  }
+
+  public Set<String> getAdditionalVariants() {
+    return Collections.singleton(ALL_METHODS);
+  }
+
+  public PsiMethod fromString(final String methodName, final ConvertContext context) {
+    final CommonProcessors.FindFirstProcessor<PsiMethod> processor = new CommonProcessors.FindFirstProcessor<PsiMethod>();
+    processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+      public PsiMethod[] fun(final PsiClass s) {
+        final PsiMethod method = findMethod(s, methodName, getMethodParams(getParent(context)));
+        if (method != null && acceptMethod(method, context)) {
+          return new PsiMethod[]{method};
+        }
+        return PsiMethod.EMPTY_ARRAY;
+      }
+    });
+    if (processor.isFound()) return processor.getFoundValue();
+
+    processMethods(context, processor, new Function<PsiClass, PsiMethod[]>() {
+      public PsiMethod[] fun(final PsiClass s) {
+        return s.findMethodsByName(methodName, true);
+      }
+    });
+    return processor.getFoundValue();
+  }
+
+  public String toString(final PsiMethod method, final ConvertContext context) {
+    return method.getName();
+  }
+
+  public static String getReferenceCanonicalText(final String name, @Nullable final AbstractMethodParams methodParams) {
+    StringBuilder sb = new StringBuilder(name);
+    if (methodParams == null) {
+      sb.append("()");
+    }
+    else if (methodParams.getXmlTag() != null) {
+      sb.append("(");
+      final List<GenericDomValue<PsiType>> list = methodParams.getMethodParams();
+      boolean first = true;
+      for (GenericDomValue<PsiType> value : list) {
+        if (first) first = false;
+        else sb.append(", ");
+        sb.append(value.getStringValue());
+      }
+      sb.append(")");
+    }
+    return sb.toString();
+  }
+
+  @Nullable
+  public static PsiMethod findMethod(final PsiClass psiClass, final String methodName, @Nullable final AbstractMethodParams methodParameters) {
+    if (psiClass == null || methodName == null) return null;
+    return ContainerUtil.find(psiClass.findMethodsByName(methodName, true), new Condition<PsiMethod>() {
+      public boolean value(final PsiMethod object) {
+        return methodParamsMatchSignature(methodParameters, object);
+      }
+    });
+  }
+
+  public static boolean methodParamsMatchSignature(@Nullable final AbstractMethodParams params, final PsiMethod psiMethod) {
+    if (params != null && params.getXmlTag() == null) return true;
+
+    PsiParameter[] parameters = psiMethod.getParameterList().getParameters();
+    if (params == null) return parameters.length == 0;
+
+    List<GenericDomValue<PsiType>> methodParams = params.getMethodParams();
+    if (methodParams.size() != parameters.length) return false;
+    for (int i = 0; i < parameters.length; i++) {
+      if (!Comparing.equal(parameters[i].getType(), methodParams.get(i).getValue())) {
+        return false;
+      }
+    }
+    return true;
+  }
+
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java b/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java
new file mode 100644
index 0000000..123ff41
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/ClassArrayConverter.java
@@ -0,0 +1,26 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.xml.converters.values;
+
+import com.intellij.openapi.components.ServiceManager;
+
+public abstract class ClassArrayConverter extends ClassValueConverter {
+
+   public static ClassArrayConverter getClassArrayConverter() {
+    return ServiceManager.getService(ClassArrayConverter.class);
+  }
+}
\ No newline at end of file
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java b/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java
new file mode 100644
index 0000000..cb2820c
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/ClassValueConverter.java
@@ -0,0 +1,68 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package com.intellij.util.xml.converters.values;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiReference;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.util.xml.*;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+public abstract class ClassValueConverter extends Converter<PsiClass> implements CustomReferenceConverter {
+
+  public static ClassValueConverter getClassValueConverter() {
+    return ServiceManager.getService(ClassValueConverter.class);
+  }
+
+  public PsiClass fromString(@Nullable @NonNls String s, final ConvertContext context) {
+    if (s == null) return null;
+    final Module module = context.getModule();
+    final PsiFile psiFile = context.getFile();
+    final Project project = psiFile.getProject();
+    return DomJavaUtil.findClass(s, context.getFile(), context.getModule(), getScope(project, module, psiFile));
+  }
+
+  public String toString(@Nullable PsiClass psiClass, final ConvertContext context) {
+    return psiClass == null? null : psiClass.getQualifiedName();
+  }
+
+  @NotNull
+  public abstract PsiReference[] createReferences(GenericDomValue genericDomValue, PsiElement element, ConvertContext context);
+
+  public static GlobalSearchScope getScope(Project project, @Nullable Module module, @Nullable PsiFile psiFile) {
+    if (module == null || psiFile == null) {
+      return ProjectScope.getAllScope(project);
+     }
+     VirtualFile file = psiFile.getOriginalFile().getVirtualFile();
+     if (file == null) {
+       return ProjectScope.getAllScope(project);
+     }
+     final boolean inTests = ProjectRootManager.getInstance(project).getFileIndex().isInTestSourceContent(file);
+
+     return module.getModuleRuntimeScope(inTests);
+  }
+}
diff --git a/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java b/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java
new file mode 100644
index 0000000..34fb74d
--- /dev/null
+++ b/java/openapi/src/com/intellij/util/xml/converters/values/GenericDomValueConvertersRegistry.java
@@ -0,0 +1,134 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.util.xml.converters.values;
+
+import com.intellij.openapi.extensions.ExtensionPointName;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiType;
+import com.intellij.util.xml.Converter;
+import com.intellij.util.xml.GenericDomValue;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.math.BigDecimal;
+import java.math.BigInteger;
+import java.util.LinkedHashMap;
+import java.util.Map;
+
+/**
+ * User: Sergey.Vasiliev
+ */
+public class GenericDomValueConvertersRegistry {
+
+  public interface Provider {
+    Converter getConverter();
+    Condition<Pair<PsiType, GenericDomValue>> getCondition();
+  }
+
+  public void registerFromExtensions(ExtensionPointName<Provider> extensionPointName) {
+    Provider[] providers = Extensions.getExtensions(extensionPointName);
+    for (Provider provider : providers) {
+      registerConverter(provider.getConverter(), provider.getCondition());
+    }
+  }
+
+  private final Map<Condition<Pair<PsiType, GenericDomValue>>, Converter<?>> myConditionConverters =
+    new LinkedHashMap<Condition<Pair<PsiType, GenericDomValue>>, Converter<?>>();
+
+  public void registerDefaultConverters() {
+    registerBooleanConverters();
+    
+    registerCharacterConverter();
+
+    registerNumberValueConverters();
+
+    registerClassValueConverters();
+  }
+
+  private void registerBooleanConverters() {
+    registerConverter(new BooleanValueConverter(false), PsiType.BOOLEAN);
+    registerConverter(new BooleanValueConverter(true), Boolean.class);
+  }
+
+  public void registerClassValueConverters() {
+    registerConverter(ClassValueConverter.getClassValueConverter(), Class.class);
+    registerConverter(ClassArrayConverter.getClassArrayConverter(), Class[].class);
+  }
+
+  public void registerCharacterConverter() {
+    registerConverter(new CharacterValueConverter(false), PsiType.CHAR);
+    registerConverter(new CharacterValueConverter(true), Character.class);
+  }
+
+  public void registerNumberValueConverters() {
+    registerConverter(new NumberValueConverter(byte.class, false), PsiType.BYTE);
+    registerConverter(new NumberValueConverter(Byte.class, true), Byte.class);
+
+    registerConverter(new NumberValueConverter(short.class, false), PsiType.SHORT);
+    registerConverter(new NumberValueConverter(Short.class, true), Short.class);
+
+    registerConverter(new NumberValueConverter(int.class, false), PsiType.INT);
+    registerConverter(new NumberValueConverter(Integer.class, true), Integer.class);
+
+    registerConverter(new NumberValueConverter(long.class, false), PsiType.LONG);
+    registerConverter(new NumberValueConverter(Long.class, true), Long.class);
+
+    registerConverter(new NumberValueConverter(float.class, false), PsiType.FLOAT);
+    registerConverter(new NumberValueConverter(Float.class, true), Float.class);
+
+    registerConverter(new NumberValueConverter(double.class, false), PsiType.DOUBLE);
+    registerConverter(new NumberValueConverter(Double.class, true), Double.class);
+
+    registerConverter(new NumberValueConverter(BigDecimal.class, true), BigDecimal.class);
+    registerConverter(new NumberValueConverter(BigInteger.class, true), BigInteger.class);
+  }
+
+  public void registerConverter(@NotNull Converter<?> provider, @NotNull final PsiType type) {
+    registerConverter(provider, new Condition<Pair<PsiType, GenericDomValue>>() {
+      public boolean value(final Pair<PsiType, GenericDomValue> pair) {
+        return Comparing.equal(pair.getFirst(), type);
+      }
+    });
+  }
+
+  public void registerConverter(@NotNull Converter<?> provider, @NotNull Condition<Pair<PsiType, GenericDomValue>> condition) {
+    myConditionConverters.put(condition, provider);
+  }
+
+  @Nullable
+  public Converter<?> getConverter(@NotNull GenericDomValue domValue, @Nullable PsiType type) {
+    final Pair<PsiType, GenericDomValue> pair = new Pair<PsiType, GenericDomValue>(type, domValue);
+    for (@NotNull Condition<Pair<PsiType, GenericDomValue>> condition : myConditionConverters.keySet()) {
+      if (condition.value(pair)) {
+        return myConditionConverters.get(condition);
+      }
+    }
+    return null;
+  }
+
+  public void registerConverter(@NotNull Converter<?> provider, @NotNull Class type) {
+    final String name = type.getCanonicalName();
+    registerConverter(provider, new Condition<Pair<PsiType, GenericDomValue>>() {
+      public boolean value(final Pair<PsiType, GenericDomValue> pair) {
+        return pair.first != null && Comparing.equal(name, pair.first.getCanonicalText());
+      }
+    });
+  }
+
+}