diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
new file mode 100644
index 0000000..240e7e5
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestCase.java
@@ -0,0 +1,736 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.highlighting.HighlightUsagesHandler;
+import com.intellij.ide.DataManager;
+import com.intellij.injected.editor.EditorWindow;
+import com.intellij.openapi.actionSystem.*;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.command.undo.UndoManager;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.editor.actionSystem.EditorActionHandler;
+import com.intellij.openapi.editor.actionSystem.EditorActionManager;
+import com.intellij.openapi.editor.actionSystem.TypedAction;
+import com.intellij.openapi.editor.impl.DocumentImpl;
+import com.intellij.openapi.editor.impl.EditorImpl;
+import com.intellij.openapi.fileEditor.FileEditorManager;
+import com.intellij.openapi.fileEditor.OpenFileDescriptor;
+import com.intellij.openapi.fileEditor.TextEditor;
+import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeManager;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.testFramework.PsiTestData;
+import com.intellij.testFramework.PsiTestUtil;
+import com.intellij.testFramework.VfsTestUtil;
+import com.intellij.util.ArrayUtil;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.io.OutputStream;
+import java.util.ArrayList;
+import java.util.LinkedHashMap;
+import java.util.List;
+
+/**
+ * @author Mike
+ */
+public abstract class CodeInsightTestCase extends PsiTestCase {
+  protected Editor myEditor;
+
+  protected Editor createEditor(VirtualFile file) {
+    final FileEditorManager instance = FileEditorManager.getInstance(myProject);
+
+    if (file.getFileType().isBinary()) return null;
+
+    Editor editor = instance.openTextEditor(new OpenFileDescriptor(myProject, file, 0), false);
+    ((EditorImpl)editor).setCaretActive();
+    return editor;
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    FileEditorManager editorManager = FileEditorManager.getInstance(myProject);
+    VirtualFile[] openFiles = editorManager.getOpenFiles();
+    for (VirtualFile openFile : openFiles) {
+      editorManager.closeFile(openFile);
+    }
+    myEditor = null;
+    super.tearDown();
+  }
+
+  @Override
+  protected PsiTestData createData() {
+    return new CodeInsightTestData();
+  }
+
+  public static final String CARET_MARKER = "<caret>";
+  @NonNls public static final String SELECTION_START_MARKER = "<selection>";
+  @NonNls public static final String SELECTION_END_MARKER = "</selection>";
+
+  protected void configureByFile(@NonNls String filePath) throws Exception {
+    configureByFile(filePath, null);
+  }
+  protected VirtualFile configureByFiles(@Nullable String projectRoot,String... files) throws Exception {
+    final VirtualFile[] vFiles = new VirtualFile[files.length];
+    for (int i = 0; i < files.length; i++) {
+      String path = files[i];
+      final String fullPath = FileUtil.toSystemIndependentName(getTestDataPath() + path);
+      VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath);
+      vFiles[i] = vFile;
+      assertNotNull("file " + fullPath + " not found", vFile);
+    }
+
+    File projectFile = projectRoot == null ? null : new File(getTestDataPath() + projectRoot);
+
+    return configureByFiles(projectFile, vFiles);
+  }
+  protected VirtualFile configureByFile(@NonNls String filePath, String projectRoot) throws Exception {
+    String fullPath = getTestDataPath() + filePath;
+
+    final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+    assertNotNull("file " + fullPath + " not found", vFile);
+
+    File projectFile = projectRoot == null ? null : new File(getTestDataPath() + projectRoot);
+
+    return configureByFile(vFile, projectFile);
+  }
+
+  protected PsiFile configureByText(final FileType fileType, @NonNls final String text) throws Exception {
+    return configureByText(fileType, text, null);
+  }
+
+  protected PsiFile configureByText(final FileType fileType, @NonNls final String text, @Nullable String _extension) throws Exception {
+    final String extension = _extension == null ? fileType.getDefaultExtension():_extension;
+
+    File dir = createTempDirectory();
+    final File tempFile = FileUtil.createTempFile(dir, "aaa", "." + extension, true);
+    final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
+    if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
+      new WriteCommandAction(getProject()) {
+        @Override
+        protected void run(Result result) throws Exception {
+          fileTypeManager.associateExtension(fileType, extension);
+        }
+      }.execute();
+    }
+    final VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
+    assert vFile != null;
+    VfsUtil.saveText(vFile, text);
+
+    final VirtualFile vdir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(dir);
+
+    PsiTestUtil.addSourceRoot(myModule, vdir);
+
+    configureByExistingFile(vFile);
+
+    assertEquals(fileType, myFile.getVirtualFile().getFileType());
+    return myFile;
+  }
+
+
+  @Override
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath();
+  }
+
+  protected void configureByFile(final VirtualFile vFile) throws IOException {
+    configureByFile(vFile, null);
+  }
+
+  protected void configureByExistingFile(final VirtualFile virtualFile) {
+    myFile = null;
+    myEditor = null;
+
+    final Editor editor = createEditor(virtualFile);
+
+    final Document document = editor.getDocument();
+    final EditorInfo editorInfo = new EditorInfo(document.getText());
+
+    final String newFileText = editorInfo.getNewFileText();
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        if (!document.getText().equals(newFileText)) {
+          document.setText(newFileText);
+        }
+
+        PsiFile file = myPsiManager.findFile(virtualFile);
+        if (myFile == null) myFile = file;
+
+        if (myEditor == null) myEditor = editor;
+
+        editorInfo.applyToEditor(editor);
+      }
+    });
+
+
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+  }
+
+  protected VirtualFile configureByFiles(@Nullable final File rawProjectRoot, final VirtualFile... vFiles) throws IOException {
+    myFile = null;
+    myEditor = null;
+
+    final File toDirIO = createTempDirectory();
+    final VirtualFile toDir = getVirtualFile(toDirIO);
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          final ModuleRootManager rootManager = ModuleRootManager.getInstance(myModule);
+          final ModifiableRootModel rootModel = rootManager.getModifiableModel();
+          if (clearModelBeforeConfiguring()) {
+            rootModel.clear();
+          }
+
+          // auxiliary files should be copied first
+          VirtualFile[] reversed = ArrayUtil.reverseArray(vFiles);
+          final LinkedHashMap<VirtualFile, EditorInfo> editorInfos;
+          if (rawProjectRoot != null) {
+            final File projectRoot = rawProjectRoot.getCanonicalFile();
+            FileUtil.copyDir(projectRoot, toDirIO);
+            VirtualFile fromDir = getVirtualFile(projectRoot);
+            editorInfos =
+              copyFilesFillingEditorInfos(fromDir, toDir, ContainerUtil.map2Array(reversed, String.class, new Function<VirtualFile, String>() {
+                @Override
+                public String fun(final VirtualFile s) {
+                  return s.getPath().substring(projectRoot.getPath().length());
+                }
+              }));
+
+            toDir.refresh(false, true);
+          }
+          else {
+            editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
+            for (final VirtualFile vFile : reversed) {
+              VirtualFile parent = vFile.getParent();
+              assert parent.isDirectory() : parent;
+              editorInfos.putAll(copyFilesFillingEditorInfos(parent, toDir, vFile.getName()));
+            }
+          }
+
+          boolean sourceRootAdded = false;
+          if (isAddDirToContentRoot()) {
+            final ContentEntry contentEntry = rootModel.addContentEntry(toDir);
+            if (isAddDirToSource()) {
+              sourceRootAdded = true;
+              contentEntry.addSourceFolder(toDir, isAddDirToTests());
+            }
+          }
+          doCommitModel(rootModel);
+          if (sourceRootAdded) {
+            sourceRootAdded(toDir);
+          }
+
+          openEditorsAndActivateLast(editorInfos);
+        }
+        catch (IOException e) {
+          LOG.error(e);
+        }
+      }
+    });
+
+
+    return toDir;
+  }
+
+  protected boolean isAddDirToTests() {
+    return false;
+  }
+
+  protected void doCommitModel(final ModifiableRootModel rootModel) {
+    rootModel.commit();
+  }
+
+  protected void sourceRootAdded(final VirtualFile dir) {
+  }
+
+  protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(String testDataFromDir,
+                                                                               final VirtualFile toDir,
+                                                                               final String... relativePaths) throws IOException {
+    if (!testDataFromDir.startsWith("/")) testDataFromDir = "/" + testDataFromDir;
+    return copyFilesFillingEditorInfos(LocalFileSystem.getInstance().refreshAndFindFileByPath(getTestDataPath() + testDataFromDir), toDir, relativePaths);
+  }
+
+  protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir, final String... relativePaths) throws IOException {
+    LinkedHashMap<VirtualFile, EditorInfo> editorInfos = new LinkedHashMap<VirtualFile, EditorInfo>();
+
+    List<OutputStream> streamsToClose = new ArrayList<OutputStream>();
+
+    for (String relativePath : relativePaths) {
+      if (relativePath.startsWith("/")) {
+        relativePath = relativePath.substring(1);
+      }
+      final VirtualFile fromFile = fromDir.findFileByRelativePath(relativePath);
+      assertNotNull(fromDir.getPath() + "/" + relativePath, fromFile);
+      VirtualFile toFile = toDir.findFileByRelativePath(relativePath);
+      if (toFile == null) {
+        final File file = new File(toDir.getPath(), relativePath);
+        FileUtil.createIfDoesntExist(file);
+        toFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+        assertNotNull(file.getCanonicalPath(), toFile);
+      }
+      toFile.putUserData(VfsTestUtil.TEST_DATA_FILE_PATH, FileUtil.toSystemDependentName(fromFile.getPath()));
+      editorInfos.put(toFile, copyContent(fromFile, toFile, streamsToClose));
+    }
+
+    for(int i = streamsToClose.size() -1; i >= 0 ; --i) {
+      streamsToClose.get(i).close();
+    }
+    return editorInfos;
+  }
+
+  /*protected LinkedHashMap<VirtualFile, EditorInfo> copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir) throws IOException {
+    final LinkedHashMap<VirtualFile, EditorInfo> map = new LinkedHashMap<VirtualFile, EditorInfo>();
+    copyFilesFillingEditorInfos(fromDir, toDir, map);
+    return map;
+  }
+
+
+  private void copyFilesFillingEditorInfos(final VirtualFile fromDir, final VirtualFile toDir, LinkedHashMap<VirtualFile, EditorInfo> editorInfos) throws IOException {
+
+    List<OutputStream> streamsToClose = new ArrayList<OutputStream>();
+
+    final VirtualFile[] files = fromDir.getChildren();
+    for (final VirtualFile fromFile : files) {
+      if (fromFile.isDirectory()) {
+        copyFilesFillingEditorInfos(fromFile, toDir.createChildDirectory(this, fromFile.getName()), editorInfos);
+      } else {
+        final VirtualFile toFile = toDir.createChildData(this, fromFile.getName());
+        editorInfos.put(toFile, copyContent(fromFile, toFile, streamsToClose));
+      }
+    }
+
+    for(int i = streamsToClose.size() -1; i >= 0 ; --i) {
+      streamsToClose.get(i).close();
+    }
+  }*/
+
+  private EditorInfo copyContent(final VirtualFile from, final VirtualFile to, final List<OutputStream> streamsToClose) throws IOException {
+    byte[] content = from.getFileType().isBinary() ? from.contentsToByteArray(): null;
+    final String fileText = from.getFileType().isBinary() ? null : StringUtil.convertLineSeparators(VfsUtil.loadText(from));
+
+    EditorInfo editorInfo = fileText != null ? new EditorInfo(fileText) : null;
+    String newFileText = fileText != null ? editorInfo.getNewFileText() : null;
+    doWrite(newFileText, to, content, streamsToClose);
+    return editorInfo;
+  }
+
+  protected final void setActiveEditor(Editor editor) {
+    myEditor = editor;
+    myFile = getPsiFile(editor.getDocument());
+  }
+
+  protected List<Editor> openEditorsAndActivateLast(final LinkedHashMap<VirtualFile, EditorInfo> editorInfos) {
+    final List<Editor> list = openEditors(editorInfos);
+    setActiveEditor(list.get(list.size() - 1));
+    return list;
+  }
+
+  protected final List<Editor> openEditors(final LinkedHashMap<VirtualFile, EditorInfo> editorInfos) {
+    return ContainerUtil.map(editorInfos.keySet(), new Function<VirtualFile, Editor>() {
+      @Override
+      public Editor fun(final VirtualFile newVFile) {
+        PsiFile file = myPsiManager.findFile(newVFile);
+        if (myFile == null) myFile = file;
+
+        Editor editor = createEditor(newVFile);
+        if (myEditor == null) myEditor = editor;
+
+        EditorInfo editorInfo = editorInfos.get(newVFile);
+        if (editorInfo != null) {
+          editorInfo.applyToEditor(editor);
+        }
+        return editor;
+      }
+    });
+  }
+
+  private void doWrite(final String newFileText, final VirtualFile newVFile, final byte[] content, final List<OutputStream> streamsToClose) throws IOException {
+    if (newFileText != null) {
+      VfsUtil.saveText(newVFile, newFileText);
+    } else {
+      final OutputStream outputStream = newVFile.getOutputStream(this, -1, -1);
+      outputStream.write(content);
+      streamsToClose.add(outputStream);
+    }
+  }
+
+  protected boolean isAddDirToContentRoot() {
+    return true;
+  }
+
+  protected boolean isAddDirToSource() {
+    return true;
+  }
+
+  protected VirtualFile configureByFile(final VirtualFile vFile, final File projectRoot) throws IOException {
+    return configureByFiles(projectRoot, vFile);
+  }
+
+  protected boolean clearModelBeforeConfiguring() {
+    return false;
+  }
+
+  protected void setupCursorAndSelection(final Editor editor) {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        Document document = editor.getDocument();
+        final String text = document.getText();
+
+        int caretIndex = text.indexOf(CARET_MARKER);
+        int selStartIndex = text.indexOf(SELECTION_START_MARKER);
+        int selEndIndex = text.indexOf(SELECTION_END_MARKER);
+
+        final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+        final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+        final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+        if (caretMarker != null) {
+          document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+        }
+        if (selStartMarker != null) {
+          document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+        }
+        if (selEndMarker != null) {
+          document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+        }
+
+        final String newText = document.getText();
+
+        if (caretMarker != null) {
+          int caretLine = StringUtil.offsetToLineNumber(newText, caretMarker.getStartOffset());
+          int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newText, caretLine, 0);
+          LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
+          editor.getCaretModel().moveToLogicalPosition(pos);
+        }
+
+        if (selStartMarker != null) {
+          editor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset());
+        }
+
+        PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+      }
+    });
+  }
+
+  @Override
+  protected void configure(String path, String dataName) throws Exception {
+    super.configure(path, dataName);
+
+    myEditor = createEditor(myFile.getVirtualFile());
+
+    CodeInsightTestData data = (CodeInsightTestData) myTestDataBefore;
+
+    LogicalPosition pos = new LogicalPosition(data.getLineNumber() - 1, data.getColumnNumber() - 1);
+    myEditor.getCaretModel().moveToLogicalPosition(pos);
+
+    int selectionEnd;
+    int selectionStart = selectionEnd = myEditor.getCaretModel().getOffset();
+
+    if (data.getSelectionStartColumnNumber() >= 0) {
+      selectionStart = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionStartColumnNumber() - 1));
+      selectionEnd = myEditor.logicalPositionToOffset(new LogicalPosition(data.getSelectionEndLineNumber() - 1, data.getSelectionEndColumnNumber() - 1));
+    }
+
+    myEditor.getSelectionModel().setSelection(selectionStart, selectionEnd);
+  }
+
+  protected void checkResultByFile(@NonNls String filePath) throws Exception {
+    checkResultByFile(filePath, false);
+  }
+
+  protected void checkResultByFile(@NonNls final String filePath, final boolean stripTrailingSpaces) throws Exception {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        getProject().getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
+        if (stripTrailingSpaces) {
+          ((DocumentImpl)myEditor.getDocument()).stripTrailingSpaces();
+        }
+
+        PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+        String fullPath = getTestDataPath() + filePath;
+
+        final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+        assertNotNull("Cannot find file " + fullPath, vFile);
+        String ft = null;
+        try {
+          ft = VfsUtil.loadText(vFile);
+        }
+        catch (IOException e) {
+          throw new RuntimeException(e);
+        }
+
+        String fileText = StringUtil.convertLineSeparators(ft);
+        Document document = EditorFactory.getInstance().createDocument(fileText);
+
+        int caretIndex = fileText.indexOf(CARET_MARKER);
+        int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
+        int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
+
+        final RangeMarker caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+        final RangeMarker selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+        final RangeMarker selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+        if (caretMarker != null) {
+          document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+        }
+        if (selStartMarker != null) {
+          document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+        }
+        if (selEndMarker != null) {
+          document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+        }
+
+        String newFileText = document.getText();
+        String newFileText1 = newFileText;
+        if (stripTrailingSpaces) {
+          Document document1 = EditorFactory.getInstance().createDocument(newFileText);
+          ((DocumentImpl)document1).stripTrailingSpaces();
+          newFileText1 = document1.getText();
+        }
+
+        if (myEditor instanceof EditorWindow) {
+          myEditor = ((EditorWindow)myEditor).getDelegate();
+          myFile = PsiDocumentManager.getInstance(getProject()).getPsiFile(myEditor.getDocument());
+        }
+
+        String text = myFile.getText();
+        text = StringUtil.convertLineSeparators(text);
+
+        assertEquals("Text mismatch in file " + filePath, newFileText1, text);
+
+        if (caretMarker != null) {
+          int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset());
+          int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0);
+
+          assertEquals("caretLine", caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
+          assertEquals("caretColumn", caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
+        }
+
+        if (selStartMarker != null && selEndMarker != null) {
+          int selStartLine = StringUtil.offsetToLineNumber(newFileText, selStartMarker.getStartOffset());
+          int selStartCol = selStartMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, selStartLine, 0);
+
+          int selEndLine = StringUtil.offsetToLineNumber(newFileText, selEndMarker.getEndOffset());
+          int selEndCol = selEndMarker.getEndOffset() - StringUtil.lineColToOffset(newFileText, selEndLine, 0);
+
+          assertEquals("selectionStartLine", selStartLine + 1,
+                       StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
+
+          assertEquals("selectionStartCol", selStartCol + 1,
+                       myEditor.getSelectionModel().getSelectionStart() - StringUtil.lineColToOffset(newFileText, selStartLine, 0) + 1);
+
+          assertEquals("selectionEndLine", selEndLine + 1,
+                       StringUtil.offsetToLineNumber(newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
+
+          assertEquals("selectionEndCol", selEndCol + 1,
+                       myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(newFileText, selEndLine, 0) + 1);
+        }
+        else {
+          assertTrue("should has no selection, but was: ("+myEditor.getSelectionModel().getSelectionStart()+", "+myEditor.getSelectionModel().getSelectionEnd()+")",
+                     !myEditor.getSelectionModel().hasSelection());
+        }
+      }
+    });
+  }
+
+  @Override
+  protected void checkResult(String dataName) throws Exception {
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+    super.checkResult(dataName);
+
+    CodeInsightTestData data = (CodeInsightTestData) myTestDataAfter;
+
+    if (data.getColumnNumber() >= 0) {
+      assertEquals(dataName + ":caretColumn", data.getColumnNumber(), myEditor.getCaretModel().getLogicalPosition().column + 1);
+    }
+    if (data.getLineNumber() >= 0) {
+      assertEquals(dataName + ":caretLine", data.getLineNumber(), myEditor.getCaretModel().getLogicalPosition().line + 1);
+    }
+
+    int selectionStart = myEditor.getSelectionModel().getSelectionStart();
+    int selectionEnd = myEditor.getSelectionModel().getSelectionEnd();
+    LogicalPosition startPosition = myEditor.offsetToLogicalPosition(selectionStart);
+    LogicalPosition endPosition = myEditor.offsetToLogicalPosition(selectionEnd);
+
+    if (data.getSelectionStartColumnNumber() >= 0) {
+      assertEquals(dataName + ":selectionStartColumn", data.getSelectionStartColumnNumber(), startPosition.column + 1);
+    }
+    if (data.getSelectionStartLineNumber() >= 0) {
+      assertEquals(dataName + ":selectionStartLine", data.getSelectionStartLineNumber(), startPosition.line + 1);
+    }
+    if (data.getSelectionEndColumnNumber() >= 0) {
+      assertEquals(dataName + ":selectionEndColumn", data.getSelectionEndColumnNumber(), endPosition.column + 1);
+    }
+    if (data.getSelectionEndLineNumber() >= 0) {
+      assertEquals(dataName + ":selectionEndLine", data.getSelectionEndLineNumber(), endPosition.line + 1);
+    }
+  }
+
+  @Override
+  public Object getData(String dataId) {
+    return PlatformDataKeys.EDITOR.is(dataId) ? myEditor : super.getData(dataId);
+  }
+
+  protected VirtualFile getVirtualFile(@NonNls String filePath) {
+    String fullPath = getTestDataPath() + filePath;
+
+    final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+    assertNotNull("file " + fullPath + " not found", vFile);
+    return vFile;
+  }
+
+  protected String getTestRoot(){
+    return FileUtil.toSystemIndependentName(getTestDataPath());
+  }
+
+  public Editor getEditor() {
+    return myEditor;
+  }
+
+  protected void type(char c) {
+    type(c, getEditor());
+  }
+
+  protected static void type(char c, Editor editor) {
+    EditorActionManager actionManager = EditorActionManager.getInstance();
+    DataContext dataContext = DataManager.getInstance().getDataContext();
+    if (c == '\n') {
+      actionManager.getActionHandler(IdeActions.ACTION_EDITOR_ENTER).execute(editor, dataContext);
+      return;
+    }
+    TypedAction action = actionManager.getTypedAction();
+    action.actionPerformed(editor, c, dataContext);
+  }
+
+  protected void caretRight() {
+    EditorActionManager actionManager = EditorActionManager.getInstance();
+    EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_RIGHT);
+    action.execute(getEditor(), DataManager.getInstance().getDataContext());
+  }
+  protected void caretUp() {
+    EditorActionManager actionManager = EditorActionManager.getInstance();
+    EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_MOVE_CARET_UP);
+    action.execute(getEditor(), DataManager.getInstance().getDataContext());
+  }
+  protected void deleteLine() {
+    EditorActionManager actionManager = EditorActionManager.getInstance();
+    EditorActionHandler action = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_DELETE_LINE);
+    action.execute(getEditor(), DataManager.getInstance().getDataContext());
+  }
+
+  protected void type(@NonNls String s) {
+    for (char c : s.toCharArray()) {
+      type(c);
+    }
+  }
+
+  protected void undo() {
+    UndoManager undoManager = UndoManager.getInstance(myProject);
+    TextEditor textEditor = TextEditorProvider.getInstance().getTextEditor(getEditor());
+    undoManager.undo(textEditor);
+  }
+
+  protected void backspace() {
+    backspace(getEditor());
+  }
+  protected void backspace(final Editor editor) {
+    CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        EditorActionManager actionManager = EditorActionManager.getInstance();
+        EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_BACKSPACE);
+
+        actionHandler.execute(editor, DataManager.getInstance().getDataContext());
+      }
+    }, "backspace", editor.getDocument());
+  }
+
+  protected void ctrlShiftF7() {
+    HighlightUsagesHandler.invoke(getProject(), getEditor(), getFile());
+  }
+
+  public static void ctrlW() {
+    AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_SELECT_WORD_AT_CARET);
+    DataContext dataContext = DataManager.getInstance().getDataContext();
+    AnActionEvent event = new AnActionEvent(null, dataContext, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
+    event.setInjectedContext(true);
+    action.actionPerformed(event);
+  }
+
+  public static void ctrlD() {
+    AnAction action = ActionManager.getInstance().getAction(IdeActions.ACTION_EDITOR_DUPLICATE);
+    DataContext dataContext = DataManager.getInstance().getDataContext();
+    AnActionEvent event = new AnActionEvent(null, dataContext, "", action.getTemplatePresentation(), ActionManager.getInstance(), 0);
+    event.setInjectedContext(true);
+    action.actionPerformed(event);
+  }
+
+  @NotNull
+  protected PsiClass findClass(@NotNull @NonNls final String name) {
+    final PsiClass aClass = myJavaFacade.findClass(name, ProjectScope.getProjectScope(getProject()));
+    assertNotNull("Class " + name + " not found", aClass);
+    return aClass;
+  }
+
+  @NotNull
+  protected PsiPackage findPackage(@NotNull @NonNls final String name) {
+    final PsiPackage aPackage = myJavaFacade.findPackage(name);
+    assertNotNull("Package " + name + " not found", aPackage);
+    return aPackage;
+  }
+
+  protected void delete(@NotNull final Editor editor) {
+    CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        EditorActionManager actionManager = EditorActionManager.getInstance();
+        EditorActionHandler actionHandler = actionManager.getActionHandler(IdeActions.ACTION_EDITOR_DELETE);
+
+        actionHandler.execute(editor, DataManager.getInstance().getDataContext());
+      }
+    }, "delete", editor.getDocument());
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.java b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.java
new file mode 100644
index 0000000..202db1b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/CodeInsightTestData.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.codeInsight;
+
+import com.intellij.testFramework.PsiTestData;
+
+/**
+ * @author Mike
+ */
+public class CodeInsightTestData extends PsiTestData{
+  public int LINE_NUMBER = -1;
+  public int COLUMN_NUMBER = -1;
+  public int SELECTION_START_LINE_NUMBER = -1;
+  public int SELECTION_START_COLUMN_NUMBER = -1;
+  public int SELECTION_END_LINE_NUMBER = -1;
+  public int SELECTION_END_COLUMN_NUMBER = -1;
+
+  public CodeInsightTestData() {
+  }
+
+  public int getLineNumber() {
+    return LINE_NUMBER;
+  }
+
+  public int getColumnNumber() {
+    return COLUMN_NUMBER;
+  }
+
+  public int getSelectionStartLineNumber() {
+    return SELECTION_START_LINE_NUMBER;
+  }
+
+  public int getSelectionStartColumnNumber() {
+    return SELECTION_START_COLUMN_NUMBER;
+  }
+
+  public int getSelectionEndLineNumber() {
+    return SELECTION_END_LINE_NUMBER;
+  }
+
+  public int getSelectionEndColumnNumber() {
+    return SELECTION_END_COLUMN_NUMBER;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java b/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java
new file mode 100644
index 0000000..d770d7e
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/EditorInfo.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS 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.application.ApplicationManager;
+import com.intellij.openapi.editor.*;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author cdr
+ */
+public class EditorInfo {
+  @NonNls public static final String CARET_MARKER = "<caret>";
+  @NonNls public static final String SELECTION_START_MARKER = "<selection>";
+  @NonNls public static final String SELECTION_END_MARKER = "</selection>";
+
+  String newFileText = null;
+  public RangeMarker caretMarker = null;
+  RangeMarker selStartMarker = null;
+  RangeMarker selEndMarker = null;
+
+  public EditorInfo(final String fileText) {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        updateCaretAndSelection(EditorFactory.getInstance().createDocument(fileText));
+      }
+    });
+  }
+
+  private boolean updateCaretAndSelection(final Document document) {
+    newFileText = document.getText();
+
+    int caretIndex = newFileText.indexOf(CARET_MARKER);
+    int selStartIndex = newFileText.indexOf(SELECTION_START_MARKER);
+    int selEndIndex = newFileText.indexOf(SELECTION_END_MARKER);
+
+    caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
+    selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
+    selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
+
+    if (caretMarker != null) {
+      document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
+    }
+    if (selStartMarker != null) {
+      document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
+    }
+    if (selEndMarker != null) {
+      document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
+    }
+
+    newFileText = document.getText();
+    return caretMarker != null || selStartMarker != null || selEndMarker != null;
+  }
+
+  public String getNewFileText() {
+    return newFileText;
+  }
+
+  public void applyToEditor(Editor editor) {
+    if (caretMarker != null) {
+      int caretLine = StringUtil.offsetToLineNumber(newFileText, caretMarker.getStartOffset());
+      int caretCol = caretMarker.getStartOffset() - StringUtil.lineColToOffset(newFileText, caretLine, 0);
+      LogicalPosition pos = new LogicalPosition(caretLine, caretCol);
+      editor.getCaretModel().moveToLogicalPosition(pos);
+    }
+
+    if (selStartMarker != null) {
+      editor.getSelectionModel().setSelection(selStartMarker.getStartOffset(), selEndMarker.getStartOffset());
+    }
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
new file mode 100644
index 0000000..9a05e8d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionAutoPopupTestCase.groovy
@@ -0,0 +1,49 @@
+/*
+ * Copyright 2000-2010 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion
+
+import com.intellij.codeInsight.lookup.LookupManager
+import com.intellij.codeInsight.lookup.impl.LookupImpl
+import com.intellij.testFramework.fixtures.CompletionAutoPopupTester
+import com.intellij.testFramework.fixtures.LightCodeInsightFixtureTestCase
+/**
+ * @author peter
+ */
+abstract class CompletionAutoPopupTestCase extends LightCodeInsightFixtureTestCase {
+  protected CompletionAutoPopupTester myTester
+
+  @Override protected void setUp() {
+    super.setUp()
+    myTester = new CompletionAutoPopupTester(myFixture)
+  }
+
+  void type(String s) {
+    myTester.typeWithPauses(s)
+  }
+
+  @Override protected boolean runInDispatchThread() {
+    return false;
+  }
+
+  @Override protected void invokeTestRunnable(Runnable runnable) {
+    myTester.runWithAutoPopupEnabled(runnable)
+  }
+
+  LookupImpl getLookup() {
+    (LookupImpl)LookupManager.getActiveLookup(myFixture.getEditor())
+  }
+
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java
new file mode 100644
index 0000000..714408d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/CompletionTestCase.java
@@ -0,0 +1,123 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion;
+
+import com.intellij.codeInsight.daemon.DaemonAnalyzerTestCase;
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupManager;
+import com.intellij.codeInsight.lookup.impl.LookupImpl;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.util.Function;
+import com.intellij.util.containers.ContainerUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Arrays;
+import java.util.List;
+
+/**
+ * @author mike
+ */
+@PlatformTestCase.WrapInCommand
+public abstract class CompletionTestCase extends DaemonAnalyzerTestCase {
+  protected String myPrefix;
+  protected LookupElement[] myItems;
+  private CompletionType myType = CompletionType.BASIC;
+
+  @Override
+  protected void tearDown() throws Exception {
+    try {
+      LookupManager.getInstance(myProject).hideActiveLookup();
+    }
+    finally {
+      super.tearDown();
+    }
+    myItems = null;
+  }
+
+  @Override
+  protected void configureByFile(String filePath) throws Exception {
+    super.configureByFile(filePath);
+
+    complete();
+  }
+
+  protected void configureByFileNoCompletion(String filePath) throws Exception {
+    super.configureByFile(filePath);
+  }
+
+  protected void complete() {
+    complete(1);
+  }
+
+  protected void complete(final int time) {
+    new CodeCompletionHandlerBase(myType).invokeCompletion(myProject, myEditor, time);
+
+    LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
+    myItems = lookup == null ? null : lookup.getItems().toArray(new LookupElement[lookup.getItems().size()]);
+    myPrefix = lookup == null ? "" : lookup.itemPattern(lookup.getItems().get(0));
+  }
+
+  public void setType(CompletionType type) {
+    myType = type;
+  }
+
+  protected void selectItem(LookupElement item, char ch) {
+    final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(myProject).getActiveLookup();
+    assert lookup != null;
+    lookup.setCurrentItem(item);
+    lookup.finishLookup(ch);
+  }
+
+  protected void selectItem(LookupElement item) {
+    selectItem(item, (char)0);
+  }
+
+  protected void doTestByCount(int finalCount, String... values) {
+    int index = 0;
+    if (myItems == null) {
+      assertEquals(0, finalCount);
+      return;
+    }
+    for (final LookupElement myItem : myItems) {
+      for (String value : values) {
+        if (value == null) {
+          assertFalse("Unacceptable value reached", true);
+        }
+        if (value.equals(myItem.getLookupString())) {
+          index++;
+          break;
+        }
+      }
+    }
+    assertEquals(Arrays.toString(myItems), finalCount, index);
+  }
+
+  @Nullable
+  protected LookupImpl getActiveLookup() {
+    return (LookupImpl)LookupManager.getActiveLookup(myEditor);
+  }
+
+  protected void assertStringItems(String... strings) {
+    assertNotNull(myItems);
+    List<String> actual = ContainerUtil.map(myItems, new Function<LookupElement, String>() {
+      @Override
+      public String fun(LookupElement element) {
+        return element.getLookupString();
+      }
+    });
+    assertOrderedEquals(actual, strings);
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java
new file mode 100644
index 0000000..5f435b0
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/completion/LightCompletionTestCase.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.completion;
+
+import com.intellij.codeInsight.lookup.LookupElement;
+import com.intellij.codeInsight.lookup.LookupManager;
+import com.intellij.codeInsight.lookup.impl.LookupImpl;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import com.intellij.util.containers.HashSet;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Set;
+
+/**
+ * @author mike
+ */
+public abstract class LightCompletionTestCase extends LightCodeInsightTestCase {
+  protected String myPrefix;
+  protected LookupElement[] myItems;
+  private CompletionType myType = CompletionType.BASIC;
+
+  @Override
+  protected void tearDown() throws Exception {
+    LookupManager.getInstance(getProject()).hideActiveLookup();
+    super.tearDown();
+  }
+
+  @Override
+  protected void configureByFile(@NotNull String filePath) {
+    super.configureByFile(filePath);
+
+    complete();
+  }
+
+  protected void configureByFileNoComplete(String filePath) throws Exception {
+    super.configureByFile(filePath);
+  }
+
+  protected void complete() {
+    complete(1);
+  }
+
+  protected void complete(final int time) {
+    new CodeCompletionHandlerBase(myType).invokeCompletion(getProject(), getEditor(), time);
+
+    LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
+    myItems = lookup == null ? null : lookup.getItems().toArray(LookupElement.EMPTY_ARRAY);
+    myPrefix = lookup == null ? null : lookup.itemPattern(lookup.getItems().get(0));
+  }
+
+  public void setType(CompletionType type) {
+    myType = type;
+  }
+
+  protected void selectItem(LookupElement item) {
+    selectItem(item, (char)0);
+  }
+  
+  protected void selectItem(LookupElement item, char completionChar) {
+    final LookupImpl lookup = (LookupImpl)LookupManager.getInstance(getProject()).getActiveLookup();
+    lookup.setCurrentItem(item);
+    if (completionChar == 0 || completionChar == '\n' || completionChar == '\t') {
+      lookup.finishLookup(completionChar);
+    } else {
+      type(completionChar);
+    }
+  }
+
+  protected void testByCount(int finalCount, @NonNls String... values) {
+    if (myItems == null) {
+      assertEquals(finalCount, 0);
+      return;
+    }
+    int index = 0;
+    for (final LookupElement myItem : myItems) {
+      for (String value : values) {
+        if (value == null) {
+          assertFalse("Unacceptable value reached: " + myItem.getLookupString(), true);
+        }
+        if (value.equals(myItem.getLookupString())) {
+          index++;
+          break;
+        }
+      }
+    }
+    assertEquals(finalCount, index);
+  }
+
+  protected void assertStringItems(@NonNls String... items) {
+    assertOrderedEquals(getLookupStrings(new ArrayList<String>()), items);
+  }
+
+  protected void assertContainsItems(final String... expected) {
+    final Set<String> actual = getLookupStrings(new HashSet<String>());
+    for (String s : expected) {
+      assertTrue("Expected '" + s + "' not found in " + actual,
+                 actual.contains(s));
+    }
+  }
+
+  protected void assertNotContainItems(final String... unexpected) {
+    final Set<String> actual = getLookupStrings(new HashSet<String>());
+    for (String s : unexpected) {
+      assertFalse("Unexpected '" + s + "' presented in " + actual,
+                  actual.contains(s));
+    }
+  }
+
+  private <T extends Collection<String>> T getLookupStrings(T actual) {
+    if (myItems != null) {
+      for (LookupElement lookupElement : myItems) {
+        actual.add(lookupElement.getLookupString());
+      }
+    }
+    return actual;
+  }
+
+  protected static LookupImpl getLookup() {
+    return (LookupImpl)LookupManager.getActiveLookup(myEditor);
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
new file mode 100644
index 0000000..ae80acc
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/DaemonAnalyzerTestCase.java
@@ -0,0 +1,481 @@
+/*
+ * 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.codeHighlighting.HighlightDisplayLevel;
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
+import com.intellij.codeInspection.InspectionProfileEntry;
+import com.intellij.codeInspection.InspectionToolProvider;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.ModifiableModel;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.ide.startup.StartupManagerEx;
+import com.intellij.ide.startup.impl.StartupManagerImpl;
+import com.intellij.lang.ExternalAnnotatorsFilter;
+import com.intellij.lang.LanguageAnnotators;
+import com.intellij.lang.StdLanguages;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.lang.injection.InjectedLanguageManager;
+import com.intellij.lang.java.JavaLanguage;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Document;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.DumbService;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.*;
+import com.intellij.profile.codeInspection.InspectionProfileManager;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import com.intellij.psi.impl.cache.CacheManager;
+import com.intellij.psi.impl.search.IndexPatternBuilder;
+import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
+import com.intellij.psi.impl.source.tree.TreeElement;
+import com.intellij.psi.impl.source.tree.TreeUtil;
+import com.intellij.psi.search.GlobalSearchScope;
+import com.intellij.psi.search.UsageSearchContext;
+import com.intellij.psi.xml.XmlFileNSInfoProvider;
+import com.intellij.testFramework.ExpectedHighlightingData;
+import com.intellij.testFramework.FileTreeAccessFilter;
+import com.intellij.testFramework.HighlightTestInfo;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.xml.XmlSchemaProvider;
+import gnu.trove.THashMap;
+import gnu.trove.TIntArrayList;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.IOException;
+import java.lang.annotation.ElementType;
+import java.lang.annotation.Retention;
+import java.lang.annotation.RetentionPolicy;
+import java.lang.annotation.Target;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.Map;
+
+public abstract class DaemonAnalyzerTestCase extends CodeInsightTestCase {
+  private final Map<String, InspectionToolWrapper> myAvailableTools = new THashMap<String, InspectionToolWrapper>();
+  private final FileTreeAccessFilter myFileTreeAccessFilter = new FileTreeAccessFilter();
+
+  @Override
+  protected boolean isRunInWriteAction() {
+    return false;
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    final LocalInspectionTool[] tools = configureLocalInspectionTools();
+    for (LocalInspectionTool tool : tools) {
+      enableInspectionTool(tool);
+    }
+
+    final InspectionProfileImpl profile = new InspectionProfileImpl(LightPlatformTestCase.PROFILE) {
+      @Override
+      @NotNull
+      public ModifiableModel getModifiableModel() {
+        mySource = this;
+        return this;
+      }
+
+      @Override
+      @NotNull
+      public InspectionTool[] getInspectionTools(PsiElement element) {
+        Collection<InspectionToolWrapper> values = myAvailableTools.values();
+        return values.toArray(new InspectionTool[values.size()]);
+      }
+
+      @Override
+      public List<ToolsImpl> getAllEnabledInspectionTools(Project project) {
+        List<ToolsImpl> result = new ArrayList<ToolsImpl>();
+        for (InspectionProfileEntry entry : getInspectionTools(null)) {
+          result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
+        }
+        return result;
+      }
+
+      @Override
+      public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
+        return key != null && myAvailableTools.containsKey(key.toString());
+      }
+
+      @Override
+      public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
+        final InspectionProfileEntry localInspectionTool = myAvailableTools.get(key.toString());
+        return localInspectionTool != null ? localInspectionTool.getDefaultLevel() : HighlightDisplayLevel.WARNING;
+      }
+
+      @Override
+      public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
+        return myAvailableTools.get(shortName);
+      }
+    };
+    final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
+    inspectionProfileManager.addProfile(profile);
+    inspectionProfileManager.setRootProfile(LightPlatformTestCase.PROFILE);
+    Disposer.register(getProject(), new Disposable() {
+      @Override
+      public void dispose() {
+        inspectionProfileManager.deleteProfile(LightPlatformTestCase.PROFILE);
+      }
+    });
+    InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
+    InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
+    DaemonCodeAnalyzerImpl daemonCodeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject());
+    daemonCodeAnalyzer.prepareForTest();
+    final StartupManagerImpl startupManager = (StartupManagerImpl)StartupManagerEx.getInstanceEx(getProject());
+    startupManager.runStartupActivities();
+    startupManager.startCacheUpdate();
+    startupManager.runPostStartupActivities();
+    DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
+
+    if (isPerformanceTest()) {
+      IntentionManager.getInstance().getAvailableIntentionActions();  // hack to avoid slowdowns in PyExtensionFactory
+      PathManagerEx.getTestDataPath(); // to cache stuff
+      ReferenceProvidersRegistry.getInstance(); // pre-load tons of classes
+      InjectedLanguageManager.getInstance(getProject()); // zillion of Dom Sem classes
+      LanguageAnnotators.INSTANCE.allForLanguage(JavaLanguage.INSTANCE); // pile of annotator classes loads
+      LanguageAnnotators.INSTANCE.allForLanguage(StdLanguages.XML);
+      ProblemHighlightFilter.EP_NAME.getExtensions();
+      Extensions.getExtensions(ImplicitUsageProvider.EP_NAME);
+      Extensions.getExtensions(XmlSchemaProvider.EP_NAME);
+      Extensions.getExtensions(XmlFileNSInfoProvider.EP_NAME);
+      Extensions.getExtensions(ExternalAnnotatorsFilter.EXTENSION_POINT_NAME);
+      Extensions.getExtensions(IndexPatternBuilder.EP_NAME);
+    }
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    ((StartupManagerImpl)StartupManager.getInstance(getProject())).checkCleared();
+    ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!LightPlatformTestCase.isLight(getProject()));
+    super.tearDown();
+    //((VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance()).assertPointersDisposed();
+  }
+
+  protected void enableInspectionTool(InspectionProfileEntry tool){
+    InspectionToolWrapper wrapper = InspectionToolRegistrar.wrapTool(tool);
+    final String shortName = wrapper.getShortName();
+    final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
+    if (key == null) {
+      HighlightDisplayKey.register(shortName, wrapper.getDisplayName(), ((LocalInspectionToolWrapper)wrapper).getID());
+    }
+    myAvailableTools.put(shortName, wrapper);
+  }
+
+  protected void enableInspectionToolsFromProvider(InspectionToolProvider toolProvider){
+    try {
+      for(Class c:toolProvider.getInspectionClasses()) {
+        enableInspectionTool((LocalInspectionTool)c.newInstance());
+      }
+    }
+    catch (Exception e) {
+      throw new RuntimeException(e);
+    }
+  }
+
+  protected void disableInspectionTool(String shortName){
+    myAvailableTools.remove(shortName);
+  }
+
+  protected LocalInspectionTool[] configureLocalInspectionTools() {
+    return LocalInspectionTool.EMPTY_ARRAY;
+  }
+
+  protected static LocalInspectionTool[] createLocalInspectionTools(final InspectionToolProvider... provider) {
+    final ArrayList<LocalInspectionTool> result = new ArrayList<LocalInspectionTool>();
+    for (InspectionToolProvider toolProvider : provider) {
+      for (Class aClass : toolProvider.getInspectionClasses()) {
+        try {
+          final Object tool = aClass.newInstance();
+          assertTrue(tool instanceof LocalInspectionTool);
+          result.add((LocalInspectionTool)tool);
+        }
+        catch (Exception e) {
+          LOG.error(e);
+        }
+      }
+    }
+    return result.toArray(new LocalInspectionTool[result.size()]);
+  }
+
+  protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) throws Exception {
+    configureByFile(filePath);
+    doDoTest(checkWarnings, checkInfos, checkWeakWarnings);
+  }
+
+  protected void doTest(@NonNls @NotNull String filePath, boolean checkWarnings, boolean checkInfos) throws Exception {
+    doTest(filePath, checkWarnings, checkInfos, false);
+  }
+
+  protected void doTest(@NonNls @NotNull String filePath, @NonNls String projectRoot, boolean checkWarnings, boolean checkInfos) throws Exception {
+    configureByFile(filePath, projectRoot);
+    doDoTest(checkWarnings, checkInfos);
+  }
+
+  @NotNull
+  @SuppressWarnings("TestMethodWithIncorrectSignature")
+  protected HighlightTestInfo testFile(@NonNls @NotNull String... filePath) {
+    return new HighlightTestInfo(getTestRootDisposable(), filePath){
+      @Override
+      public HighlightTestInfo doTest() throws Exception {
+        configureByFiles(projectRoot, filePaths);
+        ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
+        if (checkSymbolNames) data.checkSymbolNames();
+        checkHighlighting(data);
+        return this;
+      }
+    };
+  }
+
+  protected void doTest(@NotNull VirtualFile vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
+    doTest(new VirtualFile[] { vFile }, checkWarnings, checkInfos );
+  }
+
+  protected void doTest(@NotNull VirtualFile[] vFile, boolean checkWarnings, boolean checkInfos) throws Exception {
+    configureByFiles(null, vFile);
+    doDoTest(checkWarnings, checkInfos);
+  }
+
+  protected void doTest(boolean checkWarnings, boolean checkInfos, String ... files) throws Exception {
+    configureByFiles(null, files);
+    doDoTest(checkWarnings, checkInfos);
+  }
+
+  @NotNull
+  protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos) {
+    return doDoTest(checkWarnings, checkInfos, false);
+  }
+
+  protected Collection<HighlightInfo> doDoTest(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings) {
+    return checkHighlighting(new ExpectedHighlightingData(myEditor.getDocument(),checkWarnings, checkWeakWarnings, checkInfos, myFile));
+  }
+
+  @NotNull
+  protected Collection<HighlightInfo> checkHighlighting(@NotNull final ExpectedHighlightingData data) {
+    data.init();
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    //to load text
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        TreeUtil.clearCaches((TreeElement)myFile.getNode());
+      }
+    });
+
+
+    //to initialize caches
+    if (!DumbService.isDumb(getProject())) {
+      CacheManager.SERVICE.getInstance(myProject).getFilesWithWord("XXX", UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(myProject), true);
+    }
+    final JavaPsiFacadeEx facade = getJavaFacade();
+    if (facade != null) {
+      facade.setAssertOnFileLoadingFilter(myFileTreeAccessFilter); // check repository work
+    }
+
+    Collection<HighlightInfo> infos = doHighlighting();
+
+    if (facade != null) {
+      facade.setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+    }
+
+    String text = myEditor.getDocument().getText();
+    data.checkLineMarkers(DaemonCodeAnalyzerImpl.getLineMarkers(getDocument(getFile()), getProject()), text);
+    data.checkResult(infos, text);
+    return infos;
+  }
+
+  public void allowTreeAccessForFile(@NotNull VirtualFile file) {
+    myFileTreeAccessFilter.allowTreeAccessForFile(file);
+  }
+
+  @NotNull
+  protected List<HighlightInfo> highlightErrors() {
+    return doHighlighting(HighlightSeverity.ERROR);
+  }
+
+  @NotNull
+  protected List<HighlightInfo> doHighlighting(@NotNull HighlightSeverity minSeverity) {
+    return filter(doHighlighting(), minSeverity);
+  }
+
+  @NotNull
+  protected List<HighlightInfo> doHighlighting() {
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    TIntArrayList toIgnore = new TIntArrayList();
+    if (!doTestLineMarkers()) {
+      toIgnore.add(Pass.UPDATE_OVERRIDEN_MARKERS);
+      toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
+      toIgnore.add(Pass.LINE_MARKERS);
+    }
+
+    if (!doExternalValidation()) {
+      toIgnore.add(Pass.EXTERNAL_TOOLS);
+    }
+    if (forceExternalValidation()) {
+      toIgnore.add(Pass.LINE_MARKERS);
+      toIgnore.add(Pass.LOCAL_INSPECTIONS);
+      toIgnore.add(Pass.POPUP_HINTS);
+      toIgnore.add(Pass.POST_UPDATE_ALL);
+      toIgnore.add(Pass.UPDATE_ALL);
+      toIgnore.add(Pass.UPDATE_OVERRIDEN_MARKERS);
+      toIgnore.add(Pass.VISIBLE_LINE_MARKERS);
+    }
+
+    boolean canChange = canChangeDocumentDuringHighlighting();
+    List<HighlightInfo> infos = CodeInsightTestFixtureImpl.instantiateAndRun(getFile(), getEditor(), toIgnore.toNativeArray(), canChange);
+
+    if (!canChange) {
+      Document document = getDocument(getFile());
+      ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).getFileStatusMap().assertAllDirtyScopesAreNull(document);
+    }
+
+    return infos;
+  }
+
+  @Retention(RetentionPolicy.RUNTIME)
+  @Target({ElementType.METHOD, ElementType.TYPE})
+  public @interface CanChangeDocumentDuringHighlighting {}
+
+  private boolean canChangeDocumentDuringHighlighting() {
+    return annotatedWith(CanChangeDocumentDuringHighlighting.class);
+  }
+
+  @NotNull
+  public static List<HighlightInfo> filter(@NotNull List<HighlightInfo> infos, @NotNull HighlightSeverity minSeverity) {
+    ArrayList<HighlightInfo> result = new ArrayList<HighlightInfo>();
+    for (final HighlightInfo info : infos) {
+      if (info.getSeverity().compareTo(minSeverity) >= 0) result.add(info);
+    }
+    return result;
+  }
+
+  protected boolean doTestLineMarkers() {
+    return false;
+  }
+
+  protected boolean doExternalValidation() {
+    return true;
+  }
+
+  protected boolean forceExternalValidation() {
+    return false;
+  }
+
+  protected static void findAndInvokeIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
+                                                     @NotNull PsiFile file) throws IncorrectOperationException {
+    IntentionAction intentionAction = findIntentionAction(infos, intentionActionName, editor, file);
+
+    assertNotNull(intentionActionName, intentionAction);
+    assertTrue(ShowIntentionActionsHandler.chooseActionAndInvoke(file, editor, intentionAction, intentionActionName));
+  }
+
+  protected static IntentionAction findIntentionAction(@NotNull Collection<HighlightInfo> infos, @NotNull String intentionActionName, @NotNull Editor editor,
+                                                       @NotNull PsiFile file) {
+    List<IntentionAction> actions = LightQuickFixTestCase.getAvailableActions(editor, file);
+    IntentionAction intentionAction = LightQuickFixTestCase.findActionWithText(actions, intentionActionName);
+
+    if (intentionAction == null) {
+      final List<IntentionAction> availableActions = new ArrayList<IntentionAction>();
+
+      for (HighlightInfo info :infos) {
+        if (info.quickFixActionRanges != null) {
+          for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
+            IntentionAction action = pair.first.getAction();
+            if (action.isAvailable(file.getProject(), editor, file)) availableActions.add(action);
+          }
+        }
+      }
+
+      intentionAction = LightQuickFixTestCase.findActionWithText(
+        availableActions,
+        intentionActionName
+      );
+    }
+    return intentionAction;
+  }
+
+  public void checkHighlighting(Editor editor, boolean checkWarnings, boolean checkInfos) {
+    setActiveEditor(editor);
+    doDoTest(checkWarnings, checkInfos);
+  }
+
+  public PsiClass createClass(String text) throws IOException {
+    return createClass(myModule, text);
+  }
+
+  protected PsiClass createClass(final Module module, final String text) throws IOException {
+    return new WriteCommandAction<PsiClass>(getProject()) {
+      @Override
+      protected void run(Result<PsiClass> result) throws Throwable {
+        final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
+        final PsiJavaFile javaFile = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, text);
+        final String qname = javaFile.getClasses()[0].getQualifiedName();
+        assertNotNull(qname);
+        final VirtualFile[] files = ModuleRootManager.getInstance(module).getSourceRoots();
+        File dir;
+        if (files.length > 0) {
+          dir = VfsUtilCore.virtualToIoFile(files[0]);
+        }
+        else {
+          dir = createTempDirectory();
+          VirtualFile vDir =
+            LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+          addSourceContentToRoots(module, vDir);
+        }
+
+        File file = new File(dir, qname.replace('.', '/') + ".java");
+        FileUtil.createIfDoesntExist(file);
+        VirtualFile vFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(file.getCanonicalPath().replace(File.separatorChar, '/'));
+        assertNotNull(vFile);
+        VfsUtil.saveText(vFile, text);
+        PsiJavaFile psiFile = (PsiJavaFile)myPsiManager.findFile(vFile);
+        assertNotNull(psiFile);
+        PsiClass psiClass = psiFile.getClasses()[0];
+        result.setResult(psiClass);
+
+      }
+    }.execute().throwException().getResultObject();
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
new file mode 100644
index 0000000..2cc216d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightDaemonAnalyzerTestCase.java
@@ -0,0 +1,160 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.codeInsight.daemon;
+
+import com.intellij.codeHighlighting.Pass;
+import com.intellij.codeInsight.daemon.impl.DaemonCodeAnalyzerImpl;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.injected.editor.EditorWindow;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.vfs.VirtualFileFilter;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.testFramework.ExpectedHighlightingData;
+import com.intellij.testFramework.FileTreeAccessFilter;
+import com.intellij.testFramework.HighlightTestInfo;
+import com.intellij.testFramework.LightCodeInsightTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+import java.util.List;
+
+public abstract class LightDaemonAnalyzerTestCase extends LightCodeInsightTestCase {
+  private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).prepareForTest();
+    DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    ((DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(getProject())).cleanupAfterTest(!isLight(getProject()));
+    super.tearDown();
+  }
+
+  @Override
+  protected void runTest() throws Throwable {
+    final Throwable[] throwable = {null};
+    CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        try {
+          doRunTest();
+        }
+        catch (Throwable t) {
+          throwable[0] = t;
+        }
+      }
+    }, "", null);
+    if (throwable[0] != null) {
+      throw throwable[0];
+    }
+  }
+
+  protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkInfos) {
+    configureByFile(filePath);
+    doTestConfiguredFile(checkWarnings, checkInfos, filePath);
+  }
+
+  protected void doTest(@NonNls String filePath, boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos) {
+    configureByFile(filePath);
+    doTestConfiguredFile(checkWarnings, checkWeakWarnings, checkInfos, filePath);
+  }
+
+  protected void doTestConfiguredFile(boolean checkWarnings, boolean checkInfos, @Nullable String filePath) {
+    doTestConfiguredFile(checkWarnings, false, checkInfos, filePath);
+  }
+
+  protected void doTestConfiguredFile(boolean checkWarnings, boolean checkWeakWarnings, boolean checkInfos, @Nullable String filePath) {
+    getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+
+    ExpectedHighlightingData data = new ExpectedHighlightingData(getEditor().getDocument(), checkWarnings, checkWeakWarnings, checkInfos);
+    checkHighlighting(data, composeLocalPath(filePath));
+  }
+
+  @Nullable
+  private String composeLocalPath(@Nullable String filePath) {
+    return filePath != null ? getTestDataPath() + "/" + filePath : null;
+  }
+
+  private void checkHighlighting(ExpectedHighlightingData data, String filePath) {
+    data.init();
+
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+    getFile().getText(); //to load text
+    myJavaFilesFilter.allowTreeAccessForFile(getVFile());
+    getJavaFacade().setAssertOnFileLoadingFilter(myJavaFilesFilter); // check repository work
+
+    Collection<HighlightInfo> infos = doHighlighting();
+
+    getJavaFacade().setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
+
+    data.checkResult(infos, getEditor().getDocument().getText(), filePath);
+  }
+
+  protected HighlightTestInfo doTestFile(@NonNls @NotNull String filePath) {
+    return new HighlightTestInfo(getTestRootDisposable(), filePath){
+      @Override
+      public HighlightTestInfo doTest() throws Exception {
+        String path = assertOneElement(filePaths);
+        configureByFile(path);
+        ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
+        if (checkSymbolNames) data.checkSymbolNames();
+
+        checkHighlighting(data, composeLocalPath(path));
+        return this;
+      }
+    };
+  }
+
+  @NotNull
+  protected List<HighlightInfo> highlightErrors() {
+    return doHighlighting(HighlightSeverity.ERROR);
+  }
+
+  @NotNull
+  protected List<HighlightInfo> doHighlighting() {
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+
+    int[] toIgnore = doFolding() ? ArrayUtil.EMPTY_INT_ARRAY : new int[]{Pass.UPDATE_FOLDING};
+    Editor editor = getEditor();
+    PsiFile file = getFile();
+    if (editor instanceof EditorWindow) {
+      editor = ((EditorWindow)editor).getDelegate();
+      file = InjectedLanguageUtil.getTopLevelFile(file);
+    }
+    
+    return CodeInsightTestFixtureImpl.instantiateAndRun(file, editor, toIgnore, false);
+  }
+
+  protected List<HighlightInfo> doHighlighting(HighlightSeverity minSeverity) {
+    return DaemonAnalyzerTestCase.filter(doHighlighting(), minSeverity);
+  }
+
+  protected boolean doFolding() {
+    return false;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java
new file mode 100644
index 0000000..9268189
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/LightIntentionActionTestCase.java
@@ -0,0 +1,6 @@
+package com.intellij.codeInsight.daemon;
+
+import com.intellij.codeInsight.daemon.quickFix.LightQuickFixTestCase;
+
+public abstract class LightIntentionActionTestCase extends LightQuickFixTestCase {
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
new file mode 100644
index 0000000..9cf1c20
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/LightQuickFixTestCase.java
@@ -0,0 +1,318 @@
+/*
+ * 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.daemon.quickFix;
+
+import com.intellij.codeInsight.daemon.LightDaemonAnalyzerTestCase;
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
+import com.intellij.lang.Commenter;
+import com.intellij.lang.LanguageCommenters;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.CharsetToolkit;
+import com.intellij.psi.PsiFile;
+import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
+import com.intellij.rt.execution.junit.FileComparisonFailure;
+import com.intellij.testFramework.LightPlatformCodeInsightTestCase;
+import com.intellij.testFramework.LightPlatformTestCase;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.util.ui.UIUtil;
+import org.intellij.lang.annotations.RegExp;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+import java.io.FilenameFilter;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.List;
+import java.util.regex.Matcher;
+import java.util.regex.Pattern;
+
+public abstract class LightQuickFixTestCase extends LightDaemonAnalyzerTestCase {
+  @NonNls private static final String BEFORE_PREFIX = "before";
+  private static QuickFixTestCase myWrapper;
+
+  protected boolean shouldBeAvailableAfterExecution() {
+    return false;
+  }
+
+  protected Pair<String, Boolean> parseActionHintImpl(final PsiFile file, String contents) {
+    return parseActionHint(file, contents);
+  }
+
+  private static void doTestFor(final String testName, final QuickFixTestCase quickFixTestCase) {
+    final String relativePath = quickFixTestCase.getBasePath() + "/" + BEFORE_PREFIX + testName;
+    final String testFullPath = quickFixTestCase.getTestDataPath().replace(File.separatorChar, '/') + relativePath;
+    final File testFile = new File(testFullPath);
+    CommandProcessor.getInstance().executeCommand(quickFixTestCase.getProject(), new Runnable() {
+      @Override
+      public void run() {
+        try {
+          String contents = StringUtil.convertLineSeparators(FileUtil.loadFile(testFile, CharsetToolkit.UTF8));
+          quickFixTestCase.configureFromFileText(testFile.getName(), contents);
+          quickFixTestCase.bringRealEditorBack();
+          final Pair<String, Boolean> pair = quickFixTestCase.parseActionHintImpl(quickFixTestCase.getFile(), contents);
+          final String text = pair.getFirst();
+          final boolean actionShouldBeAvailable = pair.getSecond().booleanValue();
+
+          quickFixTestCase.beforeActionStarted(testName, contents);
+
+          try {
+            myWrapper = quickFixTestCase;
+            quickFixTestCase.doAction(text, actionShouldBeAvailable, testFullPath, testName);
+          }
+          finally {
+            myWrapper = null;
+            quickFixTestCase.afterActionCompleted(testName, contents);
+          }
+        }
+        catch (FileComparisonFailure e){
+          throw e;
+        }
+        catch (Throwable e) {
+          e.printStackTrace();
+          fail(testName);
+        }
+      }
+    }, "", "");
+  }
+
+  protected void afterActionCompleted(final String testName, final String contents) {
+  }
+
+  protected void beforeActionStarted(final String testName, final String contents) {
+  }
+
+  public static Pair<String, Boolean> parseActionHint(final PsiFile file, String contents) {
+    return parseActionHint(file, contents, " \"(.*)\" \"(true|false)\".*");
+  }
+
+  public static Pair<String, Boolean> parseActionHint(final PsiFile file, String contents, @NonNls @RegExp String actionPattern) {
+    PsiFile hostFile = InjectedLanguageUtil.getTopLevelFile(file);
+
+    final Commenter commenter = LanguageCommenters.INSTANCE.forLanguage(hostFile.getLanguage());
+    String comment = commenter.getLineCommentPrefix();
+    if (comment == null) {
+      comment = commenter.getBlockCommentPrefix();
+    }
+    
+    // "quick fix action text to perform" "should be available"
+    Pattern pattern = Pattern.compile("^" + comment.replace("*", "\\*") + actionPattern, Pattern.DOTALL);
+    Matcher matcher = pattern.matcher(contents);
+    assertTrue("No comment found in "+file.getVirtualFile(), matcher.matches());
+    final String text = matcher.group(1);
+    final Boolean actionShouldBeAvailable = Boolean.valueOf(matcher.group(2));
+    return Pair.create(text, actionShouldBeAvailable);
+  }
+
+  @SuppressWarnings({"HardCodedStringLiteral"})
+  public static void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath, final String testName,
+                              QuickFixTestCase quickFix)
+    throws Exception {
+    IntentionAction action = quickFix.findActionWithText(text);
+    if (action == null) {
+      if (actionShouldBeAvailable) {
+        List<IntentionAction> actions = quickFix.getAvailableActions();
+        List<String> texts = new ArrayList<String>();
+        for (IntentionAction intentionAction : actions) {
+          texts.add(intentionAction.getText());
+        }
+        Collection<HighlightInfo> infos = quickFix.doHighlighting();
+        fail("Action with text '" + text + "' is not available in test " + testFullPath+"\nAvailable actions ("+texts.size()+"): "+texts+"\n"+actions+"\nInfos:"+infos);
+      }
+    }
+    else {
+      if (!actionShouldBeAvailable) {
+        fail("Action '" + text + "' is available (but must not) in test " + testFullPath);
+      }
+      quickFix.invoke(action);
+      UIUtil.dispatchAllInvocationEvents();
+      UIUtil.dispatchAllInvocationEvents();
+      if (!quickFix.shouldBeAvailableAfterExecution()) {
+        final IntentionAction afterAction = quickFix.findActionWithText(text);
+        if (afterAction != null) {
+          fail("Action '" + text + "' is still available after its invocation in test " + testFullPath);
+        }
+      }
+      final String expectedFilePath = quickFix.getBasePath() + "/after" + testName;
+      quickFix.checkResultByFile("In file :" + expectedFilePath, expectedFilePath, false);
+    }
+  }
+
+  protected void doAction(final String text, final boolean actionShouldBeAvailable, final String testFullPath, final String testName)
+    throws Exception {
+    doAction(text, actionShouldBeAvailable, testFullPath, testName, myWrapper);
+  }
+
+  protected void doAction(final String actionName) {
+    final List<IntentionAction> available = getAvailableActions();
+    final IntentionAction action = findActionWithText(available, actionName);
+    assertNotNull("Action '" + actionName + "' not found among " + available.toString(), action);
+    invoke(action);
+  }
+
+  protected static void invoke(IntentionAction action) throws IncorrectOperationException {
+    ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
+  }
+
+  protected IntentionAction findActionWithText(final String text) {
+    return findActionWithText(getAvailableActions(), text);
+  }
+
+  public static IntentionAction findActionWithText(final List<IntentionAction> actions, final String text) {
+    for (IntentionAction action : actions) {
+      if (text.equals(action.getText())) {
+        return action;
+      }
+    }
+    return null;
+  }
+
+  public static void doAllTests(QuickFixTestCase testCase) throws Exception {
+    assertNotNull("getBasePath() should not return null!", testCase.getBasePath());
+
+    final String testDirPath = testCase.getTestDataPath().replace(File.separatorChar, '/') + testCase.getBasePath();
+    File testDir = new File(testDirPath);
+    final File[] files = testDir.listFiles(new FilenameFilter() {
+      @Override
+      public boolean accept(File dir, @NonNls String name) {
+        return name.startsWith(BEFORE_PREFIX);
+      }
+    });
+
+    if (files == null) {
+      fail("Test files not found in " + testDirPath);
+    }
+
+    for (File file : files) {
+      final String testName = file.getName().substring(BEFORE_PREFIX.length());
+      doTestFor(testName, testCase);
+      System.out.println(file.getPath());
+    }
+    assertTrue("Test files not found in "+testDirPath,files.length != 0);
+  }
+
+  protected void doSingleTest(String fileSuffix) {
+    doTestFor(fileSuffix, createWrapper());
+  }
+
+  protected void doAllTests() throws Exception {
+    doAllTests(createWrapper());
+  }
+
+  private QuickFixTestCase createWrapper() {
+    return new QuickFixTestCase() {
+      @Override
+      public String getBasePath() {
+        return LightQuickFixTestCase.this.getBasePath();
+      }
+
+      @Override
+      public String getTestDataPath() {
+        return LightQuickFixTestCase.this.getTestDataPath();
+      }
+
+      @Override
+      public Pair<String, Boolean> parseActionHintImpl(PsiFile file, String contents) {
+        return LightQuickFixTestCase.this.parseActionHintImpl(file, contents);
+      }
+
+      @Override
+      public void beforeActionStarted(String testName, String contents) {
+        LightQuickFixTestCase.this.beforeActionStarted(testName, contents);
+      }
+
+      @Override
+      public void afterActionCompleted(String testName, String contents) {
+        LightQuickFixTestCase.this.afterActionCompleted(testName, contents);
+      }
+
+      @Override
+      public void doAction(String text, boolean actionShouldBeAvailable, String testFullPath, String testName) throws Exception {
+        LightQuickFixTestCase.this.doAction(text, actionShouldBeAvailable, testFullPath, testName);
+      }
+
+      @Override
+      public void checkResultByFile(String s, String expectedFilePath, boolean b) throws Exception {
+        LightQuickFixTestCase.this.checkResultByFile(s, expectedFilePath, b);
+      }
+
+      @Override
+      public IntentionAction findActionWithText(String text) {
+        return LightQuickFixTestCase.this.findActionWithText(text);
+      }
+
+      @Override
+      public boolean shouldBeAvailableAfterExecution() {
+        return LightQuickFixTestCase.this.shouldBeAvailableAfterExecution();
+      }
+
+      @Override
+      public void invoke(IntentionAction action) {
+        LightQuickFixTestCase.invoke(action);
+      }
+
+      @Override
+      public List<HighlightInfo> doHighlighting() {
+        return LightQuickFixTestCase.this.doHighlighting();
+      }
+
+      @Override
+      public List<IntentionAction> getAvailableActions() {
+        return LightQuickFixTestCase.this.getAvailableActions();
+      }
+
+      @Override
+      public void configureFromFileText(String name, String contents) throws IOException {
+        LightPlatformCodeInsightTestCase.configureFromFileText(name, contents);
+      }
+
+      @Override
+      public PsiFile getFile() {
+        return LightPlatformCodeInsightTestCase.getFile();
+      }
+
+      @Override
+      public Project getProject() {
+        return LightPlatformTestCase.getProject();
+      }
+
+      @Override
+      public void bringRealEditorBack() {
+        LightPlatformCodeInsightTestCase.bringRealEditorBack();
+      }
+    };
+  }
+
+  protected List<IntentionAction> getAvailableActions() {
+    doHighlighting();
+    return getAvailableActions(getEditor(), getFile());
+  }
+
+  public static List<IntentionAction> getAvailableActions(@NotNull Editor editor, @NotNull PsiFile file) {
+    return CodeInsightTestFixtureImpl.getAvailableIntentions(editor, file);
+  }
+
+  @NonNls protected String getBasePath() {return null;}
+}
diff --git a/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.java b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.java
new file mode 100644
index 0000000..6134887
--- /dev/null
+++ b/java/testFramework/src/com/intellij/codeInsight/daemon/quickFix/QuickFixTestCase.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.codeInsight.daemon.quickFix;
+
+import com.intellij.codeInsight.daemon.impl.HighlightInfo;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.util.Pair;
+import com.intellij.psi.PsiFile;
+
+import java.util.List;
+
+/**
+ * @author Maxim.Mossienko
+*         Date: 22.01.2009
+*         Time: 0:28:45
+*/
+public interface QuickFixTestCase {
+  String getBasePath();
+
+  String getTestDataPath();
+
+  Pair<String, Boolean> parseActionHintImpl(PsiFile file, String contents);
+
+  void beforeActionStarted(String testName, String contents);
+
+  void afterActionCompleted(String testName, String contents);
+
+  void doAction(String text, boolean actionShouldBeAvailable, String testFullPath, String testName) throws Exception;
+
+  void checkResultByFile(String s, String expectedFilePath, boolean b) throws Exception;
+
+  IntentionAction findActionWithText(String text);
+
+  boolean shouldBeAvailableAfterExecution();
+
+  void invoke(IntentionAction action);
+
+  List<HighlightInfo> doHighlighting();
+
+  List<IntentionAction> getAvailableActions();
+
+  void bringRealEditorBack();
+
+  void configureFromFileText(String name, String contents) throws Throwable;
+
+  PsiFile getFile();
+
+  Project getProject();
+}
diff --git a/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
new file mode 100644
index 0000000..6dcf778
--- /dev/null
+++ b/java/testFramework/src/com/intellij/ide/projectWizard/ProjectWizardTestCase.java
@@ -0,0 +1,190 @@
+package com.intellij.ide.projectWizard;
+
+import com.intellij.ide.actions.ImportModuleAction;
+import com.intellij.ide.impl.NewProjectUtil;
+import com.intellij.ide.util.newProjectWizard.AddModuleWizard;
+import com.intellij.ide.util.newProjectWizard.SelectTemplateStep;
+import com.intellij.ide.util.projectWizard.ModuleWizardStep;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.projectRoots.ProjectJdkTable;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkTypeId;
+import com.intellij.openapi.roots.ProjectRootManager;
+import com.intellij.openapi.roots.ui.configuration.DefaultModulesProvider;
+import com.intellij.openapi.roots.ui.configuration.actions.NewModuleAction;
+import com.intellij.openapi.util.Condition;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.platform.ProjectTemplate;
+import com.intellij.projectImport.ProjectImportProvider;
+import com.intellij.testFramework.PlatformTestCase;
+import com.intellij.util.Consumer;
+import com.intellij.util.containers.ContainerUtil;
+import com.intellij.util.ui.UIUtil;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.List;
+
+/**
+ * @author Dmitry Avdeev
+ *         Date: 10/29/12
+ */
+public abstract class ProjectWizardTestCase extends PlatformTestCase {
+
+  protected final List<Sdk> mySdks = new ArrayList<Sdk>();
+  protected AddModuleWizard myWizard;
+  @Nullable
+  private Project myCreatedProject;
+
+  protected Project createProjectFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+    runWizard(group, name, null, adjuster);
+    try {
+      myCreatedProject = NewProjectUtil.createFromWizard(myWizard, null);
+    }
+    catch (Throwable e) {
+      myCreatedProject = ContainerUtil.find(myProjectManager.getOpenProjects(), new Condition<Project>() {
+        @Override
+        public boolean value(Project project) {
+          return myWizard.getProjectName().equals(project.getName());
+        }
+      });
+      throw new RuntimeException(e);
+    }
+    assertNotNull(myCreatedProject);
+    UIUtil.dispatchAllInvocationEvents();
+
+    Project[] projects = myProjectManager.getOpenProjects();
+    assertEquals(2, projects.length);
+    return myCreatedProject;
+  }
+
+  @Nullable
+  protected Module createModuleFromTemplate(String group, String name, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+    runWizard(group, name, getProject(), adjuster);
+    return createModuleFromWizard();
+  }
+
+  protected Module createModuleFromWizard() {
+    return new NewModuleAction().createModuleFromWizard(myProject, null, myWizard);
+  }
+
+  protected void runWizard(String group, String name, Project project, @Nullable Consumer<ModuleWizardStep> adjuster) throws IOException {
+
+    createWizard(project);
+    SelectTemplateStep step = (SelectTemplateStep)myWizard.getCurrentStepObject();
+    boolean condition = step.setSelectedTemplate(group, name);
+    if (!condition) {
+      throw new IllegalArgumentException(group + "/" + name + " template not found");
+    }
+    ProjectTemplate template = step.getSelectedTemplate();
+    assertNotNull(template);
+
+    if (adjuster != null) {
+      adjuster.consume(step);
+    }
+
+    runWizard(adjuster);
+  }
+
+  protected void createWizard(Project project) throws IOException {
+    File directory = FileUtil.createTempDirectory(getName(), "new", false);
+    myFilesToDelete.add(directory);
+    myWizard = new AddModuleWizard(project, DefaultModulesProvider.createForProject(project), directory.getPath());
+    UIUtil.dispatchAllInvocationEvents(); // to make default selection applied
+  }
+
+  protected void runWizard(Consumer<ModuleWizardStep> adjuster) {
+    while (!myWizard.isLast()) {
+      myWizard.doNextAction();
+      if (adjuster != null) {
+        adjuster.consume(myWizard.getCurrentStepObject());
+      }
+    }
+    myWizard.doOk();
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    Sdk projectSdk = ProjectRootManager.getInstance(getProject()).getProjectSdk();
+    Sdk[] jdks = ProjectJdkTable.getInstance().getAllJdks();
+    for (final Sdk jdk : jdks) {
+      if (projectSdk != jdk) {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          public void run() {
+            ProjectJdkTable.getInstance().removeJdk(jdk);
+          }
+        });
+      }
+    }
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    if (myWizard != null) {
+      Disposer.dispose(myWizard.getDisposable());
+    }
+    if (myCreatedProject != null) {
+      myProjectManager.closeProject(myCreatedProject);
+      ApplicationManager.getApplication().runWriteAction(new Runnable() {
+        @Override
+        public void run() {
+          Disposer.dispose(myCreatedProject);
+        }
+      });
+    }
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        for (Sdk sdk : mySdks) {
+          ProjectJdkTable.getInstance().removeJdk(sdk);
+        }
+      }
+    });
+    super.tearDown();
+  }
+
+  protected Module importModuleFrom(ProjectImportProvider provider, String path) {
+    return importFrom(path, getProject(), null, provider);
+  }
+
+  protected Module importProjectFrom(String path, Consumer<ModuleWizardStep> adjuster, ProjectImportProvider... providers) {
+    Module module = importFrom(path, null, adjuster, providers);
+    if (module != null) {
+      myCreatedProject = module.getProject();
+    }
+    return module;
+  }
+
+  private Module importFrom(String path,
+                            @Nullable Project project, Consumer<ModuleWizardStep> adjuster,
+                            final ProjectImportProvider... providers) {
+    VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByPath(path);
+    assertNotNull("Can't find " + path, file);
+    assertTrue(providers[0].canImport(file, project));
+
+    myWizard = ImportModuleAction.createImportWizard(project, null, file, providers);
+    if (myWizard.getStepCount() > 0) {
+      runWizard(adjuster);
+    }
+    List<Module> modules = ImportModuleAction.createFromWizard(project, myWizard);
+    return modules == null || modules.isEmpty() ? null : modules.get(0);
+  }
+
+  protected Sdk createSdk(String name, SdkTypeId sdkType) {
+    final Sdk sdk = ProjectJdkTable.getInstance().createSdk(name, sdkType);
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        ProjectJdkTable.getInstance().addJdk(sdk);
+      }
+    });
+    mySdks.add(sdk);
+    return sdk;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java b/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java
new file mode 100644
index 0000000..b451b29
--- /dev/null
+++ b/java/testFramework/src/com/intellij/mock/MockPsiDirectory.java
@@ -0,0 +1,137 @@
+/*
+ * Copyright (c) 2000-2006 JetBrains s.r.o. All Rights Reserved.
+ */
+package com.intellij.mock;
+
+import com.intellij.navigation.ItemPresentation;
+import com.intellij.openapi.Disposable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.search.PsiElementProcessor;
+import com.intellij.util.IncorrectOperationException;
+import com.intellij.lang.Language;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+/**
+ * @author peter
+ */
+public class MockPsiDirectory extends MockPsiElement implements PsiDirectory {
+  private final PsiPackage myPackage;
+
+  public MockPsiDirectory(final PsiPackage aPackage, @NotNull Disposable parentDisposable) {
+    super(parentDisposable);
+    myPackage = aPackage;
+  }
+
+  @Override
+  public boolean isDirectory() {
+    return true;
+  }
+
+  @NotNull
+  @Override
+  public Language getLanguage() {
+    return Language.ANY;
+  }
+
+  @Override
+  public void checkCreateFile(@NotNull final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method checkCreateFile is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  public void checkCreateSubdirectory(@NotNull final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method checkCreateSubdirectory is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  public PsiDirectory getParent() {
+    return getParentDirectory();
+  }
+
+
+  @Override
+  @NotNull
+  public PsiFile createFile(@NotNull final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method createFile is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public PsiFile copyFileFrom(@NotNull final String newName, @NotNull final PsiFile originalFile) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method copyFileFrom is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public PsiDirectory createSubdirectory(@NotNull final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method createSubdirectory is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @Nullable
+  public PsiFile findFile(@NotNull @NonNls final String name) {
+    throw new UnsupportedOperationException("Method findFile is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @Nullable
+  public PsiDirectory findSubdirectory(@NotNull final String name) {
+    throw new UnsupportedOperationException("Method findSubdirectory is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public PsiFile[] getFiles() {
+    throw new UnsupportedOperationException("Method getFiles is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public String getName() {
+    throw new UnsupportedOperationException("Method getName is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @Nullable
+  public PsiDirectory getParentDirectory() {
+    final PsiPackage psiPackage = myPackage.getParentPackage();
+    return psiPackage == null ? null : new MockPsiDirectory(psiPackage, getProject());
+  }
+
+  @Override
+  @NotNull
+  public PsiDirectory[] getSubdirectories() {
+    throw new UnsupportedOperationException("Method getSubdirectories is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public VirtualFile getVirtualFile() {
+    throw new UnsupportedOperationException("Method getVirtualFile is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  public boolean processChildren(final PsiElementProcessor<PsiFileSystemItem> processor) {
+    throw new UnsupportedOperationException("Method processChildren is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @NotNull
+  public PsiElement setName(@NotNull final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method setName is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  public void checkSetName(final String name) throws IncorrectOperationException {
+    throw new IncorrectOperationException("Method checkSetName is not yet implemented in " + getClass().getName());
+  }
+
+  @Override
+  @Nullable
+  public ItemPresentation getPresentation() {
+    throw new UnsupportedOperationException("Method getPresentation is not yet implemented in " + getClass().getName());
+  }
+}
diff --git a/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java
new file mode 100644
index 0000000..7979272
--- /dev/null
+++ b/java/testFramework/src/com/intellij/projectView/BaseProjectViewTestCase.java
@@ -0,0 +1,311 @@
+/*
+ * 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.projectView;
+
+import com.intellij.ide.SelectInTarget;
+import com.intellij.ide.projectView.BaseProjectTreeBuilder;
+import com.intellij.ide.projectView.ProjectView;
+import com.intellij.ide.projectView.ViewSettings;
+import com.intellij.ide.projectView.impl.*;
+import com.intellij.ide.projectView.impl.nodes.PackageElementNode;
+import com.intellij.ide.projectView.impl.nodes.PsiDirectoryNode;
+import com.intellij.ide.util.treeView.*;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.project.DumbAwareRunnable;
+import com.intellij.openapi.startup.StartupManager;
+import com.intellij.openapi.ui.Queryable;
+import com.intellij.openapi.util.Disposer;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import com.intellij.psi.PsiElement;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.ProjectViewTestUtil;
+import com.intellij.testFramework.TestSourceBasedTestCase;
+import com.intellij.util.Function;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import javax.swing.*;
+import javax.swing.tree.DefaultMutableTreeNode;
+import javax.swing.tree.DefaultTreeModel;
+import javax.swing.tree.TreeModel;
+import javax.swing.tree.TreePath;
+import java.util.ArrayList;
+import java.util.Comparator;
+import java.util.List;
+
+public abstract class BaseProjectViewTestCase extends TestSourceBasedTestCase {
+  protected AbstractTreeStructure myStructure;
+  protected boolean myShowMembers = false;
+  protected boolean myHideEmptyMiddlePackages;
+  protected boolean myFlattenPackages;
+
+  private List<AbstractProjectViewPSIPane> myPanes = new ArrayList<AbstractProjectViewPSIPane>();
+
+  protected Queryable.PrintInfo myPrintInfo;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    myStructure = new TestProjectTreeStructure(myProject) {
+      @Override
+      public boolean isShowMembers() {
+        return myShowMembers;
+      }
+
+      @Override
+      public boolean isHideEmptyMiddlePackages() {
+        return myHideEmptyMiddlePackages;
+      }
+
+      @Override
+      public boolean isFlattenPackages() {
+        return myFlattenPackages;
+      }
+    };
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    for (final AbstractProjectViewPSIPane myPane : myPanes) {
+      Disposer.dispose(myPane);
+    }
+    myPanes = null;
+    myStructure = null;
+    super.tearDown();
+  }
+
+  protected AbstractProjectViewPSIPane createPane() {
+    final AbstractProjectViewPSIPane pane = new MyAbstractProjectViewPSIPane();
+    pane.createComponent();
+    myPanes.add(pane);
+    return pane;
+  }
+
+  protected void assertStructureEqual(PsiDirectory packageDirectory, @NonNls String expected) {
+    assertStructureEqual(packageDirectory, expected, 17, myStructure);
+  }
+
+  protected void assertStructureEqual(PsiDirectory packageDirectory, @NonNls String expected, int maxRowCount) {
+    assertStructureEqual(packageDirectory, expected, maxRowCount, myStructure);
+  }
+
+  protected void useStandardProviders() {
+    getProjectTreeStructure().setProviders(new ClassesTreeStructureProvider(myProject));
+  }
+
+  protected AbstractProjectTreeStructure getProjectTreeStructure() {
+    return (AbstractProjectTreeStructure)myStructure;
+  }
+
+  protected void assertStructureEqual(String expected, Comparator comparator) {
+    assertStructureEqual(myStructure.getRootElement(), expected, 27, comparator);
+  }
+
+  private void assertStructureEqual(PsiDirectory root, String expected, int maxRowCount, AbstractTreeStructure structure) {
+    assertNotNull(root);
+    PsiDirectoryNode rootNode = new PsiDirectoryNode(myProject, root, (ViewSettings)structure);
+    assertStructureEqual(rootNode, expected, maxRowCount, PlatformTestUtil.createComparator(myPrintInfo));
+  }
+
+  private void assertStructureEqual(Object rootNode, String expected, int maxRowCount, Comparator comparator) {
+    checkGetParentConsistency(rootNode);
+    String actual = PlatformTestUtil.print(myStructure, rootNode, 0, comparator, maxRowCount, ' ', myPrintInfo).toString();
+    assertEquals(expected, actual);
+  }
+
+  private void checkGetParentConsistency(Object from) {
+    Object[] childElements = myStructure.getChildElements(from);
+    for (Object childElement : childElements) {
+      assertSame(from, myStructure.getParentElement(childElement));
+      checkGetParentConsistency(childElement);
+    }
+  }
+
+  protected static boolean isExpanded(DefaultMutableTreeNode nodeForElement, AbstractProjectViewPSIPane pane) {
+    TreePath path = new TreePath(nodeForElement.getPath());
+    return pane.getTree().isExpanded(path.getParentPath());
+  }
+
+  protected static DefaultMutableTreeNode getNodeForElement(PsiElement element, AbstractProjectViewPSIPane pane) {
+    JTree tree = pane.getTree();
+    TreeModel model = tree.getModel();
+    Object root = model.getRoot();
+    return getNodeForElement(root, model, element);
+  }
+
+  private static DefaultMutableTreeNode getNodeForElement(Object root, TreeModel model, PsiElement element) {
+    if (root instanceof DefaultMutableTreeNode) {
+      Object userObject = ((DefaultMutableTreeNode)root).getUserObject();
+      if (userObject instanceof AbstractTreeNode) {
+        AbstractTreeNode treeNode = (AbstractTreeNode)userObject;
+        if (element.equals(treeNode.getValue())) return (DefaultMutableTreeNode)root;
+        for (int i = 0; i < model.getChildCount(root); i++) {
+          DefaultMutableTreeNode nodeForChild = getNodeForElement(model.getChild(root, i), model, element);
+          if (nodeForChild != null) return nodeForChild;
+        }
+      }
+    }
+    return null;
+  }
+
+  public static void checkNavigateFromSourceBehaviour(PsiElement element, VirtualFile virtualFile, AbstractProjectViewPSIPane pane) {
+    Disposer.dispose(pane);
+    pane.createComponent();
+    assertNull(getNodeForElement(element, pane));
+    pane.select(element, virtualFile, true);
+    assertTrue(isExpanded(element, pane));
+  }
+
+  public static boolean isExpanded(PsiElement element, AbstractProjectViewPSIPane pane) {
+    DefaultMutableTreeNode nodeForElement = getNodeForElement(element, pane);
+    return nodeForElement != null && isExpanded((DefaultMutableTreeNode)nodeForElement.getParent(), pane);
+  }
+
+  protected static void assertListsEqual(ListModel model, String expected) {
+    assertEquals(expected, PlatformTestUtil.print(model));
+  }
+
+  public static void checkContainsMethod(final Object rootElement, final AbstractTreeStructure structure) {
+    ProjectViewTestUtil.checkContainsMethod(rootElement, structure, new Function<AbstractTreeNode, VirtualFile[]>() {
+      @Override
+      public VirtualFile[] fun(AbstractTreeNode kid) {
+        if (kid instanceof PackageElementNode) {
+          return ((PackageElementNode)kid).getVirtualFiles();
+        }
+        return null;
+      }
+    });
+  }
+
+  @Override
+  protected String getTestPath() {
+    return "projectView";
+  }
+
+  protected static String getPackageRelativePath() {
+    return "com/package1";
+  }
+
+  protected PsiDirectory getPackageDirectory() {
+    return getPackageDirectory(getPackageRelativePath());
+  }
+
+  private class MyAbstractProjectViewPSIPane extends AbstractProjectViewPSIPane {
+    public MyAbstractProjectViewPSIPane() {
+      super(BaseProjectViewTestCase.this.myProject);
+    }
+
+    @Override
+    public SelectInTarget createSelectInTarget() {
+      return null;
+    }
+
+    @NonNls
+    public String getComponentName() {
+      return "comp name";
+    }
+
+    @Override
+    protected AbstractTreeUpdater createTreeUpdater(AbstractTreeBuilder treeBuilder) {
+      return new AbstractTreeUpdater(treeBuilder);
+    }
+
+    @Override
+    @NotNull
+    protected BaseProjectTreeBuilder createBuilder(DefaultTreeModel treeModel) {
+      return new ProjectTreeBuilder(myProject, myTree, treeModel, AlphaComparator.INSTANCE,
+                                    (ProjectAbstractTreeStructureBase)myTreeStructure) {
+        @Override
+        protected AbstractTreeUpdater createUpdater() {
+          return createTreeUpdater(this);
+        }
+
+        protected void addTaskToWorker(final Runnable runnable, boolean first, final Runnable postRunnable) {
+          runnable.run();
+          postRunnable.run();
+        }
+      };
+    }
+
+    @Override
+    protected ProjectAbstractTreeStructureBase createStructure() {
+      return (ProjectAbstractTreeStructureBase)myStructure;
+    }
+
+    @Override
+    protected ProjectViewTree createTree(DefaultTreeModel treeModel) {
+      return new ProjectViewTree(myProject, treeModel) {
+        @Override
+        public DefaultMutableTreeNode getSelectedNode() {
+          return null;
+        }
+      };
+    }
+
+    @Override
+    public Icon getIcon() {
+      return null;
+    }
+
+    @Override
+    @NotNull
+    public String getId() {
+      return "";
+    }
+
+    @Override
+    public String getTitle() {
+      return null;
+    }
+
+    @Override
+    public int getWeight() {
+      return 0;
+    }
+
+    public void projectOpened() {
+      final Runnable runnable = new DumbAwareRunnable() {
+        @Override
+        public void run() {
+          final ProjectView projectView = ProjectView.getInstance(myProject);
+          projectView.addProjectPane(MyAbstractProjectViewPSIPane.this);
+        }
+      };
+      StartupManager.getInstance(myProject).registerPostStartupActivity(runnable);
+    }
+
+    public void projectClosed() {
+    }
+
+    public void initComponent() { }
+
+    public void disposeComponent() {
+
+    }
+  }
+
+  @Override
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath(getClass());
+  }
+
+  @Override
+  protected boolean isRunInWriteAction() {
+    return false;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java b/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.java
new file mode 100644
index 0000000..40a42a1
--- /dev/null
+++ b/java/testFramework/src/com/intellij/projectView/TestProjectTreeStructure.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.projectView;
+
+import com.intellij.ide.projectView.impl.AbstractProjectTreeStructure;
+import com.intellij.openapi.project.Project;
+
+class TestProjectTreeStructure extends AbstractProjectTreeStructure {
+  public TestProjectTreeStructure(Project project) {
+    super(project);
+  }
+
+  @Override
+  public boolean isShowMembers() {
+    return false;
+  }
+
+  @Override
+  public boolean isFlattenPackages() {
+    return false;
+  }
+
+  @Override
+  public boolean isAbbreviatePackageNames() {
+    return false;
+  }
+
+  @Override
+  public boolean isHideEmptyMiddlePackages() {
+    return false;
+  }
+
+  @Override
+  public boolean isShowLibraryContents() {
+    return true;
+  }
+
+  @Override
+  public boolean isShowModules() {
+    return true;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java b/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java
new file mode 100644
index 0000000..43bf6cc
--- /dev/null
+++ b/java/testFramework/src/com/intellij/psi/AbstractReparseTestCase.java
@@ -0,0 +1,105 @@
+package com.intellij.psi;
+
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.CommandProcessor;
+import com.intellij.openapi.components.ServiceManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.psi.impl.DebugUtil;
+import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.psi.text.BlockSupport;
+import com.intellij.testFramework.PsiTestCase;
+import com.intellij.util.IncorrectOperationException;
+import org.jetbrains.annotations.NonNls;
+
+/**
+ * @author maxim
+ */
+public abstract class AbstractReparseTestCase extends PsiTestCase {
+  protected FileType myFileType;
+  protected PsiFile myDummyFile;
+  private int myInsertOffset;
+
+  protected void setFileType(final FileType fileType) {
+    myFileType = fileType;
+  }
+
+  protected void insert(@NonNls final String s) throws IncorrectOperationException {
+    CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          @Override
+          public void run() {
+            String oldText = myDummyFile.getText();
+            String expectedNewText = oldText.substring(0, myInsertOffset) + s + oldText.substring(myInsertOffset);
+
+            try {
+              doReparse(s, expectedNewText, 0);
+            }
+            catch (IncorrectOperationException e) {
+              LOG.error(e);
+            }
+            myInsertOffset += s.length();
+          }
+        });
+      }
+    }, "asd", null);
+  }
+
+  protected void moveEditPointLeft(int count) {
+    myInsertOffset -= count;
+  }
+
+  protected void moveEditPointRight(int count) {
+    myInsertOffset += count;
+  }
+
+  protected void setEditPoint(int pos) {
+    myInsertOffset = pos;
+  }
+
+  protected void remove(int count) throws IncorrectOperationException {
+    String oldText = myDummyFile.getText();
+    String expectedNewText = oldText.substring(0, myInsertOffset-count) + oldText.substring(myInsertOffset);
+
+    doReparse("", expectedNewText, count);
+    myInsertOffset -= count;
+  }
+
+  protected void doReparse(final String s, final String expectedNewText, final int length) throws IncorrectOperationException {
+    CommandProcessor.getInstance().executeCommand(getProject(), new Runnable() {
+      @Override
+      public void run() {
+        ApplicationManager.getApplication().runWriteAction(new Runnable() {
+          @Override
+          public void run() {
+            BlockSupport blockSupport = ServiceManager.getService(myProject, BlockSupport.class);
+            try {
+              blockSupport.reparseRange(myDummyFile, myInsertOffset - length, myInsertOffset, s);
+              String foundStructure = DebugUtil.treeToString(SourceTreeToPsiMap.psiElementToTree(myDummyFile), false);
+              final PsiFile psiFile = createDummyFile(getName() + "." + myFileType.getDefaultExtension(), expectedNewText);
+              String expectedStructure = DebugUtil.treeToString(SourceTreeToPsiMap.psiElementToTree(psiFile), false);
+              if (!expectedStructure.equals(foundStructure)) {
+                System.out.println("expected: ");
+                System.out.println(expectedStructure);
+                System.out.println("found: ");
+                System.out.println(foundStructure);
+                assertEquals(expectedStructure, foundStructure);
+              }
+
+              assertEquals("Reparse tree should be equal to the document",expectedNewText,myDummyFile.getText());
+            }
+            catch (IncorrectOperationException e) {
+              LOG.error(e);
+            }
+          }
+        });
+      }
+    }, "asd", null);
+  }
+
+  protected void prepareFile(@NonNls String prefix, @NonNls String suffix) throws IncorrectOperationException {
+    myDummyFile = createDummyFile(getName() + "." + myFileType.getDefaultExtension(), prefix + suffix);
+    myInsertOffset = prefix.length();
+  }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.java b/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.java
new file mode 100644
index 0000000..3d070ef
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/MockInlineMethodOptions.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.refactoring.inline.InlineOptions;
+
+/**
+ * @author dyoma
+ */
+public class MockInlineMethodOptions implements InlineOptions {
+  @Override
+  public boolean isInlineThisOnly() {
+    return false;
+  }
+
+  @Override
+  public void close(int exitCode) {
+  }
+
+  @Override
+  public boolean isPreviewUsages() {
+    return false;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java
new file mode 100644
index 0000000..b21347b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/MultiFileTestCase.java
@@ -0,0 +1,86 @@
+/*
+ * Copyright 2000-2011 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring;
+
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDocumentManager;
+import com.intellij.psi.impl.source.PostprocessReformattingAspect;
+import com.intellij.testFramework.PlatformTestUtil;
+import com.intellij.testFramework.PsiTestUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * @author dsl
+ */
+public abstract class MultiFileTestCase extends CodeInsightTestCase {
+  protected boolean myDoCompare = true;
+
+  protected void doTest(final PerformAction performAction) throws Exception {
+    doTest(performAction, getTestName(true));
+  }
+
+  protected void doTest(final PerformAction performAction, final boolean lowercaseFirstLetter) throws Exception {
+    doTest(performAction, getTestName(lowercaseFirstLetter));
+  }
+
+  protected void doTest(final PerformAction performAction, final String testName) throws Exception {
+    String path = getTestDataPath() + getTestRoot() + testName;
+
+    String pathBefore = path + "/before";
+    final VirtualFile rootDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, pathBefore, myFilesToDelete, false);
+    prepareProject(rootDir);
+    PsiDocumentManager.getInstance(myProject).commitAllDocuments();
+
+    String pathAfter = path + "/after";
+    final VirtualFile rootAfter = LocalFileSystem.getInstance().findFileByPath(pathAfter.replace(File.separatorChar, '/'));
+
+    performAction.performAction(rootDir, rootAfter);
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      public void run() {
+        myProject.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
+      }
+    });
+
+    FileDocumentManager.getInstance().saveAllDocuments();
+
+    if (myDoCompare) {
+      PlatformTestUtil.assertDirectoriesEqual(rootAfter, rootDir, PlatformTestUtil.CVS_FILE_FILTER);
+    }
+  }
+
+  protected void prepareProject(VirtualFile rootDir) {
+    PsiTestUtil.addSourceContentToRoots(myModule, rootDir);
+  }
+
+  @Override
+  @NonNls
+  protected abstract String getTestRoot();
+
+  protected interface PerformAction {
+    void performAction(VirtualFile rootDir, VirtualFile rootAfter) throws Exception;
+  }
+
+  @Override
+  protected boolean isRunInWriteAction() {
+    return false;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java
new file mode 100644
index 0000000..bc6b747
--- /dev/null
+++ b/java/testFramework/src/com/intellij/refactoring/move/moveMembers/MockMoveMembersOptions.java
@@ -0,0 +1,64 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.refactoring.move.moveMembers;
+
+import com.intellij.psi.PsiMember;
+import com.intellij.psi.PsiModifier;
+import org.jetbrains.annotations.Nullable;
+
+import java.util.Collection;
+
+/**
+ * @author dyoma
+ */
+public class MockMoveMembersOptions implements MoveMembersOptions {
+  private final PsiMember[] mySelectedMembers;
+  private final String myTargetClassName;
+  private String myMemberVisibility = PsiModifier.PUBLIC;
+
+  public MockMoveMembersOptions(String targetClassName, PsiMember[] selectedMembers) {
+    mySelectedMembers = selectedMembers;
+    myTargetClassName = targetClassName;
+  }
+
+  public MockMoveMembersOptions(String targetClassName, Collection<PsiMember> memberSet) {
+    this(targetClassName, memberSet.toArray(new PsiMember[memberSet.size()]));
+  }
+
+  @Override
+  public String getMemberVisibility() {
+    return myMemberVisibility;
+  }
+
+  @Override
+  public boolean makeEnumConstant() {
+    return true;
+  }
+
+  public void setMemberVisibility(@Nullable String visibility) {
+    myMemberVisibility = visibility;
+  }
+
+  @Override
+  public PsiMember[] getSelectedMembers() {
+    return mySelectedMembers;
+  }
+
+  @Override
+  public String getTargetClassName() {
+    return myTargetClassName;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java
new file mode 100644
index 0000000..a50e044
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/EditorActionTestCase.java
@@ -0,0 +1,104 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework;
+
+import com.intellij.ide.DataManager;
+import com.intellij.openapi.actionSystem.ActionManager;
+import com.intellij.openapi.actionSystem.AnAction;
+import com.intellij.openapi.actionSystem.AnActionEvent;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.psi.PsiDocumentManager;
+
+import java.io.IOException;
+
+/**
+ * A TestCase for testing some action in editor
+ */
+public abstract class EditorActionTestCase extends LightCodeInsightTestCase {
+  /**
+   * @return id of the action to be tested.
+   */
+  protected abstract String getActionId();
+
+  /**
+   * Perform action test using text before and after action perform. Useas &lt;caret&gt; marker where caret should be
+   * placed when file is loaded in editor and &lt;selection&gt;&lt;/selection&gt; denoting selection bounds.
+   * @param fileName name of the file. Mostly used to create proper instance of the PsiFile
+   * @param textBefore text with markers before action
+   * @param textAfter expected text with markers after action
+   * @throws IOException
+   */
+  protected void doTextTest(String fileName, String textBefore, String textAfter) throws IOException {
+    doTextTest(fileName, textBefore, textAfter, false);
+  }
+
+  /**
+   * Perform action test using text before and after action perform. Uses &lt;caret&gt; marker where caret should be
+   * placed when file is loaded in editor and &lt;selection&gt;&lt;/selection&gt; denoting selection bounds.
+   * @param fileName  name of the file. Mostly used to create proper instance of the PsiFile
+   * @param textBefore  text with markers before action
+   * @param textAfter  expected text with markers after action
+   * @param ignoreTrailingSpaces  true if trailing spaces should be ignored.
+   * @throws IOException
+   */
+  protected void doTextTest(String fileName, String textBefore, String textAfter, boolean ignoreTrailingSpaces) throws IOException {
+    configureFromFileText(fileName, textBefore);
+    invokeAction();
+    PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
+    assertEquals("Reparse error!", myEditor.getDocument().getText(), myFile.getText());
+    checkResultByText(null, textAfter, ignoreTrailingSpaces);
+  }
+
+  /**
+   * Same as doTextTest but texts are retrieved from the data files.
+   * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @throws Exception
+   */
+  protected void doFileTest(String filePathBefore, String filePathAfter) throws Exception {
+    doFileTest(filePathBefore, filePathAfter, false);
+  }
+
+  /**
+   * Same as doTextTest but texts are retrieved from the data files.
+   * @param filePathBefore source file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @param filePathAfter expected file's relative path from %IDEA_INSTALLATION_HOME%/testData/
+   * @param ignoreTrailingSpaces  true if trailing spaces should be ignored.
+   * @throws Exception
+   */
+  protected void doFileTest(String filePathBefore, String filePathAfter, boolean ignoreTrailingSpaces) throws Exception {
+    configureByFile(filePathBefore);
+    invokeAction();
+    checkResultByFile(null, filePathAfter, ignoreTrailingSpaces);
+  }
+
+  private void invokeAction() {
+    final String actionId = getActionId();
+    final AnAction action = ActionManager.getInstance().getAction(actionId);
+    //noinspection HardCodedStringLiteral
+    assertNotNull("Can find registered action with id=" + actionId, action);
+    action.actionPerformed(
+        new AnActionEvent(
+            null,
+            DataManager.getInstance().getDataContext(),
+            "",
+            action.getTemplatePresentation(),
+            ActionManager.getInstance(),
+            0
+        )
+    );
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java
new file mode 100644
index 0000000..93e357c
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestCase.java
@@ -0,0 +1,77 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.vfs.impl.VirtualFilePointerManagerImpl;
+import com.intellij.openapi.vfs.pointers.VirtualFilePointerManager;
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+import java.util.Arrays;
+import java.util.Comparator;
+
+/**
+ * @author mike
+ */
+public abstract class IdeaTestCase extends PlatformTestCase {
+  protected JavaPsiFacadeEx myJavaFacade;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myJavaFacade = JavaPsiFacadeEx.getInstanceEx(myProject);
+    VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
+    filePointerManager.storePointers();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    myJavaFacade = null;
+    super.tearDown();
+    VirtualFilePointerManagerImpl filePointerManager = (VirtualFilePointerManagerImpl)VirtualFilePointerManager.getInstance();
+    filePointerManager.assertPointersAreDisposed();
+  }
+
+  public final JavaPsiFacadeEx getJavaFacade() {
+    return myJavaFacade;
+  }
+
+  @Override
+  protected Sdk getTestProjectJdk() {
+    return IdeaTestUtil.getMockJdk17();
+  }
+
+  @Override
+  protected ModuleType getModuleType() {
+    return StdModuleTypes.JAVA;
+  }
+
+  public static void initPlatformPrefix() {
+    initPlatformPrefix("com.intellij.idea.IdeaUltimateApplication", "Idea");
+  }
+
+  protected static void sortClassesByName(final PsiClass[] classes) {
+    Arrays.sort(classes, new Comparator<PsiClass>() {
+      @Override
+      public int compare(PsiClass o1, PsiClass o2) {
+        return o1.getName().compareTo(o2.getName());
+      }
+    });
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java
new file mode 100644
index 0000000..0f94f6a
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/IdeaTestUtil.java
@@ -0,0 +1,112 @@
+/*
+ * 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.testFramework;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.SdkModificator;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+public class IdeaTestUtil extends PlatformTestUtil {
+  public static void main(String[] args) {
+    printDetectedPerformanceTimings();
+  }
+
+  @SuppressWarnings({"UseOfSystemOutOrSystemErr"})
+  public static void printDetectedPerformanceTimings() {
+    System.out.println(Timings.getStatistics());
+  }
+
+  public static void withLevel(final Module module, final LanguageLevel level, final Runnable r) {
+    final LanguageLevelProjectExtension projectExt = LanguageLevelProjectExtension.getInstance(module.getProject());
+
+    final LanguageLevel projectLevel = projectExt.getLanguageLevel();
+    final LanguageLevel moduleLevel = LanguageLevelModuleExtension.getInstance(module).getLanguageLevel();
+    try {
+      projectExt.setLanguageLevel(level);
+      setModuleLanguageLevel(module, level);
+      r.run();
+    }
+    finally {
+      setModuleLanguageLevel(module, moduleLevel);
+      projectExt.setLanguageLevel(projectLevel);
+    }
+  }
+
+  public static void setModuleLanguageLevel(Module module, final LanguageLevel level) {
+    final LanguageLevelModuleExtension modifiable = (LanguageLevelModuleExtension)LanguageLevelModuleExtension.getInstance(module).getModifiableModel(true);
+    modifiable.setLanguageLevel(level);
+    modifiable.commit();
+  }
+
+  public static Sdk getMockJdk17() {
+    return getMockJdk17("java 1.7");
+  }
+
+  public static Sdk getMockJdk17(@NotNull String name) {
+    return JavaSdk.getInstance().createJdk(name, getMockJdk17Path().getPath(), false);
+  }
+
+  public static Sdk getMockJdk14() {
+    return JavaSdk.getInstance().createJdk("java 1.4", getMockJdk14Path().getPath(), false);
+  }
+
+  public static File getMockJdk14Path() {
+    return getPathForJdkNamed("mockJDK-1.4");
+  }
+
+  public static File getMockJdk17Path() {
+    return getPathForJdkNamed("mockJDK-1.7");
+  }
+
+  private static File getPathForJdkNamed(String name) {
+    File mockJdkCEPath = new File(PathManager.getHomePath(), "java/" + name);
+    return mockJdkCEPath.exists() ? mockJdkCEPath : new File(PathManager.getHomePath(), "community/java/" + name);
+  }
+
+  public static Sdk getWebMockJdk17() {
+    Sdk jdk = getMockJdk17();
+    addWebJarsTo(jdk);
+    return jdk;
+  }
+
+  public static void addWebJarsTo(@NotNull Sdk jdk) {
+    SdkModificator sdkModificator = jdk.getSdkModificator();
+    sdkModificator.addRoot(findJar("lib/jsp-api.jar"), OrderRootType.CLASSES);
+    sdkModificator.addRoot(findJar("lib/servlet-api.jar"), OrderRootType.CLASSES);
+    sdkModificator.commitChanges();
+  }
+
+  private static VirtualFile findJar(String name) {
+    String path = PathManager.getHomePath() + '/' + name;
+    VirtualFile file = LocalFileSystem.getInstance().findFileByPath(path);
+    assert file != null : "not found: " + path;
+    VirtualFile jar = JarFileSystem.getInstance().getJarRootForLocalFile(file);
+    assert jar != null : "no .jar for: " + path;
+    return jar;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java
new file mode 100644
index 0000000..a93ea6b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/InspectionTestCase.java
@@ -0,0 +1,235 @@
+/*
+ * 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.testFramework;
+
+import com.intellij.ExtensionPoints;
+import com.intellij.analysis.AnalysisScope;
+import com.intellij.codeInspection.GlobalInspectionTool;
+import com.intellij.codeInspection.InspectionManager;
+import com.intellij.codeInspection.LocalInspectionTool;
+import com.intellij.codeInspection.deadCode.UnusedDeclarationInspection;
+import com.intellij.codeInspection.ex.*;
+import com.intellij.codeInspection.reference.EntryPoint;
+import com.intellij.codeInspection.reference.RefElement;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.extensions.ExtensionPoint;
+import com.intellij.openapi.extensions.Extensions;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.PsiManager;
+import com.intellij.psi.util.PsiUtilCore;
+import com.intellij.testFramework.fixtures.impl.CodeInsightTestFixtureImpl;
+import com.intellij.util.ArrayUtil;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author max
+ * @since Apr 11, 2002
+ */
+@SuppressWarnings({"HardCodedStringLiteral"})
+public abstract class InspectionTestCase extends PsiTestCase {
+  private static final Logger LOG = Logger.getInstance("#com.intellij.testFramework.InspectionTestCase");
+  private EntryPoint myUnusedCodeExtension;
+  private VirtualFile ext_src;
+
+  public InspectionManagerEx getManager() {
+    return (InspectionManagerEx)InspectionManager.getInstance(myProject);
+  }
+
+  public void doTest(@NonNls String folderName, LocalInspectionTool tool) {
+    doTest(folderName, new LocalInspectionToolWrapper(tool));
+  }
+
+  public void doTest(@NonNls String folderName, GlobalInspectionTool tool) {
+    doTest(folderName, new GlobalInspectionToolWrapper(tool));
+  }
+
+  public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange) {
+    doTest(folderName, new GlobalInspectionToolWrapper(tool), checkRange);
+  }
+
+  public void doTest(@NonNls String folderName, GlobalInspectionTool tool, boolean checkRange, boolean runDeadCodeFirst) {
+    doTest(folderName, new GlobalInspectionToolWrapper(tool), "java 1.4", checkRange, runDeadCodeFirst);
+  }
+
+  public void doTest(@NonNls String folderName, InspectionTool tool) {
+    doTest(folderName, tool, "java 1.4");
+  }
+
+  public void doTest(@NonNls String folderName, InspectionTool tool, final boolean checkRange) {
+    doTest(folderName, tool, "java 1.4", checkRange);
+  }
+
+  public void doTest(@NonNls String folderName, LocalInspectionTool tool, @NonNls final String jdkName) {
+    doTest(folderName, new LocalInspectionToolWrapper(tool), jdkName);
+  }
+
+  public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName) {
+    doTest(folderName, tool, jdkName, false);
+  }
+
+  public void doTest(@NonNls String folderName, InspectionTool tool, @NonNls final String jdkName, boolean checkRange) {
+    doTest(folderName, tool, jdkName, checkRange, false);
+  }
+
+  public void doTest(@NonNls String folderName,
+                     InspectionTool tool,
+                     @NonNls final String jdkName,
+                     boolean checkRange,
+                     boolean runDeadCodeFirst,
+                     InspectionTool... additional) {
+    final String testDir = getTestDataPath() + "/" + folderName;
+    runTool(testDir, jdkName, runDeadCodeFirst, tool, additional);
+
+    InspectionTestUtil.compareToolResults(tool, checkRange, testDir);
+  }
+
+  protected void runTool(@NonNls final String testDir, @NonNls final String jdkName, final InspectionTool tool) {
+    runTool(testDir, jdkName, false, tool);
+  }
+
+  protected void runTool(final String testDir,
+                         final String jdkName,
+                         boolean runDeadCodeFirst,
+                         final InspectionTool tool,
+                         InspectionTool... additional) {
+    final VirtualFile[] sourceDir = new VirtualFile[1];
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        try {
+          setupRootModel(testDir, sourceDir, jdkName);
+        }
+        catch (Exception e) {
+          LOG.error(e);
+        }
+      }
+    });
+    AnalysisScope scope = createAnalysisScope(sourceDir[0].getParent());
+
+    InspectionManagerEx inspectionManager = (InspectionManagerEx)InspectionManager.getInstance(getProject());
+    InspectionTool[] tools = runDeadCodeFirst ? new InspectionTool[]{new UnusedDeclarationInspection(), tool} : new InspectionTool[]{tool};
+    tools = ArrayUtil.mergeArrays(tools, additional);
+    final GlobalInspectionContextImpl globalContext =
+      CodeInsightTestFixtureImpl.createGlobalContextForTool(scope, getProject(), inspectionManager, tools);
+
+    InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
+  }
+
+  protected AnalysisScope createAnalysisScope(VirtualFile sourceDir) {
+    PsiManager psiManager = PsiManager.getInstance(myProject);
+    return new AnalysisScope(psiManager.findDirectory(sourceDir));
+  }
+
+  protected void setupRootModel(final String testDir, final VirtualFile[] sourceDir, final String sdkName) {
+    VirtualFile projectDir = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir));
+    assertNotNull("could not find project dir " + testDir, projectDir);
+    sourceDir[0] = projectDir.findChild("src");
+    if (sourceDir[0] == null) {
+      sourceDir[0] = projectDir;
+    }
+    // IMPORTANT! The jdk must be obtained in a way it is obtained in the normal program!
+    //ProjectJdkEx jdk = ProjectJdkTable.getInstance().getInternalJdk();
+    PsiTestUtil.removeAllRoots(myModule, getTestProjectSdk());
+    PsiTestUtil.addContentRoot(myModule, projectDir);
+    PsiTestUtil.addSourceRoot(myModule, sourceDir[0]);
+    ext_src = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(new File(testDir + "/ext_src"));
+    if (ext_src != null) {
+      PsiTestUtil.addSourceRoot(myModule, ext_src);
+    }
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
+    myUnusedCodeExtension = new EntryPoint() {
+      @NotNull
+      @Override
+      public String getDisplayName() {
+        return "duh";
+      }
+
+      @Override
+      public boolean isEntryPoint(RefElement refElement, PsiElement psiElement) {
+        return isEntryPoint(psiElement);
+      }
+
+      @Override
+      public boolean isEntryPoint(PsiElement psiElement) {
+        return ext_src != null && VfsUtilCore.isAncestor(ext_src, PsiUtilCore.getVirtualFile(psiElement), false);
+      }
+
+      @Override
+      public boolean isSelected() {
+        return false;
+      }
+
+      @Override
+      public void setSelected(boolean selected) {
+
+      }
+
+      @Override
+      public void readExternal(Element element) {
+
+      }
+
+      @Override
+      public void writeExternal(Element element) {
+
+      }
+    };
+
+    point.registerExtension(myUnusedCodeExtension);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    ExtensionPoint<EntryPoint> point = Extensions.getRootArea().getExtensionPoint(ExtensionPoints.DEAD_CODE_TOOL);
+    point.unregisterExtension(myUnusedCodeExtension);
+    myUnusedCodeExtension = null;
+    ext_src = null;
+    super.tearDown();
+  }
+
+  @Override
+  protected void setUpJdk() {
+  }
+
+  protected Sdk getTestProjectSdk() {
+    Sdk sdk = IdeaTestUtil.getMockJdk17();
+    LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(LanguageLevel.JDK_1_5);
+    return sdk;
+  }
+
+  @Override
+  @NonNls
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath() + "/inspection/";
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java b/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java
new file mode 100644
index 0000000..0ecf5ff
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/LightCodeInsightTestCase.java
@@ -0,0 +1,70 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.LanguageLevelProjectExtension;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+/**
+ * A TestCase for single PsiFile being opened in Editor conversion. See configureXXX and checkResultXXX method docs.
+ */
+public abstract class LightCodeInsightTestCase extends LightPlatformCodeInsightTestCase {
+  private LanguageLevel myOldLanguageLevel;
+
+  @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+  protected LightCodeInsightTestCase() {
+    IdeaTestCase.initPlatformPrefix();
+  }
+
+  public static JavaPsiFacadeEx getJavaFacade() {
+    return JavaPsiFacadeEx.getInstanceEx(ourProject);
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myOldLanguageLevel = LanguageLevelProjectExtension.getInstance(getProject()).getLanguageLevel();
+    setLanguageLevel(getLanguageLevel());
+  }
+
+  protected LanguageLevel getLanguageLevel() {
+    return LanguageLevel.HIGHEST;
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    setLanguageLevel(myOldLanguageLevel);
+    super.tearDown();
+  }
+
+  protected static void setLanguageLevel(final LanguageLevel level) {
+    LanguageLevelProjectExtension.getInstance(getProject()).setLanguageLevel(level);
+  }
+
+  @Override
+  protected Sdk getProjectJDK() {
+    return IdeaTestUtil.getMockJdk17();
+  }
+
+  @Override
+  protected ModuleType getModuleType() {
+    return StdModuleTypes.JAVA;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java b/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java
new file mode 100644
index 0000000..8da3a59
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/LightIdeaTestCase.java
@@ -0,0 +1,52 @@
+/*
+ * 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.testFramework;
+
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.JavaSdkImpl;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+
+/**
+ * A test case that provides IDEA application and project. Note both are reused for each test run in the session so
+ * be careful to return all the modification made to application and project components (such as settings) after
+ * test is finished so other test aren't affected. The project is initialized with single module that have single
+ * content and source entry. For your convenience the project may be equipped with some mock JDK so your tests may
+ * refer to external classes. In order to enable this feature you have to have a folder named "mockJDK" under
+ * idea installation home that is used for test running. Place src.zip under that folder. We'd suggest this is real mock
+ * so it contains classes that is really needed in order to speed up tests startup.
+ */
+public abstract class LightIdeaTestCase extends LightPlatformTestCase {
+  @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
+  public LightIdeaTestCase() {
+    IdeaTestCase.initPlatformPrefix();
+  }
+
+  public static JavaPsiFacadeEx getJavaFacade() {
+    return JavaPsiFacadeEx.getInstanceEx(ourProject);
+  }
+
+  @Override
+  protected Sdk getProjectJDK() {
+    return IdeaTestUtil.getMockJdk17();
+  }
+
+  @Override
+  protected ModuleType getModuleType() {
+    return StdModuleTypes.JAVA;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
new file mode 100644
index 0000000..e91b5ff
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/ModuleTestCase.java
@@ -0,0 +1,177 @@
+/*
+ * 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.testFramework;
+
+import com.intellij.ide.highlighter.ModuleFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleManager;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.module.impl.ModuleImpl;
+import com.intellij.openapi.project.impl.ProjectImpl;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.impl.ModuleRootManagerImpl;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.Ref;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtilCore;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.openapi.vfs.VirtualFileVisitor;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.ArrayList;
+import java.util.Collection;
+
+public abstract class ModuleTestCase extends IdeaTestCase {
+  protected final Collection<Module> myModulesToDispose = new ArrayList<Module>();
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myModulesToDispose.clear();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    try {
+      final ModuleManager moduleManager = ModuleManager.getInstance(myProject);
+      ApplicationManager.getApplication().runWriteAction(new Runnable() {
+        @Override
+        public void run() {
+          for (Module module : myModulesToDispose) {
+            String moduleName = module.getName();
+            if (moduleManager.findModuleByName(moduleName) != null) {
+              moduleManager.disposeModule(module);
+            }
+          }
+        }
+      });
+    }
+    finally {
+      myModulesToDispose.clear();
+      super.tearDown();
+    }
+  }
+
+  protected Module createModule(final File moduleFile) {
+    return createModule(moduleFile, StdModuleTypes.JAVA);
+  }
+
+  protected Module createModule(final File moduleFile, final ModuleType moduleType) {
+    final String path = moduleFile.getAbsolutePath();
+    return createModule(path, moduleType);
+  }
+
+  protected Module createModule(final String path, final ModuleType moduleType) {
+    Module module = ApplicationManager.getApplication().runWriteAction(
+      new Computable<Module>() {
+        @Override
+        public Module compute() {
+          return ModuleManager.getInstance(myProject).newModule(path, moduleType.getId());
+        }
+      }
+    );
+
+    myModulesToDispose.add(module);
+    return module;
+  }
+
+  protected Module loadModule(final File moduleFile) {
+    Module module = ApplicationManager.getApplication().runWriteAction(
+      new Computable<Module>() {
+        @Override
+        public Module compute() {
+          try {
+            return ModuleManager.getInstance(myProject).loadModule(moduleFile.getAbsolutePath());
+          }
+          catch (Exception e) {
+            LOG.error(e);
+            return null;
+          }
+        }
+      }
+    );
+
+    myModulesToDispose.add(module);
+    return module;
+  }
+
+  protected Module loadModule(final String modulePath) {
+    return loadModule(new File(modulePath));
+  }
+
+  @Nullable
+  protected Module loadAllModulesUnder(@NotNull VirtualFile rootDir) throws Exception {
+    final Ref<Module> result = Ref.create();
+
+    VfsUtilCore.visitChildrenRecursively(rootDir, new VirtualFileVisitor() {
+      @Override
+      public boolean visitFile(@NotNull VirtualFile file) {
+        if (!file.isDirectory() && file.getName().endsWith(ModuleFileType.DOT_DEFAULT_EXTENSION)) {
+          ModuleImpl module = (ModuleImpl)loadModule(new File(file.getPath()));
+          readJdomExternalizables(module);
+          result.setIfNull(module);
+        }
+        return true;
+      }
+    });
+
+    return result.get();
+  }
+
+  protected void readJdomExternalizables(final ModuleImpl module) {
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+      @Override
+      public void run() {
+        final ProjectImpl project = (ProjectImpl)myProject;
+        project.setOptimiseTestLoadSpeed(false);
+        final ModuleRootManagerImpl moduleRootManager = (ModuleRootManagerImpl)ModuleRootManager.getInstance(module);
+        module.getStateStore().initComponent(moduleRootManager, false);
+        project.setOptimiseTestLoadSpeed(true);
+      }
+    });
+  }
+
+  protected Module createModuleFromTestData(final String dirInTestData, final String newModuleFileName, final ModuleType moduleType,
+                                            final boolean addSourceRoot)
+    throws IOException {
+    final File dirInTestDataFile = new File(dirInTestData);
+    assertTrue(dirInTestDataFile.isDirectory());
+    final File moduleDir = createTempDirectory();
+    FileUtil.copyDir(dirInTestDataFile, moduleDir);
+    final Module module = createModule(moduleDir + "/" + newModuleFileName, moduleType);
+    final VirtualFile root = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(moduleDir);
+    new WriteCommandAction.Simple(module.getProject()) {
+      @Override
+      protected void run() throws Throwable {
+        root.refresh(false, true);
+      }
+    }.execute().throwException();
+    if (addSourceRoot) {
+      PsiTestUtil.addSourceContentToRoots(module, root);
+    }
+    else {
+      PsiTestUtil.addContentRoot(module, root);
+    }
+    return module;
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
new file mode 100644
index 0000000..63bbdb2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/PsiTestCase.java
@@ -0,0 +1,241 @@
+/*
+ * 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.testFramework;
+
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.application.WriteAction;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.fileEditor.FileDocumentManager;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.fileTypes.FileTypeRegistry;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.roots.ModuleRootManager;
+import com.intellij.openapi.roots.ModuleRootModificationUtil;
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.openapi.util.DefaultJDOMExternalizer;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.PsiManagerImpl;
+import com.intellij.util.IncorrectOperationException;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.io.IOException;
+import java.util.List;
+import java.util.StringTokenizer;
+
+/**
+ * @author Mike
+ */
+public abstract class PsiTestCase extends ModuleTestCase {
+  protected PsiManagerImpl myPsiManager;
+  protected PsiFile myFile;
+  protected PsiTestData myTestDataBefore;
+  protected PsiTestData myTestDataAfter;
+  private String myDataRoot;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myPsiManager = (PsiManagerImpl) PsiManager.getInstance(myProject);
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    myPsiManager = null;
+    myFile = null;
+    myTestDataBefore = null;
+    myTestDataAfter = null;
+    super.tearDown();
+  }
+
+  protected PsiFile createDummyFile(String fileName, String text) throws IncorrectOperationException {
+    FileType type = FileTypeRegistry.getInstance().getFileTypeByFileName(fileName);
+    return PsiFileFactory.getInstance(myProject).createFileFromText(fileName, type, text);
+  }
+
+  protected PsiFile createFile(@NonNls String fileName, String text) throws Exception {
+    return createFile(myModule, fileName, text);
+  }
+  protected PsiFile createFile(Module module, String fileName, String text) throws Exception {
+    File dir = createTempDirectory();
+    VirtualFile vDir = LocalFileSystem.getInstance().refreshAndFindFileByPath(dir.getCanonicalPath().replace(File.separatorChar, '/'));
+
+    return createFile(module, vDir, fileName, text);
+  }
+
+  protected PsiFile createFile(final Module module, final VirtualFile vDir, final String fileName, final String text) throws IOException {
+    return new WriteAction<PsiFile>() {
+      @Override
+      protected void run(Result<PsiFile> result) throws Throwable {
+        if (!ModuleRootManager.getInstance(module).getFileIndex().isInSourceContent(vDir)) {
+          addSourceContentToRoots(module, vDir);
+        }
+
+        final VirtualFile vFile = vDir.createChildData(vDir, fileName);
+        VfsUtil.saveText(vFile, text);
+        assertNotNull(vFile);
+        final PsiFile file = myPsiManager.findFile(vFile);
+        assertNotNull(file);
+        result.setResult(file);
+      }
+    }.execute().getResultObject();
+  }
+
+  protected void addSourceContentToRoots(final Module module, final VirtualFile vDir) {
+    PsiTestUtil.addSourceContentToRoots(module, vDir);
+  }
+
+  protected PsiElement configureByFileWithMarker(String filePath, String marker) throws Exception{
+    final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(filePath.replace(File.separatorChar, '/'));
+    assertNotNull("file " + filePath + " not found", vFile);
+
+    String fileText = VfsUtil.loadText(vFile);
+    fileText = StringUtil.convertLineSeparators(fileText);
+
+    int offset = fileText.indexOf(marker);
+    assertTrue(offset >= 0);
+    fileText = fileText.substring(0, offset) + fileText.substring(offset + marker.length());
+
+    myFile = createFile(vFile.getName(), fileText);
+
+    return myFile.findElementAt(offset);
+  }
+
+  protected void configure(String path, String dataName) throws Exception {
+    myDataRoot = getTestDataPath() + path;
+
+    myTestDataBefore = loadData(dataName);
+
+    PsiTestUtil.removeAllRoots(myModule, IdeaTestUtil.getMockJdk17());
+    VirtualFile vDir = PsiTestUtil.createTestProjectStructure(myProject, myModule, myDataRoot, myFilesToDelete);
+
+    final VirtualFile vFile = vDir.findChild(myTestDataBefore.getTextFile());
+    myFile = myPsiManager.findFile(vFile);
+  }
+
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath();
+  }
+
+  protected String loadFile(String name) throws Exception {
+    String result = FileUtil.loadFile(new File(getTestDataPath() + File.separatorChar + name));
+    return StringUtil.convertLineSeparators(result);
+  }
+
+  private PsiTestData loadData(String dataName) throws Exception {
+    Document document = JDOMUtil.loadDocument(new File(myDataRoot + "/" + "data.xml"));
+
+    PsiTestData data = createData();
+    Element documentElement = document.getRootElement();
+
+    final List nodes = documentElement.getChildren("data");
+
+    for (Object node1 : nodes) {
+      Element node = (Element)node1;
+      String value = node.getAttributeValue("name");
+
+      if (value.equals(dataName)) {
+        DefaultJDOMExternalizer.readExternal(data, node);
+        data.loadText(myDataRoot);
+
+        return data;
+      }
+    }
+
+    throw new IllegalArgumentException("Cannot find data chunk '" + dataName + "'");
+  }
+
+  protected PsiTestData createData() {
+    return new PsiTestData();
+  }
+
+  protected void checkResult(String dataName) throws Exception {
+    myTestDataAfter = loadData(dataName);
+
+    final String textExpected = myTestDataAfter.getText();
+    final String actualText = myFile.getText();
+
+    if (!textExpected.equals(actualText)) {
+      System.out.println("Text mismatch: " + getName() + "(" + getClass().getName() + ")");
+      System.out.println("Text expected:");
+      printText(textExpected);
+      System.out.println("Text found:");
+      printText(actualText);
+
+      fail("text");
+    }
+
+//    assertEquals(myTestDataAfter.getText(), myFile.getText());
+  }
+
+  protected static void printText(String text) {
+    final String q = "\"";
+    System.out.print(q);
+
+    text = StringUtil.convertLineSeparators(text);
+
+    StringTokenizer tokenizer = new StringTokenizer(text, "\n", true);
+    while (tokenizer.hasMoreTokens()) {
+      final String token = tokenizer.nextToken();
+
+      if (token.equals("\n")) {
+        System.out.print(q);
+        System.out.println();
+        System.out.print(q);
+        continue;
+      }
+
+      System.out.print(token);
+    }
+
+    System.out.print(q);
+    System.out.println();
+  }
+
+  protected void addLibraryToRoots(final VirtualFile jarFile, OrderRootType rootType) {
+    addLibraryToRoots(myModule, jarFile, rootType);
+  }
+
+  protected static void addLibraryToRoots(final Module module, final VirtualFile root, final OrderRootType rootType) {
+    assertEquals(OrderRootType.CLASSES, rootType);
+    ModuleRootModificationUtil.addModuleLibrary(module, root.getUrl());
+  }
+
+
+  public PsiFile getFile() {
+    return myFile;
+  }
+
+  public com.intellij.openapi.editor.Document getDocument(PsiFile file) {
+    return PsiDocumentManager.getInstance(getProject()).getDocument(file);
+  }
+
+  public com.intellij.openapi.editor.Document getDocument(VirtualFile file) {
+    return FileDocumentManager.getInstance().getDocument(file);
+  }
+
+  public void commitDocument(com.intellij.openapi.editor.Document document) {
+    PsiDocumentManager.getInstance(getProject()).commitDocument(document);
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/PsiTestData.java b/java/testFramework/src/com/intellij/testFramework/PsiTestData.java
new file mode 100644
index 0000000..2691de2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/PsiTestData.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.testFramework;
+
+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 com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.util.text.StringUtil;
+import org.jdom.Element;
+
+import java.io.File;
+import java.io.IOException;
+
+/**
+ * @author Mike
+ */
+public class PsiTestData implements JDOMExternalizable {
+  public String TEXT_FILE = "";
+  private String myText;
+
+  public String getTextFile() {
+    return TEXT_FILE;
+  }
+
+  public String getText() {
+    return myText;
+  }
+
+  public void loadText(String root) throws IOException{
+    String fileName = root + "/" + TEXT_FILE;
+    myText = FileUtil.loadFile(new File(fileName));
+    myText = StringUtil.convertLineSeparators(myText);
+  }
+
+  @Override
+  public void readExternal(Element element) throws InvalidDataException {
+    DefaultJDOMExternalizer.readExternal(this, element);
+  }
+
+  @Override
+  public void writeExternal(Element element) throws WriteExternalException {
+    DefaultJDOMExternalizer.writeExternal(this, element);
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.java
new file mode 100644
index 0000000..e2cebe4
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/ResolveTestCase.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.testFramework;
+
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.text.StringUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VfsUtil;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiReference;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+
+public abstract class ResolveTestCase extends PsiTestCase {
+  @NonNls protected static final String MARKER = "<ref>";
+
+  protected PsiReference configureByFile(@NonNls String filePath) throws Exception{
+    return configureByFile(filePath, null);
+  }
+  
+  protected PsiReference configureByFile(@TestDataFile @NonNls String filePath, @Nullable VirtualFile parentDir) throws Exception{
+    final String fullPath = getTestDataPath() + filePath;
+    final VirtualFile vFile = LocalFileSystem.getInstance().findFileByPath(fullPath.replace(File.separatorChar, '/'));
+    assertNotNull("file " + filePath + " not found", vFile);
+
+    String fileText = StringUtil.convertLineSeparators(VfsUtil.loadText(vFile));
+
+    final String fileName = vFile.getName();
+
+    return configureByFileText(fileText, fileName, parentDir);
+  }
+
+  protected PsiReference configureByFileText(String fileText, String fileName) throws Exception {
+    return configureByFileText(fileText, fileName, null);
+  }
+  
+  protected PsiReference configureByFileText(String fileText, String fileName, @Nullable final VirtualFile parentDir) throws Exception {
+    int offset = fileText.indexOf(MARKER);
+    assertTrue(offset >= 0);
+    fileText = fileText.substring(0, offset) + fileText.substring(offset + MARKER.length());
+
+    myFile = parentDir == null? createFile(myModule, fileName, fileText) : createFile(myModule, parentDir, fileName, fileText);
+    PsiReference ref = myFile.findReferenceAt(offset);
+
+    assertNotNull(ref);
+
+    return ref;
+  }
+
+  @Override
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath() + "/psi/resolve/";
+  }
+}
\ No newline at end of file
diff --git a/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java b/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java
new file mode 100644
index 0000000..377de5d
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/TestSourceBasedTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework;
+
+import com.intellij.ide.highlighter.ProjectFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.application.ex.PathManagerEx;
+import com.intellij.openapi.util.io.FileUtil;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.PsiDirectory;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+@SuppressWarnings({"HardCodedStringLiteral", "ConstantConditions", "JUnitTestCaseInProductSource"})
+@NonNls public abstract class TestSourceBasedTestCase extends IdeaTestCase {
+  private File myTempDirectory;
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+    myTempDirectory = FileUtil.createTempDirectory(getTestName(true), "test",false);
+    myFilesToDelete.add(myTempDirectory);
+    final File testRoot = new File(getTestDataPath(), getTestPath());
+    assertTrue(testRoot.getAbsolutePath(), testRoot.isDirectory());
+
+    final File currentTestRoot = new File(testRoot, getTestDirectoryName());
+    assertTrue(currentTestRoot.getAbsolutePath(), currentTestRoot.isDirectory());
+
+    FileUtil.copyDir(currentTestRoot, new File(myTempDirectory, getTestDirectoryName()));
+
+    ApplicationManager.getApplication().runWriteAction(new Runnable() {
+                                                             @Override
+                                                             public void run() {
+                                                               setupContentRoot();
+                                                             }
+                                                           });
+
+  }
+
+  protected String getTestDataPath() {
+    return PathManagerEx.getTestDataPath(getClass());
+  }
+
+  protected abstract String getTestPath();
+
+  private File getTestContentFile() {
+    return new File(myTempDirectory, getTestDirectoryName());
+  }
+
+  private void setupContentRoot() {
+    PsiTestUtil.addContentRoot(myModule, getContentRoot());
+    VirtualFile src = getContentRoot().findChild("src");
+    if (src != null) {
+      PsiTestUtil.addSourceRoot(myModule, src);
+    }
+  }
+
+  protected VirtualFile getContentRoot() {
+    File file = getTestContentFile();
+    return LocalFileSystem.getInstance().refreshAndFindFileByIoFile(file);
+  }
+
+  @Override
+  protected String getTestDirectoryName() {
+    return getTestName(true);
+  }
+
+
+  protected PsiDirectory getPackageDirectory(final String packageRelativePath) {
+    return getPsiManager().findDirectory(getContentRoot().findFileByRelativePath("src/" + packageRelativePath));
+  }
+
+  protected PsiDirectory getSrcDirectory() {
+    return getPsiManager().findDirectory(getContentRoot().findFileByRelativePath("src"));
+  }
+
+  protected PsiDirectory getContentDirectory() {
+    return getPsiManager().findDirectory(getContentRoot());
+  }
+  
+  protected String getRootFiles() {
+    return " " + myModule.getModuleFile().getName() + "\n" +
+           " " + myProject.getName() + ProjectFileType.DOT_DEFAULT_EXTENSION +
+           "\n";
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java b/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.java
new file mode 100644
index 0000000..df0b9f2
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/builders/JavaModuleFixtureBuilder.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.testFramework.builders;
+
+import com.intellij.openapi.roots.OrderRootType;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.fixtures.ModuleFixture;
+import org.jetbrains.annotations.NonNls;
+
+import java.util.Map;
+
+/**
+ * @author mike
+ */
+public interface JavaModuleFixtureBuilder<T extends ModuleFixture> extends ModuleFixtureBuilder<T> {
+
+  enum MockJdkLevel {
+    jdk14,
+    jdk15
+  }
+
+  JavaModuleFixtureBuilder setLanguageLevel(LanguageLevel languageLevel);
+
+  JavaModuleFixtureBuilder addLibrary(@NonNls String libraryName, @NonNls String... classPath);
+
+  JavaModuleFixtureBuilder addLibrary(@NonNls String libraryName, Map<OrderRootType, String[]> roots);
+
+  JavaModuleFixtureBuilder addLibraryJars(@NonNls String libraryName, @NonNls String basePath, @NonNls String... jarNames);
+
+  JavaModuleFixtureBuilder addJdk(@NonNls String jdkPath);
+
+  void setMockJdkLevel(MockJdkLevel level);
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java
new file mode 100755
index 0000000..5e6a31f
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/codeInsight/hierarchy/HierarchyViewTestBase.java
@@ -0,0 +1,155 @@
+package com.intellij.testFramework.codeInsight.hierarchy;
+
+import com.intellij.codeInsight.CodeInsightTestCase;
+import com.intellij.ide.hierarchy.HierarchyNodeDescriptor;
+import com.intellij.ide.hierarchy.HierarchyTreeStructure;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.util.JDOMUtil;
+import com.intellij.openapi.util.io.FileUtil;
+import org.jdom.Document;
+import org.jdom.Element;
+import org.jetbrains.annotations.Nullable;
+
+import java.io.File;
+import java.util.*;
+
+/**
+ * Checks tree structure for Type Hierarchy (Ctrl+H), Call Hierarchy (Ctrl+Alt+H), Method Hierarchy (Ctrl+Shift+H).
+ */
+public abstract class HierarchyViewTestBase extends CodeInsightTestCase {
+
+  private static final String NODE_ELEMENT_NAME = "node";
+  private static final String ANY_NODES_ELEMENT_NAME = "any";
+  private static final String TEXT_ATTR_NAME = "text";
+  private static final String BASE_ATTR_NAME = "base";
+
+  protected abstract String getBasePath();
+
+  protected void doHierarchyTest(final Computable<HierarchyTreeStructure> treeStructureComputable, final String... fileNames)
+    throws Exception {
+    final String[] relFilePaths = new String[fileNames.length];
+    for (int i = 0; i < fileNames.length; i++) {
+      relFilePaths[i] = "/" + getBasePath() + "/" + fileNames[i];
+    }
+    configureByFiles(null, relFilePaths);
+
+    final String verificationFilePath = getTestDataPath() + "/" + getBasePath() + "/" + getTestName(false) + "_verification.xml";
+    HierarchyTreeStructure structure = treeStructureComputable.compute();
+    try {
+      checkHierarchyTreeStructure(structure, JDOMUtil.loadDocument(new File(verificationFilePath)));
+    } catch (Throwable e)  {
+      assertEquals("XML structure comparison for your convenience, actual failure details BELOW",
+                   FileUtil.loadFile(new File(verificationFilePath)), dump(structure, null, 0));
+      //noinspection CallToPrintStackTrace
+      e.printStackTrace();
+    }
+  }
+
+  private static String dump(final HierarchyTreeStructure treeStructure, @Nullable HierarchyNodeDescriptor descriptor, int level) {
+    StringBuilder s = new StringBuilder();
+    dump(treeStructure, descriptor, level, s);
+    return s.toString();
+  }
+
+  private static void dump(final HierarchyTreeStructure treeStructure,
+                             @Nullable HierarchyNodeDescriptor descriptor,
+                             int level,
+                             StringBuilder b) {
+    if (level > 10) {
+      for(int i = 0; i<level; i++) b.append("  ");
+      b.append("<Probably infinite part skipped>\n");
+      return;
+    }
+    if(descriptor==null) descriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
+    for(int i = 0; i<level; i++) b.append("  ");
+    descriptor.update();
+    b.append("<node text=\"").append(descriptor.getHighlightedText().getText()).append("\"")
+      .append(treeStructure.getBaseDescriptor() == descriptor ? " base=\"true\"" : "");
+
+    final Object[] children = treeStructure.getChildElements(descriptor);
+    if(children.length>0) {
+      b.append(">\n");
+      for (Object o : children) {
+        HierarchyNodeDescriptor d = (HierarchyNodeDescriptor)o;
+        dump(treeStructure, d, level + 1, b);
+      }
+      for(int i = 0; i<level; i++) b.append("  ");
+      b.append("</node>\n");
+    } else {
+      b.append("/>\n");
+    }
+  }
+
+  private static void checkHierarchyTreeStructure(final HierarchyTreeStructure treeStructure, final Document document) {
+    final HierarchyNodeDescriptor rootNodeDescriptor = (HierarchyNodeDescriptor)treeStructure.getRootElement();
+    rootNodeDescriptor.update();
+    final Element rootElement = document.getRootElement();
+    if (rootElement == null || !NODE_ELEMENT_NAME.equals(rootElement.getName())) {
+      throw new IllegalArgumentException("Incorrect root element in verification resource");
+    }
+    checkNodeDescriptorRecursively(treeStructure, rootNodeDescriptor, rootElement);
+  }
+
+  private static void checkNodeDescriptorRecursively(final HierarchyTreeStructure treeStructure,
+                                                     final HierarchyNodeDescriptor descriptor,
+                                                     final Element expectedElement) {
+    checkBaseNode(treeStructure, descriptor, expectedElement);
+    checkContent(descriptor, expectedElement);
+    checkChildren(treeStructure, descriptor, expectedElement);
+  }
+
+  private static void checkBaseNode(final HierarchyTreeStructure treeStructure,
+                                    final HierarchyNodeDescriptor descriptor,
+                                    final Element expectedElement) {
+    final String baseAttrValue = expectedElement.getAttributeValue(BASE_ATTR_NAME);
+    final HierarchyNodeDescriptor baseDescriptor = treeStructure.getBaseDescriptor();
+    final boolean mustBeBase = "true".equalsIgnoreCase(baseAttrValue);
+    assertTrue("Incorrect base node", mustBeBase ? baseDescriptor == descriptor : baseDescriptor != descriptor);
+  }
+
+  private static void checkContent(final HierarchyNodeDescriptor descriptor, final Element expectedElement) {
+    assertEquals(expectedElement.getAttributeValue(TEXT_ATTR_NAME), descriptor.getHighlightedText().getText());
+  }
+
+  private static void checkChildren(final HierarchyTreeStructure treeStructure,
+                                    final HierarchyNodeDescriptor descriptor,
+                                    final Element element) {
+    if (element.getChild(ANY_NODES_ELEMENT_NAME) != null) {
+      return;
+    }
+
+    final Object[] children = treeStructure.getChildElements(descriptor);
+    //noinspection unchecked
+    final List<Element> expectedChildren = new ArrayList<Element>(element.getChildren(NODE_ELEMENT_NAME));
+
+    final StringBuilder messageBuilder = new StringBuilder("Actual children of [" + descriptor.getHighlightedText().getText() + "]:\n");
+    for (Object child : children) {
+      final HierarchyNodeDescriptor nodeDescriptor = (HierarchyNodeDescriptor)child;
+      nodeDescriptor.update();
+      messageBuilder.append("    [").append(nodeDescriptor.getHighlightedText().getText()).append("]\n");
+    }
+    assertEquals(messageBuilder.toString(), expectedChildren.size(), children.length);
+
+    Arrays.sort(children, new Comparator<Object>() {
+      @Override
+      public int compare(final Object first, final Object second) {
+        return ((HierarchyNodeDescriptor)first).getHighlightedText().getText()
+          .compareTo(((HierarchyNodeDescriptor)second).getHighlightedText().getText());
+      }
+    });
+
+    Collections.sort(expectedChildren, new Comparator<Element>() {
+      @Override
+      public int compare(final Element first, final Element second) {
+        return first.getAttributeValue(TEXT_ATTR_NAME).compareTo(second.getAttributeValue(TEXT_ATTR_NAME));
+      }
+    });
+
+    //noinspection unchecked
+    final Iterator<Element> iterator = expectedChildren.iterator();
+    for (Object child : children) {
+      checkNodeDescriptorRecursively(treeStructure, ((HierarchyNodeDescriptor)child), iterator.next());
+    }
+  }
+
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java b/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java
new file mode 100644
index 0000000..2a2d15c
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/DefaultLightProjectDescriptor.java
@@ -0,0 +1,50 @@
+/*
+ * Copyright 2000-2012 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework.fixtures;
+
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.LightProjectDescriptor;
+
+/**
+* @author peter
+*/
+public class DefaultLightProjectDescriptor implements LightProjectDescriptor {
+  @Override
+  public ModuleType getModuleType() {
+    return StdModuleTypes.JAVA;
+  }
+
+  @Override
+  public Sdk getSdk() {
+    return IdeaTestUtil.getMockJdk17();
+  }
+
+  @Override
+  public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+    LanguageLevelModuleExtension extension = model.getModuleExtension(LanguageLevelModuleExtension.class);
+    if (extension != null) {
+      extension.setLanguageLevel(LanguageLevel.HIGHEST);
+    }
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java
new file mode 100644
index 0000000..d811f49
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightFixtureTestCase.java
@@ -0,0 +1,101 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework.fixtures;
+
+import com.intellij.openapi.application.PathManager;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.psi.JavaPsiFacade;
+import com.intellij.psi.PsiElementFactory;
+import com.intellij.psi.PsiManager;
+import com.intellij.testFramework.IdeaTestCase;
+import com.intellij.testFramework.UsefulTestCase;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+
+/**
+ * @author peter
+ */
+public abstract class JavaCodeInsightFixtureTestCase extends UsefulTestCase{
+  protected JavaCodeInsightTestFixture myFixture;
+  protected Module myModule;
+
+  @SuppressWarnings({"JUnitTestCaseWithNonTrivialConstructors"})
+  protected JavaCodeInsightFixtureTestCase() {
+    IdeaTestCase.initPlatformPrefix();
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    final TestFixtureBuilder<IdeaProjectTestFixture> projectBuilder = IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(getName());
+    myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(projectBuilder.getFixture());
+    final JavaModuleFixtureBuilder moduleFixtureBuilder = projectBuilder.addModule(JavaModuleFixtureBuilder.class);
+    moduleFixtureBuilder.addSourceContentRoot(myFixture.getTempDirPath());
+    tuneFixture(moduleFixtureBuilder);    
+
+    myFixture.setUp();
+    myFixture.setTestDataPath(getTestDataPath());
+    myModule = moduleFixtureBuilder.getFixture().getModule();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    myModule = null;
+    myFixture.tearDown();
+    myFixture = null;
+    super.tearDown();
+  }
+
+  /**
+   * Return relative path to the test data. Path is relative to the
+   * {@link com.intellij.openapi.application.PathManager#getHomePath()}
+   *
+   * @return relative path to the test data.
+   */
+  @NonNls
+  protected String getBasePath() {
+    return "";
+  }
+
+  /**
+   * Return absolute path to the test data. Not intended to be overridden.
+   *
+   * @return absolute path to the test data.
+   */
+  @NonNls
+  protected String getTestDataPath() {
+    return PathManager.getHomePath().replace(File.separatorChar, '/') + getBasePath();
+  }
+
+  protected void tuneFixture(final JavaModuleFixtureBuilder moduleBuilder) throws Exception {}
+
+
+  protected Project getProject() {
+    return myFixture.getProject();
+  }
+
+  protected PsiManager getPsiManager() {
+    return PsiManager.getInstance(getProject());
+  }
+
+  public PsiElementFactory getElementFactory() {
+    return JavaPsiFacade.getInstance(getProject()).getElementFactory();
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.java
new file mode 100644
index 0000000..e5d8c43
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestFixture.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.testFramework.fixtures;
+
+import com.intellij.psi.PsiClass;
+import com.intellij.psi.PsiPackage;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public interface JavaCodeInsightTestFixture extends CodeInsightTestFixture {
+  JavaPsiFacadeEx getJavaFacade();
+
+  PsiClass addClass(@NotNull @NonNls final String classText);
+
+  @NotNull
+  PsiClass findClass(@NotNull @NonNls String name);
+
+  @NotNull
+  PsiPackage findPackage(@NotNull @NonNls String name);
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java
new file mode 100644
index 0000000..dac9920
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaCodeInsightTestUtil.java
@@ -0,0 +1,106 @@
+/*
+ * 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.testFramework.fixtures;
+
+import com.intellij.codeInsight.TargetElementUtilBase;
+import com.intellij.openapi.application.Result;
+import com.intellij.openapi.command.WriteCommandAction;
+import com.intellij.openapi.editor.Editor;
+import com.intellij.psi.*;
+import com.intellij.refactoring.inline.InlineConstantFieldProcessor;
+import com.intellij.refactoring.inline.InlineLocalHandler;
+import com.intellij.refactoring.inline.InlineMethodProcessor;
+import com.intellij.refactoring.inline.InlineParameterHandler;
+import com.intellij.refactoring.util.InlineUtil;
+import org.jetbrains.annotations.NotNull;
+
+
+public class JavaCodeInsightTestUtil {
+  private static final int TARGET_FOR_INLINE_FLAGS =
+    TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED;
+
+  private JavaCodeInsightTestUtil() { }
+
+  public static void doInlineLocalTest(@NotNull final CodeInsightTestFixture fixture,
+                                       @NotNull final String before, @NotNull final String after) {
+    fixture.configureByFile(before);
+    new WriteCommandAction(fixture.getProject()) {
+      @Override
+      protected void run(final Result result) throws Throwable {
+        final Editor editor = fixture.getEditor();
+        final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+        assert element instanceof PsiLocalVariable : element;
+        InlineLocalHandler.invoke(fixture.getProject(), editor, (PsiLocalVariable)element, null);
+      }
+    }.execute();
+    fixture.checkResultByFile(after, false);
+  }
+
+  public static void doInlineParameterTest(@NotNull final CodeInsightTestFixture fixture,
+                                           @NotNull final String before, @NotNull final String after) {
+    fixture.configureByFile(before);
+    new WriteCommandAction(fixture.getProject()) {
+      @Override
+      protected void run(final Result result) throws Throwable {
+        final Editor editor = fixture.getEditor();
+        final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+        assert element instanceof PsiParameter : element;
+        new InlineParameterHandler().inlineElement(getProject(), editor, element);
+      }
+    }.execute();
+    fixture.checkResultByFile(after, false);
+  }
+
+  public static void doInlineMethodTest(@NotNull final CodeInsightTestFixture fixture,
+                                        @NotNull final String before, @NotNull final String after) {
+    fixture.configureByFile(before);
+    new WriteCommandAction(fixture.getProject()) {
+      @Override
+      protected void run(final Result result) throws Throwable {
+        final Editor editor = fixture.getEditor();
+        final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+        assert element instanceof PsiMethod : element;
+
+        final PsiReference ref = fixture.getFile().findReferenceAt(editor.getCaretModel().getOffset());
+        final PsiReferenceExpression refExpr = ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
+
+        final PsiMethod method = (PsiMethod)element;
+        assert !(InlineMethodProcessor.checkBadReturns(method) && !InlineUtil.allUsagesAreTailCalls(method)) : "Bad returns found";
+        new InlineMethodProcessor(getProject(), method, refExpr, editor, false).run();
+      }
+    }.execute();
+    fixture.checkResultByFile(after, false);
+  }
+
+  public static void doInlineConstantTest(@NotNull final CodeInsightTestFixture fixture,
+                                          @NotNull final String before, @NotNull final String after) {
+    fixture.configureByFile(before);
+    new WriteCommandAction(fixture.getProject()) {
+      @Override
+      protected void run(final Result result) throws Throwable {
+        final Editor editor = fixture.getEditor();
+        final PsiElement element = TargetElementUtilBase.findTargetElement(editor, TARGET_FOR_INLINE_FLAGS);
+        assert element instanceof PsiField : element;
+
+        final PsiReference ref = fixture.getFile().findReferenceAt(editor.getCaretModel().getOffset());
+        final PsiReferenceExpression refExpr = ref instanceof PsiReferenceExpression ? (PsiReferenceExpression)ref : null;
+
+        new InlineConstantFieldProcessor((PsiField)element, getProject(), refExpr, false).run();
+      }
+    }.execute();
+    fixture.checkResultByFile(after, false);
+  }
+}
\ No newline at end of file
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.java b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.java
new file mode 100644
index 0000000..5ae1917
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/JavaTestFixtureFactory.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.testFramework.fixtures;
+
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public abstract class JavaTestFixtureFactory {
+  private static final JavaTestFixtureFactory ourInstance;
+
+  static {
+    try {
+      final Class<?> aClass = Class.forName("com.intellij.testFramework.fixtures.impl.JavaTestFixtureFactoryImpl");
+      ourInstance = (JavaTestFixtureFactory)aClass.newInstance();
+    }
+    catch (Exception e) {
+      throw new RuntimeException("Can't instantiate factory", e);
+    }
+  }
+
+  public static JavaTestFixtureFactory getFixtureFactory() {
+    return ourInstance;
+  }
+
+  public abstract TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder();
+
+  public abstract JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture);
+
+  public abstract JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture);
+
+  /**
+   *
+   * @deprecated use {@link JavaTestFixtureFactory#createFixtureBuilder(String)}
+   */
+  //also implicitly initializes ourInstance and registers java module fixture builder
+  public static TestFixtureBuilder<IdeaProjectTestFixture> createFixtureBuilder() {
+    return IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder();
+  }
+  public static TestFixtureBuilder<IdeaProjectTestFixture> createFixtureBuilder(@NotNull String name) {
+    return IdeaTestFixtureFactory.getFixtureFactory().createFixtureBuilder(name);
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
new file mode 100644
index 0000000..4d284cf
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/LightCodeInsightFixtureTestCase.java
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2000-2009 JetBrains s.r.o.
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package com.intellij.testFramework.fixtures;
+
+import com.intellij.lang.Language;
+import com.intellij.openapi.fileTypes.FileType;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.project.Project;
+import com.intellij.openapi.roots.ContentEntry;
+import com.intellij.openapi.roots.LanguageLevelModuleExtension;
+import com.intellij.openapi.roots.ModifiableRootModel;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.psi.*;
+import com.intellij.testFramework.*;
+import com.intellij.testFramework.fixtures.impl.LightTempDirTestFixtureImpl;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+import java.io.File;
+
+/**
+ * @author peter
+ */
+public abstract class LightCodeInsightFixtureTestCase extends UsefulTestCase{
+  public static final LightProjectDescriptor JAVA_1_6 = new DefaultLightProjectDescriptor() {
+    @Override
+    public void configureModule(Module module, ModifiableRootModel model, ContentEntry contentEntry) {
+      model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_6);
+    }
+  };
+  public static final LightProjectDescriptor JAVA_LATEST = new DefaultLightProjectDescriptor();
+
+
+  protected JavaCodeInsightTestFixture myFixture;
+  protected Module myModule;
+
+  @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+  protected LightCodeInsightFixtureTestCase() {
+    IdeaTestCase.initPlatformPrefix();
+  }
+
+  @SuppressWarnings("JUnitTestCaseWithNonTrivialConstructors")
+  public LightCodeInsightFixtureTestCase(String classToTest, String prefix) {
+    PlatformTestCase.initPlatformPrefix(classToTest, prefix);
+  }
+
+  @Override
+  protected void setUp() throws Exception {
+    super.setUp();
+
+    IdeaTestFixtureFactory factory = IdeaTestFixtureFactory.getFixtureFactory();
+    TestFixtureBuilder<IdeaProjectTestFixture> fixtureBuilder = factory.createLightFixtureBuilder(getProjectDescriptor());
+    final IdeaProjectTestFixture fixture = fixtureBuilder.getFixture();
+    myFixture = JavaTestFixtureFactory.getFixtureFactory().createCodeInsightFixture(fixture, new LightTempDirTestFixtureImpl(true));
+
+    myFixture.setUp();
+    myFixture.setTestDataPath(getTestDataPath());
+
+    myModule = myFixture.getModule();
+  }
+
+  /**
+   * Return relative path to the test data.
+   *
+   * @return relative path to the test data.
+   */
+  @NonNls
+  protected String getBasePath() {
+    return "";
+  }
+
+  @NotNull
+  protected LightProjectDescriptor getProjectDescriptor() {
+    return JAVA_LATEST;
+  }
+
+
+  /**
+   * Return absolute path to the test data. Not intended to be overridden.
+   *
+   * @return absolute path to the test data.
+   */
+  @NonNls
+  protected String getTestDataPath() {
+    String communityPath = PlatformTestUtil.getCommunityPath().replace(File.separatorChar, '/');
+    String path = communityPath + getBasePath();
+    if (new File(path).exists()) return path;
+    return communityPath + "/../" + getBasePath();
+  }
+
+  @Override
+  protected void tearDown() throws Exception {
+    myFixture.tearDown();
+    myFixture = null;
+    myModule = null;
+    super.tearDown();
+  }
+  protected final void runTestBare() throws Throwable {
+    LightCodeInsightFixtureTestCase.super.runTest();
+  }
+
+  protected Project getProject() {
+    return myFixture.getProject();
+  }
+
+  protected PsiManager getPsiManager() {
+    return PsiManager.getInstance(getProject());
+  }
+
+  public PsiElementFactory getElementFactory() {
+    return JavaPsiFacade.getInstance(getProject()).getElementFactory();
+  }
+
+  protected PsiFile createLightFile(final FileType fileType, final String text) {
+    return PsiFileFactory.getInstance(getProject()).createFileFromText("a." + fileType.getDefaultExtension(), fileType, text);
+  }
+
+  public PsiFile createLightFile(final String fileName, final Language language, final String text) {
+    return PsiFileFactory.getInstance(getProject()).createFileFromText(fileName, language, text, false, true);
+  }
+
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
new file mode 100644
index 0000000..e4d075b
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaCodeInsightTestFixtureImpl.java
@@ -0,0 +1,94 @@
+/*
+ * 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.testFramework.fixtures.impl;
+
+import com.intellij.ide.highlighter.JavaFileType;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.util.Computable;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.psi.*;
+import com.intellij.psi.impl.JavaPsiFacadeEx;
+import com.intellij.psi.impl.PsiModificationTrackerImpl;
+import com.intellij.psi.search.ProjectScope;
+import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
+import com.intellij.testFramework.fixtures.JavaCodeInsightTestFixture;
+import com.intellij.testFramework.fixtures.TempDirTestFixture;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+
+/**
+ * @author yole
+ */
+public class JavaCodeInsightTestFixtureImpl extends CodeInsightTestFixtureImpl implements JavaCodeInsightTestFixture {
+  public JavaCodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture) {
+    super(projectFixture, tempDirFixture);
+  }
+
+  @Override
+  public JavaPsiFacadeEx getJavaFacade() {
+    assertInitialized();
+    return JavaPsiFacadeEx.getInstanceEx(getProject());
+  }
+
+  @Override
+  public PsiClass addClass(@NotNull @NonNls final String classText) {
+    assertInitialized();
+    final PsiClass psiClass = addClass(getTempDirPath(), classText);
+    final VirtualFile file = psiClass.getContainingFile().getVirtualFile();
+    allowTreeAccessForFile(file);
+    return psiClass;
+  }
+
+  private PsiClass addClass(@NonNls final String rootPath, @NotNull @NonNls final String classText) {
+    final String qName =
+      ApplicationManager.getApplication().runReadAction(new Computable<String>() {
+        public String compute() {
+          final PsiFileFactory factory = PsiFileFactory.getInstance(getProject());
+          final PsiJavaFile javaFile = (PsiJavaFile)factory.createFileFromText("a.java", JavaFileType.INSTANCE, classText);
+          return javaFile.getClasses()[0].getQualifiedName();
+        }
+      });
+    assert qName != null;
+    final PsiFile psiFile = addFileToProject(rootPath, qName.replace('.', '/') + ".java", classText);
+    return ApplicationManager.getApplication().runReadAction(new Computable<PsiClass>() {
+            public PsiClass compute() {
+              return ((PsiJavaFile)psiFile).getClasses()[0];
+            }
+          });
+  }
+
+  @Override
+  @NotNull
+  public PsiClass findClass(@NotNull @NonNls final String name) {
+    final PsiClass aClass = getJavaFacade().findClass(name, ProjectScope.getProjectScope(getProject()));
+    assertNotNull("Class " + name + " not found", aClass);
+    return aClass;
+  }
+
+  @Override
+  @NotNull
+  public PsiPackage findPackage(@NotNull @NonNls final String name) {
+    final PsiPackage aPackage = getJavaFacade().findPackage(name);
+    assertNotNull("Package " + name + " not found", aPackage);
+    return aPackage;
+  }
+
+  @Override
+  public void tearDown() throws Exception {
+    ((PsiModificationTrackerImpl)getPsiManager().getModificationTracker()).incCounter();// drop all caches
+    super.tearDown();
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
new file mode 100644
index 0000000..21f3e43
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaModuleFixtureBuilderImpl.java
@@ -0,0 +1,215 @@
+/*
+ * 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.testFramework.fixtures.impl;
+
+import com.intellij.compiler.CompilerConfigurationImpl;
+import com.intellij.openapi.module.Module;
+import com.intellij.openapi.module.ModuleType;
+import com.intellij.openapi.module.StdModuleTypes;
+import com.intellij.openapi.projectRoots.JavaSdk;
+import com.intellij.openapi.projectRoots.Sdk;
+import com.intellij.openapi.projectRoots.impl.MockJdkWrapper;
+import com.intellij.openapi.projectRoots.impl.ProjectJdkImpl;
+import com.intellij.openapi.roots.*;
+import com.intellij.openapi.roots.libraries.Library;
+import com.intellij.openapi.roots.libraries.LibraryTable;
+import com.intellij.openapi.vfs.JarFileSystem;
+import com.intellij.openapi.vfs.LocalFileSystem;
+import com.intellij.openapi.vfs.VirtualFile;
+import com.intellij.pom.java.LanguageLevel;
+import com.intellij.testFramework.IdeaTestUtil;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.IdeaProjectTestFixture;
+import com.intellij.testFramework.fixtures.ModuleFixture;
+import com.intellij.testFramework.fixtures.TestFixtureBuilder;
+import com.intellij.util.ArrayUtil;
+import org.jetbrains.annotations.NonNls;
+
+import java.io.File;
+import java.util.ArrayList;
+import java.util.HashMap;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * @author mike
+ */
+abstract class JavaModuleFixtureBuilderImpl<T extends ModuleFixture> extends ModuleFixtureBuilderImpl<T> implements JavaModuleFixtureBuilder<T> {
+  private final List<Lib> myLibraries = new ArrayList<Lib>();
+  private String myJdk;
+  private MockJdkLevel myMockJdkLevel = MockJdkLevel.jdk14;
+  private LanguageLevel myLanguageLevel = null;
+
+  public JavaModuleFixtureBuilderImpl(final TestFixtureBuilder<? extends IdeaProjectTestFixture> fixtureBuilder) {
+    super(StdModuleTypes.JAVA, fixtureBuilder);
+  }
+
+  public JavaModuleFixtureBuilderImpl(final ModuleType moduleType, final TestFixtureBuilder<? extends IdeaProjectTestFixture> fixtureBuilder) {
+    super(moduleType, fixtureBuilder);
+  }
+
+  @Override
+  public JavaModuleFixtureBuilder setLanguageLevel(final LanguageLevel languageLevel) {
+    myLanguageLevel = languageLevel;
+    return this;
+  }
+
+  @Override
+  public JavaModuleFixtureBuilder addLibrary(String libraryName, String... classPath) {
+    final HashMap<OrderRootType, String[]> map = new HashMap<OrderRootType, String[]>();
+    for (String path : classPath) {
+      if (!new File(path).exists()) {
+        System.out.println(path + " not exists");
+      }
+    }
+    map.put(OrderRootType.CLASSES, classPath);
+    myLibraries.add(new Lib(libraryName, map));
+    return this;
+  }
+
+  @Override
+  public JavaModuleFixtureBuilder addLibrary(@NonNls final String libraryName, final Map<OrderRootType, String[]> roots) {
+    myLibraries.add(new Lib(libraryName, roots));
+    return this;
+  }
+
+  @Override
+  public JavaModuleFixtureBuilder addLibraryJars(String libraryName, String basePath, String... jars) {
+    if (!basePath.endsWith("/")) {
+      basePath += "/";
+    }
+    String[] classPath = ArrayUtil.newStringArray(jars.length);
+    for (int i = 0; i < jars.length; i++) {
+      classPath[i] = basePath + jars[i];
+    }
+    return addLibrary(libraryName, classPath);
+  }
+
+  @Override
+  public JavaModuleFixtureBuilder addJdk(String jdkPath) {
+    myJdk = jdkPath;
+    return this;
+  }
+
+  @Override
+  public void setMockJdkLevel(final MockJdkLevel level) {
+    myMockJdkLevel = level;
+  }
+
+  @Override
+  protected void initModule(final Module module) {
+    super.initModule(module);
+
+    final ModifiableRootModel model = ModuleRootManager.getInstance(module).getModifiableModel();
+    final LibraryTable libraryTable = model.getModuleLibraryTable();
+
+    for (Lib lib : myLibraries) {
+      String libraryName = lib.getName();
+
+      final Library library = libraryTable.createLibrary(libraryName);
+
+      final Library.ModifiableModel libraryModel = library.getModifiableModel();
+
+      for (OrderRootType rootType : OrderRootType.getAllTypes()) {
+        final String[] roots = lib.getRoots(rootType);
+        for (String root : roots) {
+          VirtualFile vRoot = LocalFileSystem.getInstance().refreshAndFindFileByPath(root);
+          if (vRoot != null && OrderRootType.CLASSES.equals(rootType) && !vRoot.isDirectory()) {
+            final VirtualFile jar = JarFileSystem.getInstance().refreshAndFindFileByPath(root + "!/");
+            if (jar != null) vRoot = jar;
+          }
+          if (vRoot != null) {
+            libraryModel.addRoot(vRoot, rootType);
+          }
+        }
+      }
+      libraryModel.commit();
+    }
+
+    final Sdk jdk;
+    if (myJdk != null) {
+      jdk = JavaSdk.getInstance().createJdk(module.getName() + "_jdk", myJdk, false);
+      ((ProjectJdkImpl)jdk).setVersionString("java 1.5");
+    }
+    else {
+      jdk = IdeaTestUtil.getMockJdk17();
+    }
+    if (jdk != null) {
+      model.setSdk(new MockJdkWrapper(CompilerConfigurationImpl.getTestsExternalCompilerHome(), jdk));
+    }
+
+    if (myLanguageLevel != null) {
+      model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(myLanguageLevel);
+    }
+    else if (myMockJdkLevel == MockJdkLevel.jdk15) {
+      model.getModuleExtension(LanguageLevelModuleExtension.class).setLanguageLevel(LanguageLevel.JDK_1_5);
+    }
+
+    model.commit();
+
+    for (OrderEntry entry : ModuleRootManager.getInstance(module).getOrderEntries()) {
+      if (entry instanceof LibraryOrderEntry) {
+        Library library = ((LibraryOrderEntry)entry).getLibrary();
+        libraryCreated(library, module);
+      }
+    }
+  }
+
+  @Override
+  protected void setupRootModel(ModifiableRootModel rootModel) {
+    if (myOutputPath != null) {
+      final File pathFile = new File(myOutputPath);
+      if (!pathFile.mkdirs()) {
+        assert pathFile.exists() : "unable to create: " + myOutputPath;
+      }
+      final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(myOutputPath);
+      assert virtualFile != null : "cannot find output path: " + myOutputPath;
+      rootModel.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPath(virtualFile);
+      rootModel.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false);
+      rootModel.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
+    }
+    if (myTestOutputPath != null) {
+      assert new File(myTestOutputPath).mkdirs() : myTestOutputPath;
+      final VirtualFile virtualFile = LocalFileSystem.getInstance().refreshAndFindFileByPath(myTestOutputPath);
+      assert virtualFile != null : "cannot find test output path: " + myTestOutputPath;
+      rootModel.getModuleExtension(CompilerModuleExtension.class).setCompilerOutputPathForTests(virtualFile);
+      rootModel.getModuleExtension(CompilerModuleExtension.class).inheritCompilerOutputPath(false);
+      rootModel.getModuleExtension(CompilerModuleExtension.class).setExcludeOutput(false);
+    }
+  }
+
+  protected void libraryCreated(Library library, Module module) {}
+
+  private static class Lib {
+    private final String myName;
+    private final Map<OrderRootType, String []> myRoots;
+
+    public Lib(final String name, final Map<OrderRootType, String[]> roots) {
+      myName = name;
+      myRoots = roots;
+    }
+
+    public String getName() {
+      return myName;
+    }
+
+    public String [] getRoots(OrderRootType rootType) {
+      final String[] roots = myRoots.get(rootType);
+      return roots != null ? roots : ArrayUtil.EMPTY_STRING_ARRAY;
+    }
+  }
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.java
new file mode 100644
index 0000000..d4e85df
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/fixtures/impl/JavaTestFixtureFactoryImpl.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.testFramework.fixtures.impl;
+
+import com.intellij.testFramework.LightProjectDescriptor;
+import com.intellij.testFramework.builders.JavaModuleFixtureBuilder;
+import com.intellij.testFramework.fixtures.*;
+
+/**
+ * @author yole
+ */
+public class JavaTestFixtureFactoryImpl extends JavaTestFixtureFactory {
+  public JavaTestFixtureFactoryImpl() {
+    IdeaTestFixtureFactory.getFixtureFactory().registerFixtureBuilder(JavaModuleFixtureBuilder.class, MyJavaModuleFixtureBuilderImpl.class);
+  }
+
+  @Override
+  public JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture) {
+    return new JavaCodeInsightTestFixtureImpl(projectFixture, new TempDirTestFixtureImpl());
+  }
+
+  @Override
+  public JavaCodeInsightTestFixture createCodeInsightFixture(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirFixture) {
+    return new JavaCodeInsightTestFixtureImpl(projectFixture, tempDirFixture);
+  }
+
+  @Override
+  public TestFixtureBuilder<IdeaProjectTestFixture> createLightFixtureBuilder() {
+    return new LightTestFixtureBuilderImpl<IdeaProjectTestFixture>(new LightIdeaTestFixtureImpl(ourJavaProjectDescriptor));
+  }
+
+  public static class MyJavaModuleFixtureBuilderImpl extends JavaModuleFixtureBuilderImpl {
+    public MyJavaModuleFixtureBuilderImpl(final TestFixtureBuilder<? extends IdeaProjectTestFixture> testFixtureBuilder) {
+      super(testFixtureBuilder);
+    }
+
+    @Override
+    protected ModuleFixture instantiateFixture() {
+      return new ModuleFixtureImpl(this);
+    }
+  }
+
+  private static final LightProjectDescriptor ourJavaProjectDescriptor = LightCodeInsightFixtureTestCase.JAVA_1_6;
+}
diff --git a/java/testFramework/src/com/intellij/testFramework/package.html b/java/testFramework/src/com/intellij/testFramework/package.html
new file mode 100644
index 0000000..960f5c5
--- /dev/null
+++ b/java/testFramework/src/com/intellij/testFramework/package.html
@@ -0,0 +1,4 @@
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 3.2 Final//EN">
+<html><body bgcolor="white">
+Provides a test framework for writing tests which use IDEA projects, PSI and other services.
+</body></html>
diff --git a/java/testFramework/testFramework-java.iml b/java/testFramework/testFramework-java.iml
new file mode 100644
index 0000000..408e30d
--- /dev/null
+++ b/java/testFramework/testFramework-java.iml
@@ -0,0 +1,31 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<module relativePaths="true" type="JAVA_MODULE" version="4">
+  <component name="NewModuleRootManager" inherit-compiler-output="true">
+    <exclude-output />
+    <content url="file://$MODULE_DIR$">
+      <sourceFolder url="file://$MODULE_DIR$/src" isTestSource="false" />
+    </content>
+    <orderEntry type="inheritedJdk" />
+    <orderEntry type="sourceFolder" forTests="false" />
+    <orderEntry type="module" module-name="openapi" exported="" />
+    <orderEntry type="module" module-name="util" exported="" />
+    <orderEntry type="library" name="JUnit4" level="project" />
+    <orderEntry type="library" name="JDOM" level="project" />
+    <orderEntry type="library" name="Log4J" level="project" />
+    <orderEntry type="module" module-name="lang-api" exported="" />
+    <orderEntry type="module" module-name="lang-impl" exported="" />
+    <orderEntry type="module" module-name="compiler-impl" />
+    <orderEntry type="module" module-name="java-impl" exported="" />
+    <orderEntry type="module" module-name="execution-impl" exported="" scope="RUNTIME" />
+    <orderEntry type="library" name="Groovy" level="project" />
+    <orderEntry type="module" module-name="testFramework" exported="" />
+    <orderEntry type="module" module-name="relaxng" exported="" scope="TEST" />
+    <orderEntry type="module" module-name="idea-ui" exported="" />
+  </component>
+  <component name="copyright">
+    <Base>
+      <setting name="state" value="1" />
+    </Base>
+  </component>
+</module>
+
