07b303e3a8b9aac6f7e6000171e135205a1bcf7c
[idea/community.git] / platform / testFramework / src / com / intellij / testFramework / fixtures / impl / CodeInsightTestFixtureImpl.java
1 /*
2  * Copyright 2000-2010 JetBrains s.r.o.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16
17 package com.intellij.testFramework.fixtures.impl;
18
19 import com.intellij.analysis.AnalysisScope;
20 import com.intellij.codeHighlighting.HighlightDisplayLevel;
21 import com.intellij.codeHighlighting.TextEditorHighlightingPass;
22 import com.intellij.codeInsight.CodeInsightActionHandler;
23 import com.intellij.codeInsight.TargetElementUtilBase;
24 import com.intellij.codeInsight.completion.CodeCompletionHandlerBase;
25 import com.intellij.codeInsight.completion.CompletionContext;
26 import com.intellij.codeInsight.completion.CompletionProgressIndicator;
27 import com.intellij.codeInsight.completion.CompletionType;
28 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer;
29 import com.intellij.codeInsight.daemon.DaemonCodeAnalyzerSettings;
30 import com.intellij.codeInsight.daemon.HighlightDisplayKey;
31 import com.intellij.codeInsight.daemon.impl.*;
32 import com.intellij.codeInsight.highlighting.HighlightUsagesHandler;
33 import com.intellij.codeInsight.intention.IntentionAction;
34 import com.intellij.codeInsight.intention.impl.ShowIntentionActionsHandler;
35 import com.intellij.codeInsight.lookup.LookupElement;
36 import com.intellij.codeInsight.lookup.LookupManager;
37 import com.intellij.codeInsight.lookup.impl.LookupImpl;
38 import com.intellij.codeInspection.*;
39 import com.intellij.codeInspection.ex.*;
40 import com.intellij.facet.Facet;
41 import com.intellij.facet.FacetManager;
42 import com.intellij.find.FindManager;
43 import com.intellij.find.findUsages.FindUsagesHandler;
44 import com.intellij.find.findUsages.FindUsagesOptions;
45 import com.intellij.find.impl.FindManagerImpl;
46 import com.intellij.ide.DataManager;
47 import com.intellij.lang.annotation.HighlightSeverity;
48 import com.intellij.openapi.Disposable;
49 import com.intellij.openapi.actionSystem.DataContext;
50 import com.intellij.openapi.actionSystem.IdeActions;
51 import com.intellij.openapi.application.ApplicationManager;
52 import com.intellij.openapi.application.ModalityState;
53 import com.intellij.openapi.application.Result;
54 import com.intellij.openapi.command.WriteCommandAction;
55 import com.intellij.openapi.editor.Document;
56 import com.intellij.openapi.editor.Editor;
57 import com.intellij.openapi.editor.EditorFactory;
58 import com.intellij.openapi.editor.RangeMarker;
59 import com.intellij.openapi.editor.actionSystem.EditorActionManager;
60 import com.intellij.openapi.editor.ex.DocumentEx;
61 import com.intellij.openapi.editor.ex.util.EditorUtil;
62 import com.intellij.openapi.editor.markup.GutterIconRenderer;
63 import com.intellij.openapi.editor.markup.RangeHighlighter;
64 import com.intellij.openapi.extensions.ExtensionPoint;
65 import com.intellij.openapi.extensions.ExtensionPointName;
66 import com.intellij.openapi.extensions.ExtensionsArea;
67 import com.intellij.openapi.fileEditor.FileEditorManager;
68 import com.intellij.openapi.fileEditor.OpenFileDescriptor;
69 import com.intellij.openapi.fileEditor.impl.text.TextEditorProvider;
70 import com.intellij.openapi.fileTypes.FileType;
71 import com.intellij.openapi.fileTypes.FileTypeManager;
72 import com.intellij.openapi.module.Module;
73 import com.intellij.openapi.progress.ProgressIndicator;
74 import com.intellij.openapi.progress.ProgressManager;
75 import com.intellij.openapi.project.DumbServiceImpl;
76 import com.intellij.openapi.project.Project;
77 import com.intellij.openapi.util.*;
78 import com.intellij.openapi.util.io.FileUtil;
79 import com.intellij.openapi.util.text.StringUtil;
80 import com.intellij.openapi.vfs.LocalFileSystem;
81 import com.intellij.openapi.vfs.VfsUtil;
82 import com.intellij.openapi.vfs.VirtualFile;
83 import com.intellij.openapi.vfs.VirtualFileFilter;
84 import com.intellij.profile.codeInspection.InspectionProfileManager;
85 import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
86 import com.intellij.psi.*;
87 import com.intellij.psi.impl.PsiManagerImpl;
88 import com.intellij.psi.impl.cache.impl.todo.TodoIndex;
89 import com.intellij.psi.impl.source.PostprocessReformattingAspect;
90 import com.intellij.psi.impl.source.PsiFileImpl;
91 import com.intellij.psi.impl.source.resolve.FileContextUtil;
92 import com.intellij.psi.impl.source.tree.injected.InjectedLanguageUtil;
93 import com.intellij.psi.search.GlobalSearchScope;
94 import com.intellij.psi.search.UsageSearchContext;
95 import com.intellij.psi.stubs.StubUpdatingIndex;
96 import com.intellij.psi.util.PsiTreeUtil;
97 import com.intellij.psi.util.PsiUtilBase;
98 import com.intellij.refactoring.move.moveFilesOrDirectories.MoveFilesOrDirectoriesProcessor;
99 import com.intellij.refactoring.rename.RenameProcessor;
100 import com.intellij.refactoring.rename.RenamePsiElementProcessor;
101 import com.intellij.testFramework.*;
102 import com.intellij.testFramework.fixtures.*;
103 import com.intellij.usageView.UsageInfo;
104 import com.intellij.util.ArrayUtil;
105 import com.intellij.util.CommonProcessors;
106 import com.intellij.util.Function;
107 import com.intellij.util.SmartList;
108 import com.intellij.util.containers.ContainerUtil;
109 import com.intellij.util.indexing.FileBasedIndex;
110 import gnu.trove.THashMap;
111 import junit.framework.Assert;
112 import org.jetbrains.annotations.NonNls;
113 import org.jetbrains.annotations.NotNull;
114 import org.jetbrains.annotations.Nullable;
115
116 import javax.swing.*;
117 import java.io.File;
118 import java.io.IOException;
119 import java.io.OutputStream;
120 import java.util.*;
121
122 /**
123  * @author Dmitry Avdeev
124  */
125 @SuppressWarnings({"TestMethodWithIncorrectSignature"})
126 public class CodeInsightTestFixtureImpl extends BaseFixture implements CodeInsightTestFixture {
127
128   @NonNls private static final String PROFILE = "Configurable";
129
130   private PsiManagerImpl myPsiManager;
131   private PsiFile myFile;
132   private Editor myEditor;
133   private String myTestDataPath;
134   private boolean myEmptyLookup;
135
136   private InspectionProfileEntry[] myInspections;
137   private final Map<String, InspectionProfileEntry> myAvailableTools = new THashMap<String, InspectionProfileEntry>();
138   private final Map<String, InspectionTool> myAvailableLocalTools = new THashMap<String, InspectionTool>();
139
140   private final TempDirTestFixture myTempDirFixture;
141   protected final IdeaProjectTestFixture myProjectFixture;
142   @NonNls private static final String XXX = "XXX";
143   private PsiElement myFileContext;
144   private final FileTreeAccessFilter myJavaFilesFilter = new FileTreeAccessFilter();
145
146   public CodeInsightTestFixtureImpl(IdeaProjectTestFixture projectFixture, TempDirTestFixture tempDirTestFixture) {
147     myProjectFixture = projectFixture;
148     myTempDirFixture = tempDirTestFixture;
149   }
150
151   public void setTestDataPath(String dataPath) {
152     myTestDataPath = dataPath;
153   }
154
155   public String getTempDirPath() {
156     return myTempDirFixture.getTempDirPath();
157   }
158
159   public TempDirTestFixture getTempDirFixture() {
160     return myTempDirFixture;
161   }
162
163   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath) {
164     File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
165     if (!fromFile.exists()) {
166       fromFile = new File(sourceFilePath);
167     }
168
169     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
170       VirtualFile fromVFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(fromFile);
171       if (fromVFile == null) {
172         fromVFile = myTempDirFixture.getFile(sourceFilePath);
173       }
174       assert fromVFile != null: "can't find testdata file " + sourceFilePath;
175       return myTempDirFixture.copyFile(fromVFile, targetPath);
176     }
177     final File destFile = new File(getTempDirPath() + "/" + targetPath);
178     if (!destFile.exists()) {
179
180       if (fromFile.isDirectory()) {
181         destFile.mkdirs();
182       }
183       else {
184         try {
185           FileUtil.copy(fromFile, destFile);
186         }
187         catch (IOException e) {
188           throw new RuntimeException(e);
189         }
190       }
191     }
192     final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
193     Assert.assertNotNull(file);
194     return file;
195   }
196
197   public VirtualFile copyDirectoryToProject(@NonNls final String sourceFilePath, @NonNls final String targetPath)  {
198     assert getTestDataPath() != null: "test data path not specified";
199     final File fromFile = new File(getTestDataPath() + "/" + sourceFilePath);
200     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
201       return myTempDirFixture.copyAll(fromFile.getPath(), targetPath);
202     }
203     else {
204       final File destFile = new File(getTempDirPath() + "/" + targetPath);
205       try {
206         FileUtil.copyDir(fromFile, destFile);
207       }
208       catch (IOException e) {
209         throw new RuntimeException(e);
210       }
211       final VirtualFile file = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(destFile);
212       Assert.assertNotNull(file);
213       file.refresh(false, true);
214       return file;
215     }
216   }
217
218   public VirtualFile copyFileToProject(@NonNls final String sourceFilePath) {
219     return copyFileToProject(sourceFilePath, sourceFilePath);
220   }
221
222   public void enableInspections(InspectionProfileEntry... inspections) {
223     myInspections = inspections;
224     if (isInitialized()) {
225       configureInspections(myInspections);
226     }
227   }
228
229   private boolean isInitialized() {
230     return myPsiManager != null;
231   }
232
233   public void enableInspections(final Class<? extends LocalInspectionTool>... inspections) {
234     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
235     for (Class clazz: inspections) {
236       try {
237         LocalInspectionTool inspection = (LocalInspectionTool)clazz.getConstructor().newInstance();
238         tools.add(inspection);
239       }
240       catch (Exception e) {
241         throw new RuntimeException("Cannot instantiate " + clazz);
242       }
243     }
244     enableInspections(tools.toArray(new LocalInspectionTool[tools.size()]));
245   }
246
247   public void disableInspections(InspectionProfileEntry... inspections) {
248     myAvailableTools.clear();
249     myAvailableLocalTools.clear();
250     final ArrayList<InspectionProfileEntry> tools = new ArrayList<InspectionProfileEntry>(Arrays.asList(myInspections));
251     for (Iterator<InspectionProfileEntry> i = tools.iterator(); i.hasNext();) {
252       final InspectionProfileEntry tool = i.next();
253       for (InspectionProfileEntry toRemove: inspections) {
254         if (tool.getShortName().equals(toRemove.getShortName())) {
255           i.remove();
256           break;
257         }
258       }
259     }
260     myInspections = tools.toArray(new InspectionProfileEntry[tools.size()]);
261     configureInspections(myInspections);
262   }
263
264   public void enableInspections(InspectionToolProvider... providers) {
265     final ArrayList<LocalInspectionTool> tools = new ArrayList<LocalInspectionTool>();
266     for (InspectionToolProvider provider: providers) {
267       for (Class clazz: provider.getInspectionClasses()) {
268         try {
269           Object o = clazz.getConstructor().newInstance();
270           if (o instanceof LocalInspectionTool) {
271             LocalInspectionTool inspection = (LocalInspectionTool)o;
272             tools.add(inspection);
273           }
274         }
275         catch (Exception e) {
276           throw new RuntimeException("Cannot instantiate " + clazz, e);
277         }
278       }
279     }
280     myInspections = tools.toArray(new LocalInspectionTool[tools.size()]);
281     configureInspections(myInspections);
282   }
283
284   public long testHighlighting(final boolean checkWarnings,
285                                final boolean checkInfos,
286                                final boolean checkWeakWarnings,
287                                final String... filePaths) {
288     final Ref<Long> duration = new Ref<Long>();
289     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
290
291       protected void run() throws Exception {
292         if (filePaths.length > 0) {
293           configureByFilesInner(filePaths);
294         }
295         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
296       }
297     }.execute().throwException();
298     return duration.get().longValue();
299   }
300
301   public long testHighlightingAllFiles(final boolean checkWarnings,
302                                        final boolean checkInfos,
303                                        final boolean checkWeakWarnings,
304                                        @NonNls final String... filePaths) {
305     final ArrayList<VirtualFile> files = new ArrayList<VirtualFile>();
306     for (String path : filePaths) {
307       files.add(copyFileToProject(path));
308     }
309     return testHighlightingAllFiles(checkWarnings, checkInfos, checkWeakWarnings, VfsUtil.toVirtualFileArray(files));
310   }
311
312   public long testHighlightingAllFiles(final boolean checkWarnings,
313                                final boolean checkInfos,
314                                final boolean checkWeakWarnings,
315                                @NonNls final VirtualFile... files) {
316     final Ref<Long> duration = new Ref<Long>();
317     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
318
319       protected void run() throws Exception {
320         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration, files);
321       }
322     }.execute().throwException();
323     return duration.get().longValue();
324   }
325
326   private void collectAndCheckHighlightings(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final Ref<Long> duration,
327                                             final VirtualFile[] files) {
328     final List<Trinity<PsiFile, Editor, ExpectedHighlightingData>> datas = ContainerUtil.map2List(files, new Function<VirtualFile, Trinity<PsiFile, Editor, ExpectedHighlightingData>>() {
329       public Trinity<PsiFile, Editor, ExpectedHighlightingData> fun(final VirtualFile file) {
330         final PsiFile psiFile = myPsiManager.findFile(file);
331         assertNotNull(psiFile);
332         final Document document = PsiDocumentManager.getInstance(getProject()).getDocument(psiFile);
333         assertNotNull(document);
334         return Trinity.create(psiFile, createEditor(file), new ExpectedHighlightingData(document, checkWarnings, checkWeakWarnings, checkInfos, psiFile));
335       }
336     });
337     for (Trinity<PsiFile, Editor, ExpectedHighlightingData> trinity : datas) {
338       myEditor = trinity.second;
339       myFile = trinity.first;
340       collectAndCheckHighlightings(trinity.third, duration);
341     }
342   }
343
344   public long checkHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings) {
345     final Ref<Long> duration = new Ref<Long>();
346     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
347       protected void run() throws Exception {
348         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
349       }
350     }.execute().throwException();
351     return duration.get().longValue();
352   }
353
354   public long checkHighlighting() {
355     return checkHighlighting(true, true, true);
356   }
357
358   public long testHighlighting(final String... filePaths) {
359     return testHighlighting(true, true, true, filePaths);
360   }
361
362   public long testHighlighting(final boolean checkWarnings, final boolean checkInfos, final boolean checkWeakWarnings, final VirtualFile file) {
363     final Ref<Long> duration = new Ref<Long>();
364     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
365       protected void run() throws Exception {
366         openFileInEditor(file);
367         collectAndCheckHighlightings(checkWarnings, checkInfos, checkWeakWarnings, duration);
368       }
369     }.execute().throwException();
370     return duration.get().longValue();
371   }
372
373   public void openFileInEditor(@NotNull final VirtualFile file) {
374     myFile = myPsiManager.findFile(file);
375     myEditor = createEditor(file);
376   }
377
378   public void testInspection(String testDir, InspectionTool tool) {
379     VirtualFile sourceDir = copyDirectoryToProject(new File(testDir, "src").getPath(), "src");
380     AnalysisScope scope = new AnalysisScope(getPsiManager().findDirectory(sourceDir));
381
382     InspectionManagerEx inspectionManager = (InspectionManagerEx) InspectionManager.getInstance(getProject());
383     final GlobalInspectionContextImpl globalContext = inspectionManager.createNewGlobalContext(!(myProjectFixture instanceof LightIdeaTestFixture));
384     globalContext.setCurrentScope(scope);
385     scope.invalidate();
386
387     InspectionTestUtil.runTool(tool, scope, globalContext, inspectionManager);
388     InspectionTestUtil.compareToolResults(tool, false, new File(getTestDataPath(), testDir).getPath());
389   }
390
391   @Nullable
392   public PsiReference getReferenceAtCaretPosition(final String... filePaths) {
393     new WriteCommandAction<PsiReference>(myProjectFixture.getProject()) {
394       protected void run(final Result<PsiReference> result) throws Exception {
395         configureByFilesInner(filePaths);
396       }
397     }.execute().throwException();
398     return getFile().findReferenceAt(myEditor.getCaretModel().getOffset());
399   }
400
401   @NotNull
402   public PsiReference getReferenceAtCaretPositionWithAssertion(final String... filePaths) {
403     final PsiReference reference = getReferenceAtCaretPosition(filePaths);
404     assert reference != null: "no reference found at " + myEditor.getCaretModel().getLogicalPosition();
405     return reference;
406   }
407
408   @NotNull
409   public List<IntentionAction> getAvailableIntentions(final String... filePaths) {
410
411     return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
412       protected void run(final Result<List<IntentionAction>> result) throws Exception {
413         if (filePaths.length > 0) {
414           configureByFilesInner(filePaths);
415         }
416         result.setResult(getAvailableIntentions());
417       }
418     }.execute().throwException().getResultObject();
419   }
420
421   @NotNull
422   public List<IntentionAction> getAllQuickFixes(@NonNls final String... filePaths) {
423     return new WriteCommandAction<List<IntentionAction>>(myProjectFixture.getProject()) {
424       protected void run(final Result<List<IntentionAction>> result) throws Exception {
425         configureByFilesInner(filePaths);
426         List<HighlightInfo> infos = doHighlighting();
427         ArrayList<IntentionAction> actions = new ArrayList<IntentionAction>();
428         for (HighlightInfo info : infos) {
429           for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
430             actions.add(pair.getFirst().getAction());
431           }
432         }
433         result.setResult(actions);
434       }
435     }.execute().throwException().getResultObject();
436   }
437
438   @NotNull
439   public List<IntentionAction> getAvailableIntentions() {
440     doHighlighting();
441     return getAvailableIntentions(myEditor, myFile);
442   }
443
444   public List<IntentionAction> filterAvailableIntentions(@NotNull final String hint) {
445     final List<IntentionAction> availableIntentions = getAvailableIntentions();
446     return ContainerUtil.findAll(availableIntentions, new Condition<IntentionAction>() {
447       public boolean value(final IntentionAction intentionAction) {
448         return intentionAction.getText().startsWith(hint);
449       }
450     });
451   }
452
453   public IntentionAction findSingleIntention(@NotNull final String hint) {
454     final List<IntentionAction> list = filterAvailableIntentions(hint);
455     if (list.size() != 1) {
456       Assert.fail(StringUtil.join(getAvailableIntentions(), new Function<IntentionAction, String>() {
457         public String fun(final IntentionAction intentionAction) {
458           return intentionAction.getText();
459         }
460       }, ", "));
461     }
462     return UsefulTestCase.assertOneElement(list);
463   }
464
465   public IntentionAction getAvailableIntention(final String intentionName, final String... filePaths) {
466     List<IntentionAction> intentions = getAvailableIntentions(filePaths);
467     return CodeInsightTestUtil.findIntentionByText(intentions, intentionName);
468   }
469
470   public void launchAction(@NotNull final IntentionAction action) {
471     new WriteCommandAction(myProjectFixture.getProject()) {
472       protected void run(final Result result) throws Exception {
473         ShowIntentionActionsHandler.chooseActionAndInvoke(getFile(), getEditor(), action, action.getText());
474       }
475     }.execute().throwException();
476
477   }
478
479   public void testCompletion(final String[] filesBefore, final String fileAfter) {
480     assertInitialized();
481     configureByFiles(filesBefore);
482     final LookupElement[] items = complete(CompletionType.BASIC);
483     if (items != null) {
484       System.out.println("items = " + Arrays.toString(items));
485     }
486     checkResultByFile(fileAfter);
487   }
488
489   protected void assertInitialized() {
490     Assert.assertNotNull("setUp() hasn't been called", myPsiManager);
491   }
492
493   public void testCompletion(String fileBefore, String fileAfter, final String... additionalFiles) {
494     testCompletion(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)), fileAfter);
495   }
496
497   public void testCompletionVariants(final String fileBefore, final String... expectedItems) {
498     assertInitialized();
499     final List<String> result = getCompletionVariants(fileBefore);
500     UsefulTestCase.assertSameElements(result, expectedItems);
501   }
502
503   public List<String> getCompletionVariants(final String... filesBefore) {
504     assertInitialized();
505     configureByFiles(filesBefore);
506     final LookupElement[] items = complete(CompletionType.BASIC);
507     Assert.assertNotNull("No lookup was shown, probably there was only one lookup element that was inserted automatically", items);
508     return getLookupElementStrings();
509   }
510
511   @Nullable
512   public List<String> getLookupElementStrings() {
513     assertInitialized();
514     final LookupElement[] elements = getLookupElements();
515     if (elements == null) return null;
516
517     return ContainerUtil.map(elements, new Function<LookupElement, String>() {
518       public String fun(final LookupElement lookupItem) {
519         return lookupItem.getLookupString();
520       }
521     });
522   }
523
524   public void testRename(final String fileBefore, final String fileAfter, final String newName, final String... additionalFiles) {
525     assertInitialized();
526     configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, fileBefore)));
527     testRename(fileAfter, newName);
528   }
529
530   public void testRename(final String fileAfter, final String newName) {
531     renameElementAtCaret(newName);
532     checkResultByFile(fileAfter);
533   }
534
535   @NotNull
536   public PsiElement getElementAtCaret() {
537     assertInitialized();
538     final PsiElement element = TargetElementUtilBase.findTargetElement(getCompletionEditor(),
539         TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED | TargetElementUtilBase.ELEMENT_NAME_ACCEPTED);
540     assert element != null : "element not found in file " + myFile.getName() + " at caret position, offset " + myEditor.getCaretModel().getOffset();
541     return element;
542   }
543
544   public void renameElementAtCaret(final String newName) {
545     renameElement(getElementAtCaret(), newName);
546   }
547
548   public void renameElement(final PsiElement element, final String newName) {
549     final boolean searchInComments = false;
550     final boolean searchTextOccurrences = false;
551     renameElement(element, newName, searchInComments, searchTextOccurrences);
552   }
553
554   public void renameElement(final PsiElement element,
555                              final String newName,
556                              final boolean searchInComments,
557                              final boolean searchTextOccurrences) {
558     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
559       protected void run() throws Exception {
560         final PsiElement substitution = RenamePsiElementProcessor.forElement(element).substituteElementToRename(element, myEditor);
561         new RenameProcessor(myProjectFixture.getProject(), substitution, newName, searchInComments, searchTextOccurrences).run();
562      }
563     }.execute().throwException();
564   }
565
566   public <T extends PsiElement> T findElementByText(String text, Class<T> elementClass) {
567     int pos = PsiDocumentManager.getInstance(getProject()).getDocument(getFile()).getText().indexOf(text);
568     assert pos >= 0: "text not found in file";
569     return PsiTreeUtil.getParentOfType(getFile().findElementAt(pos), elementClass);
570   }
571
572   public void type(final char c) {
573     assertInitialized();
574     new WriteCommandAction(getProject()) {
575       protected void run(Result result) throws Exception {
576         EditorActionManager actionManager = EditorActionManager.getInstance();
577         final DataContext dataContext = DataManager.getInstance().getDataContext();
578         if (c == '\b') {
579           performEditorAction(IdeActions.ACTION_EDITOR_BACKSPACE);
580           return;
581         }
582         if (c == '\n') {
583           if (LookupManager.getActiveLookup(getEditor()) != null) {
584             performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM);
585             return;
586           }
587
588           performEditorAction(IdeActions.ACTION_EDITOR_ENTER);
589           return;
590         }
591         if (c == '\t') {
592           if (LookupManager.getInstance(getProject()).getActiveLookup() != null) {
593             performEditorAction(IdeActions.ACTION_CHOOSE_LOOKUP_ITEM_REPLACE);
594             return;
595           }
596         }
597
598         actionManager.getTypedAction().actionPerformed(getEditor(), c, dataContext);
599       }
600     }.execute();
601   }
602
603   public void performEditorAction(final String actionId) {
604     assertInitialized();
605     final DataContext dataContext = DataManager.getInstance().getDataContext();
606     EditorActionManager actionManager = EditorActionManager.getInstance();
607     actionManager.getActionHandler(actionId).execute(getEditor(), dataContext);
608   }
609
610   public Collection<UsageInfo> testFindUsages(@NonNls final String... fileNames) {
611     assertInitialized();
612     configureByFiles(fileNames);
613     final PsiElement targetElement = TargetElementUtilBase
614       .findTargetElement(getEditor(), TargetElementUtilBase.ELEMENT_NAME_ACCEPTED | TargetElementUtilBase.REFERENCED_ELEMENT_ACCEPTED);
615     assert targetElement != null : "Cannot find referenced element";
616     return findUsages(targetElement);
617   }
618
619   public Collection<UsageInfo> findUsages(@NotNull final PsiElement targetElement) {
620     final Project project = getProject();
621     final FindUsagesHandler handler = ((FindManagerImpl)FindManager.getInstance(project)).getFindUsagesManager().getFindUsagesHandler(targetElement, false);
622
623     final CommonProcessors.CollectProcessor<UsageInfo> processor = new CommonProcessors.CollectProcessor<UsageInfo>();
624     assert handler != null : "Cannot find handler for: " + targetElement;
625     final PsiElement[] psiElements = ArrayUtil.mergeArrays(handler.getPrimaryElements(), handler.getSecondaryElements(), PsiElement.class);
626     final FindUsagesOptions options = handler.getFindUsagesOptions();
627     for (PsiElement psiElement : psiElements) {
628       handler.processElementUsages(psiElement, processor, options);
629     }
630     return processor.getResults();
631   }
632
633   public RangeHighlighter[] testHighlightUsages(final String... files) {
634     configureByFiles(files);
635     final Editor editor = getEditor();
636     HighlightUsagesHandler.invoke(getProject(), editor, getFile());
637     return editor.getMarkupModel().getAllHighlighters();
638   }
639
640   public void moveFile(@NonNls final String filePath, @NonNls final String to, final String... additionalFiles) {
641     assertInitialized();
642     final Project project = myProjectFixture.getProject();
643     new WriteCommandAction.Simple(project) {
644       protected void run() throws Exception {
645         configureByFiles(ArrayUtil.reverseArray(ArrayUtil.append(additionalFiles, filePath)));
646         final VirtualFile file = findFileInTempDir(to);
647         assert file.isDirectory() : to + " is not a directory";
648         final PsiDirectory directory = myPsiManager.findDirectory(file);
649         new MoveFilesOrDirectoriesProcessor(project, new PsiElement[] {myFile}, directory,
650                                             false, false, null, null).run();
651       }
652     }.execute().throwException();
653
654   }
655
656   @Nullable
657   public GutterIconRenderer findGutter(final String filePath) {
658     assertInitialized();
659     final Project project = myProjectFixture.getProject();
660     final Ref<GutterIconRenderer> result = new Ref<GutterIconRenderer>();
661     new WriteCommandAction.Simple(project) {
662
663       protected void run() throws Exception {
664         final int offset = configureByFilesInner(filePath);
665
666         final Collection<HighlightInfo> infos = doHighlighting();
667         for (HighlightInfo info :infos) {
668           if (info.endOffset >= offset && info.startOffset <= offset) {
669             final GutterIconRenderer renderer = info.getGutterIconRenderer();
670             if (renderer != null) {
671               result.set(renderer);
672               return;
673             }
674           }
675         }
676
677       }
678     }.execute().throwException();
679     return result.get();
680   }
681
682   @NotNull
683   public Collection<GutterIconRenderer> findAllGutters(final String filePath) {
684     assertInitialized();
685     final Project project = myProjectFixture.getProject();
686     final SortedMap<Integer, List<GutterIconRenderer>> result = new TreeMap<Integer, List<GutterIconRenderer>>();
687     new WriteCommandAction.Simple(project) {
688
689       protected void run() throws Exception {
690         configureByFilesInner(filePath);
691
692         for (HighlightInfo info : doHighlighting()) {
693           addGutterIconRenderer(info.getGutterIconRenderer(), info.startOffset);
694         }
695
696         for (final RangeHighlighter highlighter : myEditor.getDocument().getMarkupModel(project).getAllHighlighters()) {
697           addGutterIconRenderer(highlighter.getGutterIconRenderer(), highlighter.getStartOffset());
698         }
699       }
700
701       private void addGutterIconRenderer(final GutterIconRenderer renderer, final int offset) {
702         if (renderer == null) return;
703
704         List<GutterIconRenderer> renderers = result.get(offset);
705         if (renderers == null) {
706           result.put(offset, renderers = new SmartList<GutterIconRenderer>());
707         }
708         renderers.add(renderer);
709       }
710
711     }.execute().throwException();
712     return ContainerUtil.concat(result.values());
713   }
714
715
716   public PsiFile addFileToProject(@NonNls final String relativePath, @NonNls final String fileText) {
717     assertInitialized();
718     return addFileToProject(getTempDirPath(), relativePath, fileText);
719   }
720
721   protected PsiFile addFileToProject(String rootPath, String relativePath, String fileText) {
722     try {
723       if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
724         final VirtualFile file = myTempDirFixture.createFile(relativePath, fileText);
725         return PsiManager.getInstance(getProject()).findFile(file);
726       }
727
728       return ((HeavyIdeaTestFixture)myProjectFixture).addFileToProject(rootPath, relativePath, fileText);
729     }
730     catch (IOException e) {
731       throw new RuntimeException(e);
732     }
733   }
734
735   public <T> void registerExtension(final ExtensionsArea area, final ExtensionPointName<T> epName, final T extension) {
736     assertInitialized();
737     final ExtensionPoint<T> extensionPoint = area.getExtensionPoint(epName);
738     extensionPoint.registerExtension(extension);
739     disposeOnTearDown(new Disposable() {
740       public void dispose() {
741         extensionPoint.unregisterExtension(extension);
742       }
743     });
744   }
745
746   public PsiManager getPsiManager() {
747     return myPsiManager;
748   }
749
750   public LookupElement[] complete(final CompletionType type) {
751     assertInitialized();
752     myEmptyLookup = false;
753     new WriteCommandAction(getProject()) {
754       protected void run(Result result) throws Exception {
755         final CodeInsightActionHandler handler = new CodeCompletionHandlerBase(type) {
756           protected PsiFile createFileCopy(final PsiFile file) {
757             final PsiFile copy = super.createFileCopy(file);
758             if (myFileContext != null) {
759               final PsiElement contextCopy = myFileContext.copy();
760               final PsiFile containingFile = contextCopy.getContainingFile();
761               if (containingFile instanceof PsiFileImpl) {
762                 ((PsiFileImpl)containingFile).setOriginalFile(myFileContext.getContainingFile());
763               }
764               setContext(copy, contextCopy);
765             }
766             return copy;
767           }
768
769           @Override
770           protected void completionFinished(final int offset1, final int offset2, final CompletionContext context, final CompletionProgressIndicator indicator,
771                                             final LookupElement[] items) {
772             myEmptyLookup = items.length == 0;
773             super.completionFinished(offset1, offset2, context, indicator, items);
774           }
775         };
776         Editor editor = getCompletionEditor();
777         handler.invoke(getProject(), editor, PsiUtilBase.getPsiFileInEditor(editor, getProject()));
778       }
779     }.execute();
780     return getLookupElements();
781   }
782
783   @Nullable
784   protected Editor getCompletionEditor() {
785     return InjectedLanguageUtil.getEditorForInjectedLanguageNoCommit(myEditor, myFile);
786   }
787
788   @Nullable
789   public LookupElement[] completeBasic() {
790     return complete(CompletionType.BASIC);
791   }
792
793   @Nullable
794   public LookupElement[] getLookupElements() {
795     LookupImpl lookup = (LookupImpl)LookupManager.getActiveLookup(myEditor);
796     if (lookup == null) {
797       return myEmptyLookup ? LookupElement.EMPTY_ARRAY : null;
798     }
799     else {
800       final List<LookupElement> list = lookup.getItems();
801       return list.toArray(new LookupElement[list.size()]);
802     }
803   }
804
805   public void checkResult(final String text) {
806     checkResult(text, false);
807   }
808
809   public void checkResult(String text, boolean stripTrailingSpaces) {
810     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
811     EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
812     checkResult("TEXT", stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromText(text, getProject()), myFile.getText());
813   }
814
815   public void checkResultByFile(final String expectedFile) {
816     checkResultByFile(expectedFile, false);
817   }
818
819   public void checkResultByFile(final String expectedFile, final boolean ignoreTrailingWhitespaces) {
820     assertInitialized();
821     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
822
823       protected void run() throws Exception {
824         checkResultByFile(expectedFile, myFile, ignoreTrailingWhitespaces);
825       }
826     }.execute().throwException();
827   }
828
829   public void checkResultByFile(final String filePath, final String expectedFile, final boolean ignoreTrailingWhitespaces) {
830     assertInitialized();
831
832     new WriteCommandAction.Simple(myProjectFixture.getProject()) {
833
834       protected void run() throws Exception {
835         final String path = filePath.replace(File.separatorChar, '/');
836         final VirtualFile copy = findFileInTempDir(path);
837         if (copy == null) {
838           throw new IllegalArgumentException("could not find results file " + path);
839         }
840         final PsiFile psiFile = myPsiManager.findFile(copy);
841         assert psiFile != null;
842         checkResultByFile(expectedFile, psiFile, ignoreTrailingWhitespaces);
843       }
844     }.execute().throwException();
845   }
846
847   public void setUp() throws Exception {
848     super.setUp();
849
850     myProjectFixture.setUp();
851     myTempDirFixture.setUp();
852     myPsiManager = (PsiManagerImpl)PsiManager.getInstance(getProject());
853     configureInspections(myInspections == null ? new LocalInspectionTool[0] : myInspections);
854     DaemonCodeAnalyzerSettings.getInstance().setImportHintEnabled(false);
855     DaemonCodeAnalyzer.getInstance(getProject()).setUpdateByTimerEnabled(false);
856     ensureIndexesUpToDate(getProject());
857   }
858
859   private void enableInspectionTool(InspectionProfileEntry tool){
860     final String shortName = tool.getShortName();
861     final HighlightDisplayKey key = HighlightDisplayKey.find(shortName);
862     if (key == null){
863       String id = tool instanceof LocalInspectionTool ? ((LocalInspectionTool)tool).getID() : shortName;
864       HighlightDisplayKey.register(shortName, tool.getDisplayName(), id);
865     }
866     myAvailableTools.put(shortName, tool);
867     myAvailableLocalTools.put(shortName, tool instanceof LocalInspectionTool ?
868                                          new LocalInspectionToolWrapper((LocalInspectionTool)tool) :
869                                          (InspectionTool)tool);
870   }
871
872   private void configureInspections(final InspectionProfileEntry[] tools) {
873     for (InspectionProfileEntry tool : tools) {
874       enableInspectionTool(tool);
875     }
876
877     final InspectionProfileImpl profile = new InspectionProfileImpl(PROFILE) {
878       @NotNull
879       public ModifiableModel getModifiableModel() {
880         mySource = this;
881         return this;
882       }
883
884       @NotNull
885       public InspectionProfileEntry[] getInspectionTools(PsiElement element) {
886         final Collection<InspectionTool> tools = myAvailableLocalTools.values();
887         return tools.toArray(new InspectionTool[tools.size()]);
888       }
889
890       @Override
891       public List<ToolsImpl> getAllEnabledInspectionTools() {
892         List<ToolsImpl> result = new ArrayList<ToolsImpl>();
893         for (InspectionProfileEntry entry : getInspectionTools(null)) {
894           result.add(new ToolsImpl(entry, entry.getDefaultLevel(), true));
895         }
896         return result;
897       }
898
899       public boolean isToolEnabled(HighlightDisplayKey key, PsiElement element) {
900         return key != null && key.toString() != null && myAvailableTools.containsKey(key.toString());
901       }
902
903       public HighlightDisplayLevel getErrorLevel(@NotNull HighlightDisplayKey key, PsiElement element) {
904         final InspectionProfileEntry entry = myAvailableTools.get(key.toString());
905         return entry != null ? entry.getDefaultLevel() : HighlightDisplayLevel.WARNING;
906       }
907
908       public InspectionTool getInspectionTool(@NotNull String shortName, @NotNull PsiElement element) {
909         return myAvailableLocalTools.get(shortName);
910       }
911     };
912     final InspectionProfileManager inspectionProfileManager = InspectionProfileManager.getInstance();
913     inspectionProfileManager.addProfile(profile);
914     Disposer.register(getTestRootDisposable(), new Disposable() {
915       public void dispose() {
916         inspectionProfileManager.deleteProfile(PROFILE);
917       }
918     });
919     inspectionProfileManager.setRootProfile(profile.getName());
920     InspectionProjectProfileManager.getInstance(getProject()).updateProfile(profile);
921     InspectionProjectProfileManager.getInstance(getProject()).setProjectProfile(profile.getName());
922   }
923
924   public void tearDown() throws Exception {
925     if (SwingUtilities.isEventDispatchThread()) {
926       LookupManager.getInstance(getProject()).hideActiveLookup();
927     }
928     else {
929       ApplicationManager.getApplication().invokeAndWait(new Runnable() {
930         public void run() {
931           LookupManager.getInstance(getProject()).hideActiveLookup();
932         }
933       }, ModalityState.NON_MODAL);
934     }
935
936     FileEditorManager editorManager = FileEditorManager.getInstance(getProject());
937     VirtualFile[] openFiles = editorManager.getOpenFiles();
938     for (VirtualFile openFile : openFiles) {
939       editorManager.closeFile(openFile);
940     }
941
942     myProjectFixture.tearDown();
943     myTempDirFixture.tearDown();
944
945     super.tearDown();
946   }
947
948   private int configureByFilesInner(@NonNls String... filePaths) throws IOException {
949     assertInitialized();
950     myFile = null;
951     myEditor = null;
952     for (int i = filePaths.length - 1; i > 0; i--) {
953       configureByFileInner(filePaths[i]);
954     }
955     return configureByFileInner(filePaths[0]);
956   }
957
958   public void configureByFile(final String file) {
959     assertInitialized();
960     new WriteCommandAction.Simple(getProject()) {
961       protected void run() throws Exception {
962         configureByFilesInner(file);
963       }
964     }.execute();
965   }
966
967   public void configureByFiles(@NonNls final String... files) {
968     new WriteCommandAction.Simple(getProject()) {
969       protected void run() throws Exception {
970         configureByFilesInner(files);
971       }
972     }.execute();
973   }
974
975   public PsiFile configureByText(final FileType fileType, @NonNls final String text) {
976     assertInitialized();
977     final String extension = fileType.getDefaultExtension();
978     final FileTypeManager fileTypeManager = FileTypeManager.getInstance();
979     if (fileTypeManager.getFileTypeByExtension(extension) != fileType) {
980       new WriteCommandAction(getProject()) {
981         protected void run(Result result) throws Exception {
982           fileTypeManager.associateExtension(fileType, extension);
983         }
984       }.execute();
985     }
986     final String fileName = "aaa." + extension;
987     return configureByText(fileName, text);
988   }
989
990   public PsiFile configureByText(String fileName, @NonNls String text) {
991     assertInitialized();
992     try {
993       final VirtualFile vFile;
994       if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
995         final VirtualFile root = LightPlatformTestCase.getSourceRoot();
996         root.refresh(false, false);
997         vFile = root.findOrCreateChildData(this, fileName);
998       }
999       else{
1000         String prefix = StringUtil.getPackageName(fileName);
1001         if (prefix.length() < 3) {
1002           prefix += "___";
1003         }
1004         final File tempFile = File.createTempFile(prefix, "." + StringUtil.getShortName(fileName), new File(getTempDirPath()));
1005         vFile = LocalFileSystem.getInstance().refreshAndFindFileByIoFile(tempFile);
1006       }
1007       VfsUtil.saveText(vFile, text);
1008       configureInner(vFile, SelectionAndCaretMarkupLoader.fromFile(vFile, getProject()));
1009     }
1010     catch (IOException e) {
1011       throw new RuntimeException(e);
1012     }
1013     return myFile;
1014   }
1015
1016   public Document getDocument(final PsiFile file) {
1017     assertInitialized();
1018     return PsiDocumentManager.getInstance(getProject()).getDocument(file);
1019   }
1020
1021   public void setFileContext(@Nullable final PsiElement context) {
1022     myFileContext = context;
1023     setContext(myFile, context);
1024   }
1025
1026   /**
1027    *
1028    * @param filePath
1029    * @return caret offset or -1 if caret marker does not present
1030    * @throws IOException
1031    */
1032   private int configureByFileInner(@NonNls String filePath) {
1033     assertInitialized();
1034     final VirtualFile file = copyFileToProject(filePath);
1035     return configureByFileInner(file);
1036   }
1037
1038   public int configureFromTempProjectFile(final String filePath)  {
1039     return configureByFileInner(findFileInTempDir(filePath));
1040   }
1041
1042   public void configureFromExistingVirtualFile(VirtualFile f) {
1043     configureByFileInner(f);
1044   }
1045
1046   private int configureByFileInner(final VirtualFile copy) {
1047     return configureInner(copy, SelectionAndCaretMarkupLoader.fromFile(copy, getProject()));
1048   }
1049
1050   private int configureInner(@NotNull final VirtualFile copy, final SelectionAndCaretMarkupLoader loader) {
1051     assertInitialized();
1052     try {
1053       final OutputStream outputStream = copy.getOutputStream(null, 0, 0);
1054       outputStream.write(loader.newFileText.getBytes(copy.getCharset()));
1055       outputStream.close();
1056     }
1057     catch (IOException e) {
1058       throw new RuntimeException(e);
1059     }
1060     myFile = myPsiManager.findFile(copy);
1061     setContext(myFile, myFileContext);
1062     myEditor = createEditor(copy);
1063     assert myEditor != null : "Editor couldn't be created for file: " + copy.getPath() + ", use copyFileToProject(..) method for this file instead of configureByFile(..)" ;
1064     int offset = -1;
1065     if (loader.caretMarker != null) {
1066       offset = loader.caretMarker.getStartOffset();
1067       myEditor.getCaretModel().moveToOffset(offset);
1068     }
1069     if (loader.selStartMarker != null && loader.selEndMarker != null) {
1070       myEditor.getSelectionModel().setSelection(loader.selStartMarker.getStartOffset(), loader.selEndMarker.getStartOffset());
1071     }
1072
1073     Module module = getModule();
1074     if (module != null) {
1075       for (Facet facet : FacetManager.getInstance(module).getAllFacets()) {
1076         module.getMessageBus().syncPublisher(FacetManager.FACETS_TOPIC).facetConfigurationChanged(facet);
1077       }
1078     }
1079
1080     return offset;
1081   }
1082
1083   private static void setContext(final PsiFile file, final PsiElement context) {
1084     if (file != null && context != null) {
1085       file.putUserData(FileContextUtil.INJECTED_IN_ELEMENT, new IdentitySmartPointer<PsiElement>(context));
1086     }
1087   }
1088
1089   public VirtualFile findFileInTempDir(final String filePath) {
1090     if (myTempDirFixture instanceof LightTempDirTestFixtureImpl) {
1091       return myTempDirFixture.getFile(filePath);
1092     }
1093     String fullPath = getTempDirPath() + "/" + filePath;
1094
1095     final VirtualFile copy = LocalFileSystem.getInstance().refreshAndFindFileByPath(fullPath.replace(File.separatorChar, '/'));
1096     assert copy != null : "file " + fullPath + " not found";
1097     return copy;
1098   }
1099
1100   @Nullable
1101   private Editor createEditor(VirtualFile file) {
1102     final Project project = getProject();
1103     final FileEditorManager instance = FileEditorManager.getInstance(project);
1104     if (file.getFileType().isBinary()) {
1105       return null;
1106     }
1107     return instance.openTextEditor(new OpenFileDescriptor(project, file, 0), false);
1108   }
1109
1110   private void collectAndCheckHighlightings(boolean checkWarnings, boolean checkInfos, boolean checkWeakWarnings, Ref<Long> duration)
1111     throws Exception {
1112     ExpectedHighlightingData data = new ExpectedHighlightingData(myEditor.getDocument(), checkWarnings, checkWeakWarnings, checkInfos, myFile);
1113
1114     collectAndCheckHighlightings(data, duration);
1115   }
1116
1117   private void collectAndCheckHighlightings(final ExpectedHighlightingData data, final Ref<Long> duration) {
1118     final Project project = getProject();
1119     PsiDocumentManager.getInstance(project).commitAllDocuments();
1120
1121     ((PsiFileImpl)myFile).calcTreeElement(); //to load text
1122
1123     //to initialize caches
1124     myPsiManager.getCacheManager().getFilesWithWord(XXX, UsageSearchContext.IN_COMMENTS, GlobalSearchScope.allScope(project), true);
1125
1126     List<HighlightInfo> infos;
1127     try {
1128       ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(myJavaFilesFilter);
1129
1130       final long start = System.currentTimeMillis();
1131 //    ProfilingUtil.startCPUProfiling();
1132       infos = doHighlighting();
1133       removeDuplicatedRangesForInjected(infos);
1134       final long elapsed = System.currentTimeMillis() - start;
1135       duration.set(duration.isNull()? elapsed : duration.get().longValue() + elapsed);
1136 //    ProfilingUtil.captureCPUSnapshot("testing");
1137     }
1138     finally {
1139       ((PsiManagerImpl)PsiManager.getInstance(project)).setAssertOnFileLoadingFilter(VirtualFileFilter.NONE);
1140     }
1141
1142
1143     data.checkResult(infos, myEditor.getDocument().getText());
1144   }
1145
1146   private static void removeDuplicatedRangesForInjected(List<HighlightInfo> infos) {
1147     Collections.sort(infos, new Comparator<HighlightInfo>() {
1148       public int compare(HighlightInfo o1, HighlightInfo o2) {
1149         final int i = o2.startOffset - o1.startOffset;
1150         return i != 0 ? i : o1.getSeverity().myVal - o2.getSeverity().myVal;
1151       }
1152     });
1153     HighlightInfo prevInfo = null;
1154     for (Iterator<HighlightInfo> it = infos.iterator(); it.hasNext();) {
1155       final HighlightInfo info = it.next();
1156       if (prevInfo != null &&
1157           info.getSeverity() == HighlightSeverity.INFORMATION &&
1158           info.description == null &&
1159           info.startOffset == prevInfo.startOffset &&
1160           info.endOffset == prevInfo.endOffset) {
1161         it.remove();
1162       }
1163       prevInfo = info.getSeverity() == HighlightInfoType.INJECTED_FRAGMENT_SEVERITY ? info : null;
1164     }
1165   }
1166
1167   @NotNull
1168   public List<HighlightInfo> doHighlighting() {
1169     final Project project = myProjectFixture.getProject();
1170     PsiDocumentManager.getInstance(project).commitAllDocuments();
1171
1172     return
1173     ApplicationManager.getApplication().runReadAction(new Computable<List<HighlightInfo>>() {
1174       public List<HighlightInfo> compute() {
1175         return instantiateAndRun(getFile(), getEditor(), ArrayUtil.EMPTY_INT_ARRAY, false);
1176       }
1177     });
1178   }
1179
1180   @NotNull
1181   public static List<HighlightInfo> instantiateAndRun(PsiFile file, Editor editor, int[] toIgnore, boolean allowDirt) {
1182     Project project = file.getProject();
1183     ensureIndexesUpToDate(project);
1184     DaemonCodeAnalyzerImpl codeAnalyzer = (DaemonCodeAnalyzerImpl)DaemonCodeAnalyzer.getInstance(project);
1185     codeAnalyzer.setUpdateByTimerEnabled(false);
1186     FileStatusMap fileStatusMap = codeAnalyzer.getFileStatusMap();
1187     for (int ignoreId : toIgnore) {
1188       fileStatusMap.markFileUpToDate(editor.getDocument(), file, ignoreId);
1189     }
1190     fileStatusMap.allowDirt(allowDirt);
1191     try {
1192       TextEditorBackgroundHighlighter highlighter = (TextEditorBackgroundHighlighter)TextEditorProvider.getInstance().getTextEditor(editor).getBackgroundHighlighter();
1193       final List<TextEditorHighlightingPass> passes = highlighter.getPasses(toIgnore);
1194       final ProgressIndicator progress = new DaemonProgressIndicator();
1195       ProgressManager.getInstance().runProcess(new Runnable() {
1196         public void run() {
1197           for (TextEditorHighlightingPass pass : passes) {
1198             pass.collectInformation(progress);
1199             pass.applyInformationToEditor();
1200           }
1201         }
1202       }, progress);
1203       List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getHighlights(editor.getDocument(), project);
1204       return infos == null ? Collections.<HighlightInfo>emptyList() : new ArrayList<HighlightInfo>(infos);
1205     }
1206     finally {
1207       fileStatusMap.allowDirt(true);
1208       codeAnalyzer.clearPasses();
1209     }
1210   }
1211
1212   public static void ensureIndexesUpToDate(Project project) {
1213     FileBasedIndex.getInstance().ensureUpToDate(StubUpdatingIndex.INDEX_ID, project, null);
1214     FileBasedIndex.getInstance().ensureUpToDate(TodoIndex.NAME, project, null);
1215     assertTrue(!DumbServiceImpl.getInstance(project).isDumb());
1216   }
1217
1218   public String getTestDataPath() {
1219     return myTestDataPath;
1220   }
1221
1222   public Project getProject() {
1223     return myProjectFixture.getProject();
1224   }
1225
1226   public Module getModule() {
1227     return myProjectFixture.getModule();
1228   }
1229
1230   public Editor getEditor() {
1231     return myEditor;
1232   }
1233
1234   public PsiFile getFile() {
1235     return myFile;
1236   }
1237
1238   public static List<IntentionAction> getAvailableIntentions(final Editor editor, final PsiFile file) {
1239     return ApplicationManager.getApplication().runReadAction(new Computable<List<IntentionAction>>() {
1240       public List<IntentionAction> compute() {
1241         return doGetAvailableIntentions(editor, file);
1242       }
1243     });
1244   }
1245
1246   private static List<IntentionAction> doGetAvailableIntentions(Editor editor, PsiFile file) {
1247     ShowIntentionsPass.IntentionsInfo intentions = new ShowIntentionsPass.IntentionsInfo();
1248     ShowIntentionsPass.getActionsToShow(editor, file, intentions, -1);
1249     List<HighlightInfo.IntentionActionDescriptor> descriptors = new ArrayList<HighlightInfo.IntentionActionDescriptor>();
1250     descriptors.addAll(intentions.intentionsToShow);
1251     descriptors.addAll(intentions.errorFixesToShow);
1252     descriptors.addAll(intentions.inspectionFixesToShow);
1253     descriptors.addAll(intentions.guttersToShow);
1254
1255     PsiElement element = file.findElementAt(editor.getCaretModel().getOffset());
1256     List<IntentionAction> result = new ArrayList<IntentionAction>();
1257
1258     List<HighlightInfo> infos = DaemonCodeAnalyzerImpl.getFileLevelHighlights(file.getProject(), file);
1259     for (HighlightInfo info : infos) {
1260       for (Pair<HighlightInfo.IntentionActionDescriptor, TextRange> pair : info.quickFixActionRanges) {
1261         HighlightInfo.IntentionActionDescriptor actionInGroup = pair.first;
1262         if (actionInGroup.getAction().isAvailable(file.getProject(), editor, file)) {
1263           descriptors.add(actionInGroup);
1264         }
1265       }
1266     }
1267
1268     // add all intention options for simplicity
1269     for (HighlightInfo.IntentionActionDescriptor descriptor : descriptors) {
1270       result.add(descriptor.getAction());
1271       List<IntentionAction> options = descriptor.getOptions(element);
1272       if (options != null) {
1273         for (IntentionAction option : options) {
1274           if (option.isAvailable(file.getProject(), editor, file)) {
1275             result.add(option);
1276           }
1277         }
1278       }
1279     }
1280     return result;
1281   }
1282
1283   public void allowTreeAccessForFile(final VirtualFile file) {
1284     myJavaFilesFilter.allowTreeAccessForFile(file);
1285   }
1286
1287   public void allowTreeAccessForAllFiles() {
1288     myJavaFilesFilter.allowTreeAccessForAllFiles();
1289   }
1290
1291   static class SelectionAndCaretMarkupLoader {
1292     final String newFileText;
1293     final RangeMarker caretMarker;
1294     final RangeMarker selStartMarker;
1295     final RangeMarker selEndMarker;
1296
1297     static SelectionAndCaretMarkupLoader fromFile(String path, Project project) throws IOException {
1298       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(new String(FileUtil.loadFileText(new File(path)))), project);
1299     }
1300     static SelectionAndCaretMarkupLoader fromFile(VirtualFile file, Project project) {
1301       final String text;
1302       try {
1303         text = VfsUtil.loadText(file);
1304       }
1305       catch (IOException e) {
1306         throw new RuntimeException(e);
1307       }
1308       return new SelectionAndCaretMarkupLoader(StringUtil.convertLineSeparators(text), project);
1309     }
1310
1311     static SelectionAndCaretMarkupLoader fromText(String text, Project project) {
1312       return new SelectionAndCaretMarkupLoader(text, project);
1313     }
1314
1315     private SelectionAndCaretMarkupLoader(String fileText, Project project) {
1316       final Document document = EditorFactory.getInstance().createDocument(fileText);
1317
1318       int caretIndex = fileText.indexOf(CARET_MARKER);
1319       int selStartIndex = fileText.indexOf(SELECTION_START_MARKER);
1320       int selEndIndex = fileText.indexOf(SELECTION_END_MARKER);
1321
1322       caretMarker = caretIndex >= 0 ? document.createRangeMarker(caretIndex, caretIndex) : null;
1323       selStartMarker = selStartIndex >= 0 ? document.createRangeMarker(selStartIndex, selStartIndex) : null;
1324       selEndMarker = selEndIndex >= 0 ? document.createRangeMarker(selEndIndex, selEndIndex) : null;
1325
1326       new WriteCommandAction(project) {
1327         protected void run(Result result) throws Exception {
1328           if (caretMarker != null) {
1329             document.deleteString(caretMarker.getStartOffset(), caretMarker.getStartOffset() + CARET_MARKER.length());
1330           }
1331           if (selStartMarker != null) {
1332             document.deleteString(selStartMarker.getStartOffset(), selStartMarker.getStartOffset() + SELECTION_START_MARKER.length());
1333           }
1334           if (selEndMarker != null) {
1335             document.deleteString(selEndMarker.getStartOffset(), selEndMarker.getStartOffset() + SELECTION_END_MARKER.length());
1336           }
1337         }
1338       }.execute();
1339
1340       newFileText = document.getText();
1341     }
1342
1343   }
1344   private void checkResultByFile(@NonNls String expectedFile,
1345                                  @NotNull PsiFile originalFile,
1346                                  boolean stripTrailingSpaces) throws IOException {
1347     if (!stripTrailingSpaces) {
1348       EditorUtil.fillVirtualSpaceUntilCaret(myEditor);
1349     }
1350     PsiDocumentManager.getInstance(getProject()).commitAllDocuments();
1351     checkResult(expectedFile, stripTrailingSpaces, SelectionAndCaretMarkupLoader.fromFile(getTestDataPath() + "/" + expectedFile, getProject()), originalFile.getText());
1352   }
1353
1354   private void checkResult(final String expectedFile,
1355                            final boolean stripTrailingSpaces,
1356                            final SelectionAndCaretMarkupLoader loader,
1357                            String actualText) {
1358     assertInitialized();
1359     Project project = myProjectFixture.getProject();
1360
1361     project.getComponent(PostprocessReformattingAspect.class).doPostponedFormatting();
1362     if (stripTrailingSpaces) {
1363       actualText = stripTrailingSpaces(actualText);
1364     }
1365
1366     PsiDocumentManager.getInstance(project).commitAllDocuments();
1367
1368     String newFileText1 = loader.newFileText;
1369     if (stripTrailingSpaces) {
1370       newFileText1 = stripTrailingSpaces(newFileText1);
1371     }
1372
1373     actualText = StringUtil.convertLineSeparators(actualText);
1374
1375     //noinspection HardCodedStringLiteral
1376     Assert.assertEquals("Text mismatch in file " + expectedFile, newFileText1, actualText);
1377
1378     if (loader.caretMarker != null) {
1379       int caretLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.caretMarker.getStartOffset());
1380       int caretCol = loader.caretMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, caretLine, 0);
1381
1382       Assert.assertEquals("caretLine in " + expectedFile, caretLine + 1, myEditor.getCaretModel().getLogicalPosition().line + 1);
1383       Assert.assertEquals("caretColumn in " + expectedFile, caretCol + 1, myEditor.getCaretModel().getLogicalPosition().column + 1);
1384     }
1385
1386     if (loader.selStartMarker != null && loader.selEndMarker != null) {
1387       int selStartLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selStartMarker.getStartOffset());
1388       int selStartCol = loader.selStartMarker.getStartOffset() - StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0);
1389
1390       int selEndLine = StringUtil.offsetToLineNumber(loader.newFileText, loader.selEndMarker.getEndOffset());
1391       int selEndCol = loader.selEndMarker.getEndOffset() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0);
1392
1393       Assert.assertEquals("selectionStartLine in " + expectedFile, selStartLine + 1,
1394                           StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionStart()) + 1);
1395
1396       Assert.assertEquals("selectionStartCol in " + expectedFile, selStartCol + 1, myEditor.getSelectionModel().getSelectionStart() -
1397                                                                 StringUtil.lineColToOffset(loader.newFileText, selStartLine, 0) + 1);
1398
1399       Assert.assertEquals("selectionEndLine in " + expectedFile, selEndLine + 1,
1400                           StringUtil.offsetToLineNumber(loader.newFileText, myEditor.getSelectionModel().getSelectionEnd()) + 1);
1401
1402       Assert.assertEquals("selectionEndCol in " + expectedFile, selEndCol + 1,
1403                           myEditor.getSelectionModel().getSelectionEnd() - StringUtil.lineColToOffset(loader.newFileText, selEndLine, 0) +
1404                           1);
1405     }
1406     else if (myEditor != null) {
1407       Assert.assertTrue("has no selection in " + expectedFile, !myEditor.getSelectionModel().hasSelection());
1408     }
1409   }
1410
1411   private static String stripTrailingSpaces(String actualText) {
1412     final Document document = EditorFactory.getInstance().createDocument(actualText);
1413     ((DocumentEx)document).stripTrailingSpaces(false);
1414     actualText = document.getText();
1415     return actualText;
1416   }
1417
1418 }