newlines fixed (please set 'core.autocrlf' to 'true')
authorMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Thu, 26 Nov 2009 17:49:19 +0000 (20:49 +0300)
committerMaxim.Mossienko <Maxim.Mossienko@jetbrains.com>
Thu, 26 Nov 2009 17:49:19 +0000 (20:49 +0300)
platform/lang-impl/src/com/intellij/codeInsight/daemon/impl/HighlightInfo.java

index d186442fdea80efa4b51428a7e5c74a3d3fa3a87..7ce05c83a03b68d813401fb13bba78d1343970e9 100644 (file)
-/*\r
- * Copyright 2000-2009 JetBrains s.r.o.\r
- *\r
- * Licensed under the Apache License, Version 2.0 (the "License");\r
- * you may not use this file except in compliance with the License.\r
- * You may obtain a copy of the License at\r
- *\r
- * http://www.apache.org/licenses/LICENSE-2.0\r
- *\r
- * Unless required by applicable law or agreed to in writing, software\r
- * distributed under the License is distributed on an "AS IS" BASIS,\r
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\r
- * See the License for the specific language governing permissions and\r
- * limitations under the License.\r
- */\r
-\r
-package com.intellij.codeInsight.daemon.impl;\r
-\r
-import com.intellij.codeInsight.daemon.HighlightDisplayKey;\r
-import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;\r
-import com.intellij.codeInsight.intention.IntentionAction;\r
-import com.intellij.codeInsight.intention.IntentionManager;\r
-import com.intellij.codeInspection.*;\r
-import com.intellij.codeInspection.actions.CleanupInspectionIntention;\r
-import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;\r
-import com.intellij.codeInspection.ex.QuickFixWrapper;\r
-import com.intellij.lang.ASTNode;\r
-import com.intellij.lang.annotation.Annotation;\r
-import com.intellij.lang.annotation.HighlightSeverity;\r
-import com.intellij.openapi.application.ApplicationManager;\r
-import com.intellij.openapi.diagnostic.Logger;\r
-import com.intellij.openapi.editor.RangeMarker;\r
-import com.intellij.openapi.editor.colors.CodeInsightColors;\r
-import com.intellij.openapi.editor.colors.EditorColorsManager;\r
-import com.intellij.openapi.editor.colors.EditorColorsScheme;\r
-import com.intellij.openapi.editor.colors.TextAttributesKey;\r
-import com.intellij.openapi.editor.ex.RangeHighlighterEx;\r
-import com.intellij.openapi.editor.markup.GutterIconRenderer;\r
-import com.intellij.openapi.editor.markup.TextAttributes;\r
-import com.intellij.openapi.util.Comparing;\r
-import com.intellij.openapi.util.Pair;\r
-import com.intellij.openapi.util.TextRange;\r
-import com.intellij.profile.codeInspection.InspectionProjectProfileManager;\r
-import com.intellij.psi.PsiElement;\r
-import com.intellij.psi.impl.source.SourceTreeToPsiMap;\r
-import com.intellij.util.ArrayUtil;\r
-import com.intellij.xml.util.XmlStringUtil;\r
-import org.jetbrains.annotations.NonNls;\r
-import org.jetbrains.annotations.NotNull;\r
-import org.jetbrains.annotations.Nullable;\r
-\r
-import javax.swing.*;\r
-import java.awt.*;\r
-import java.util.Arrays;\r
-import java.util.List;\r
-\r
-public class HighlightInfo {\r
-  public static final HighlightInfo[] EMPTY_ARRAY = new HighlightInfo[0];\r
-  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.HighlightInfo");\r
-  private final boolean myNeedsUpdateOnTyping;\r
-  public JComponent fileLevelComponent;\r
-  public final TextAttributes forcedTextAttributes;\r
-\r
-  public HighlightSeverity getSeverity() {\r
-    return severity;\r
-  }\r
-\r
-  public TextAttributes getTextAttributes(final PsiElement element) {\r
-    return forcedTextAttributes == null ? getAttributesByType(element, type) : forcedTextAttributes;\r
-  }\r
-\r
-  public static TextAttributes getAttributesByType(@Nullable final PsiElement element, @NotNull HighlightInfoType type) {\r
-    final TextAttributes textAttributes = SeverityRegistrar.getInstance(element != null ? element.getProject() : null).getTextAttributesBySeverity(type.getSeverity(element));\r
-    if (textAttributes != null) {\r
-      return textAttributes;\r
-    }\r
-    EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();\r
-    TextAttributesKey key = type.getAttributesKey();\r
-    return scheme.getAttributes(key);\r
-  }\r
-\r
-  @Nullable\r
-  public Color getErrorStripeMarkColor(final PsiElement element) {\r
-    if (forcedTextAttributes != null && forcedTextAttributes.getErrorStripeColor() != null) {\r
-      return forcedTextAttributes.getErrorStripeColor();\r
-    }\r
-    if (severity == HighlightSeverity.ERROR) {\r
-      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.ERRORS_ATTRIBUTES).getErrorStripeColor();\r
-    }\r
-    if (severity == HighlightSeverity.WARNING) {\r
-      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.WARNINGS_ATTRIBUTES).getErrorStripeColor();\r
-    }\r
-    if (severity == HighlightSeverity.INFO){\r
-      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.INFO_ATTRIBUTES).getErrorStripeColor();\r
-    }\r
-    if (severity == HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING) {\r
-      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING).getErrorStripeColor();\r
-    }\r
-\r
-    TextAttributes attributes = getAttributesByType(element, type);\r
-    return attributes == null ? null : attributes.getErrorStripeColor();\r
-\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description) {\r
-    return createHighlightInfo(type, element, description, htmlEscapeToolTip(description));\r
-  }\r
-\r
-  @Nullable\r
-  @NonNls\r
-  public static String htmlEscapeToolTip(String description) {\r
-    return description == null ? null : "<html><body>"+ XmlStringUtil.escapeString(description)+"</body></html>";\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description, String toolTip) {\r
-    TextRange range = element.getTextRange();\r
-    int start = range.getStartOffset();\r
-    int end = range.getEndOffset();\r
-    return createHighlightInfo(type, element, start, end, description, toolTip);\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description,\r
-                                                  String toolTip,\r
-                                                  boolean isEndOfLine,\r
-                                                  TextAttributes forcedAttributes) {\r
-    LOG.assertTrue(ArrayUtil.find(HighlightSeverity.DEFAULT_SEVERITIES, type.getSeverity(element)) != -1 || element != null, "Custom type demands element to detect text attributes");\r
-    HighlightInfo highlightInfo = new HighlightInfo(forcedAttributes, type, start, end, description, toolTip, type.getSeverity(null), isEndOfLine, null, false);\r
-    for (HighlightInfoFilter filter : getFilters()) {\r
-      if (!filter.accept(highlightInfo, element != null ? element.getContainingFile() : null)) {\r
-        return null;\r
-      }\r
-    }\r
-    return highlightInfo;\r
-  }\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description, String toolTip) {\r
-    return createHighlightInfo(type, element, start, end, description, toolTip, false, null);\r
-  }\r
-\r
-  @NotNull private static HighlightInfoFilter[] getFilters() {\r
-    return ApplicationManager.getApplication().getExtensions(HighlightInfoFilter.EXTENSION_POINT_NAME);\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, int start, int end, String description) {\r
-    return createHighlightInfo(type, null, start, end, description, htmlEscapeToolTip(description));\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull TextRange textRange, String description) {\r
-    return createHighlightInfo(type, textRange.getStartOffset(), textRange.getEndOffset(), description);\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull TextRange textRange, String description, String toolTip, TextAttributes textAttributes) {\r
-    // do not use HighlightInfoFilter\r
-    return new HighlightInfo(textAttributes, type, textRange.getStartOffset(), textRange.getEndOffset(), description, htmlEscapeToolTip(toolTip),type.getSeverity(null), false, null,\r
-                             false);\r
-  }\r
-\r
-  public boolean needUpdateOnTyping() {\r
-    return myNeedsUpdateOnTyping;\r
-  }\r
-\r
-  public final HighlightInfoType type;\r
-  public int group;\r
-  public final int startOffset;\r
-  public final int endOffset;\r
-\r
-  public int fixStartOffset;\r
-  public int fixEndOffset;\r
-  public RangeMarker fixMarker;\r
-\r
-  public final String description;\r
-  public final String toolTip;\r
-  public final HighlightSeverity severity;\r
-\r
-  public final boolean isAfterEndOfLine;\r
-  public final boolean isFileLevelAnnotation;\r
-  public int navigationShift = 0;\r
-\r
-  public RangeHighlighterEx highlighter;\r
-  public String text;\r
-\r
-  public List<Pair<IntentionActionDescriptor, TextRange>> quickFixActionRanges;\r
-  public List<Pair<IntentionActionDescriptor, RangeMarker>> quickFixActionMarkers;\r
-  private boolean hasHint;\r
-\r
-  private GutterIconRenderer gutterIconRenderer;\r
-\r
-  public HighlightInfo(HighlightInfoType type, int startOffset, int endOffset, String description, String toolTip) {\r
-    this(null, type, startOffset, endOffset, description, toolTip, type.getSeverity(null), false, null, false);\r
-  }\r
-\r
-  public HighlightInfo(@Nullable TextAttributes textAttributes,\r
-                       @NotNull HighlightInfoType type,\r
-                       int startOffset,\r
-                       int endOffset,\r
-                       @Nullable String description,\r
-                       @Nullable String toolTip,\r
-                       @NotNull HighlightSeverity severity,\r
-                       boolean afterEndOfLine,\r
-                       @Nullable Boolean needsUpdateOnTyping, boolean isFileLevelAnnotation) {\r
-    if (startOffset < 0 || startOffset > endOffset) {\r
-      LOG.error("Incorrect highlightInfo bounds. description="+description+"; startOffset="+startOffset+"; endOffset="+endOffset+";type="+type);\r
-    }\r
-    forcedTextAttributes = textAttributes;\r
-    this.type = type;\r
-    this.startOffset = startOffset;\r
-    this.endOffset = endOffset;\r
-    fixStartOffset = startOffset;\r
-    fixEndOffset = endOffset;\r
-    this.description = description;\r
-    this.toolTip = toolTip;\r
-    this.severity = severity;\r
-    isAfterEndOfLine = afterEndOfLine;\r
-    myNeedsUpdateOnTyping = calcNeedUpdateOnTyping(needsUpdateOnTyping, type);\r
-    this.isFileLevelAnnotation = isFileLevelAnnotation;\r
-  }\r
-\r
-  private static boolean calcNeedUpdateOnTyping(Boolean needsUpdateOnTyping, HighlightInfoType type) {\r
-    if (needsUpdateOnTyping != null) return needsUpdateOnTyping.booleanValue();\r
-\r
-    if (type == HighlightInfoType.TODO) return false;\r
-    if (type == HighlightInfoType.LOCAL_VARIABLE) return false;\r
-    if (type == HighlightInfoType.INSTANCE_FIELD) return false;\r
-    if (type == HighlightInfoType.STATIC_FIELD) return false;\r
-    if (type == HighlightInfoType.PARAMETER) return false;\r
-    if (type == HighlightInfoType.METHOD_CALL) return false;\r
-    if (type == HighlightInfoType.METHOD_DECLARATION) return false;\r
-    if (type == HighlightInfoType.STATIC_METHOD) return false;\r
-    if (type == HighlightInfoType.CONSTRUCTOR_CALL) return false;\r
-    if (type == HighlightInfoType.CONSTRUCTOR_DECLARATION) return false;\r
-    if (type == HighlightInfoType.INTERFACE_NAME) return false;\r
-    if (type == HighlightInfoType.ABSTRACT_CLASS_NAME) return false;\r
-    if (type == HighlightInfoType.CLASS_NAME) return false;\r
-    return true;\r
-  }\r
-\r
-  public boolean equals(Object obj) {\r
-    if (obj == this) return true;\r
-    if (!(obj instanceof HighlightInfo)) return false;\r
-    HighlightInfo info = (HighlightInfo)obj;\r
-\r
-    return info.getSeverity() == getSeverity() &&\r
-           info.startOffset == startOffset &&\r
-           info.endOffset == endOffset &&\r
-           Comparing.equal(info.type, type) &&\r
-           Comparing.equal(info.gutterIconRenderer, gutterIconRenderer) &&\r
-           Comparing.equal(info.forcedTextAttributes, forcedTextAttributes) &&\r
-           Comparing.strEqual(info.description, description);\r
-  }\r
-\r
-  public int hashCode() {\r
-    return startOffset;\r
-  }\r
-\r
-  @NonNls\r
-  public String toString() {\r
-    @NonNls String s = "HighlightInfo(" + startOffset + "," + endOffset+")";\r
-    if (getActualStartOffset() != startOffset || getActualEndOffset() != endOffset) {\r
-      s += "; actual: (" + getActualStartOffset() + "," + getActualEndOffset() + ")";\r
-    }\r
-    if (text != null) s += " text='" + text + "'";\r
-    if (description != null) s+= ", description='" + description + "'";\r
-    if (toolTip != null) s+= ", toolTip='" + toolTip + "'";\r
-    s += " severity=" + severity;\r
-    return s;\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull ASTNode childByRole, String localizedMessage) {\r
-    return createHighlightInfo(type, SourceTreeToPsiMap.treeElementToPsi(childByRole), localizedMessage);\r
-  }\r
-\r
-  public GutterIconRenderer getGutterIconRenderer() {\r
-    return gutterIconRenderer;\r
-  }\r
-\r
-  public void setGutterIconRenderer(final GutterIconRenderer gutterIconRenderer) {\r
-    this.gutterIconRenderer = gutterIconRenderer;\r
-  }\r
-\r
-  public static HighlightInfo createHighlightInfo(@NotNull final HighlightInfoType type,\r
-                                                  @NotNull final PsiElement element,\r
-                                                  final String message,\r
-                                                  final TextAttributes attributes) {\r
-    TextRange textRange = element.getTextRange();\r
-    // do not use HighlightInfoFilter\r
-    return new HighlightInfo(attributes, type, textRange.getStartOffset(), textRange.getEndOffset(), message, htmlEscapeToolTip(message),\r
-                             type.getSeverity(element), false, Boolean.FALSE, false);\r
-  }\r
-\r
-\r
-\r
-  public static HighlightInfo fromAnnotation(@NotNull Annotation annotation) {\r
-    return fromAnnotation(annotation, null);\r
-  }\r
-\r
-  public static HighlightInfo fromAnnotation(@NotNull Annotation annotation, @Nullable TextRange fixedRange) {\r
-    TextAttributes attributes = annotation.getEnforcedTextAttributes();\r
-    if (attributes == null) {\r
-      attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(annotation.getTextAttributes());\r
-    }\r
-    HighlightInfo info = new HighlightInfo(attributes, convertType(annotation),\r
-                                           fixedRange != null? fixedRange.getStartOffset() : annotation.getStartOffset(),\r
-                                           fixedRange != null? fixedRange.getEndOffset() : annotation.getEndOffset(),\r
-                                           annotation.getMessage(), annotation.getTooltip(),\r
-                                           annotation.getSeverity(), annotation.isAfterEndOfLine(), annotation.needsUpdateOnTyping(), annotation.isFileLevelAnnotation());\r
-    info.setGutterIconRenderer(annotation.getGutterIconRenderer());\r
-    List<Annotation.QuickFixInfo> fixes = annotation.getQuickFixes();\r
-    if (fixes != null) {\r
-      for (final Annotation.QuickFixInfo quickFixInfo : fixes) {\r
-        QuickFixAction.registerQuickFixAction(info, fixedRange != null? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, quickFixInfo.key);\r
-      }\r
-    }\r
-    return info;\r
-  }\r
-\r
-  public static HighlightInfoType convertType(Annotation annotation) {\r
-    ProblemHighlightType type = annotation.getHighlightType();\r
-    if (type == ProblemHighlightType.LIKE_UNUSED_SYMBOL) return HighlightInfoType.UNUSED_SYMBOL;\r
-    if (type == ProblemHighlightType.LIKE_UNKNOWN_SYMBOL) return HighlightInfoType.WRONG_REF;\r
-    if (type == ProblemHighlightType.LIKE_DEPRECATED) return HighlightInfoType.DEPRECATED;\r
-    return convertSeverity(annotation.getSeverity());\r
-  }\r
-\r
-  public static HighlightInfoType convertSeverity(final HighlightSeverity severity) {\r
-    return severity == HighlightSeverity.ERROR\r
-           ? HighlightInfoType.ERROR\r
-           : severity == HighlightSeverity.WARNING ? HighlightInfoType.WARNING\r
-             : severity == HighlightSeverity.INFO ? HighlightInfoType.INFO : HighlightInfoType.INFORMATION;\r
-  }\r
-\r
-  public static ProblemHighlightType convertType(HighlightInfoType infoType) {\r
-    if (infoType == HighlightInfoType.ERROR || infoType == HighlightInfoType.WRONG_REF) return ProblemHighlightType.ERROR;\r
-    if (infoType == HighlightInfoType.WARNING) return ProblemHighlightType.GENERIC_ERROR_OR_WARNING;\r
-    if (infoType == HighlightInfoType.INFORMATION) return ProblemHighlightType.INFORMATION;\r
-    return ProblemHighlightType.INFO;\r
-  }\r
-\r
-  public static ProblemHighlightType convertSeverityToProblemHighlight(HighlightSeverity severity) {\r
-    return severity == HighlightSeverity.ERROR? ProblemHighlightType.ERROR :\r
-           severity == HighlightSeverity.WARNING ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING :\r
-             severity == HighlightSeverity.INFO ? ProblemHighlightType.INFO : ProblemHighlightType.INFORMATION;\r
-  }\r
-\r
-\r
-  public boolean hasHint() {\r
-    return hasHint;\r
-  }\r
-\r
-  public void setHint(final boolean hasHint) {\r
-    this.hasHint = hasHint;\r
-  }\r
-\r
-  public int getActualStartOffset() {\r
-    return highlighter == null ? startOffset : highlighter.getStartOffset();\r
-  }\r
-  public int getActualEndOffset() {\r
-    return highlighter == null ? endOffset : highlighter.getEndOffset();\r
-  }\r
-\r
-  public static class IntentionActionDescriptor {\r
-    private final IntentionAction myAction;\r
-    private volatile List<IntentionAction> myOptions;\r
-    private HighlightDisplayKey myKey;\r
-    private final String myDisplayName;\r
-    private final Icon myIcon;\r
-\r
-    public IntentionActionDescriptor(@NotNull IntentionAction action, final HighlightDisplayKey key) {\r
-      this(action, null, HighlightDisplayKey.getDisplayNameByKey(key), null);\r
-      myKey = key;\r
-    }\r
-\r
-    public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName) {\r
-      this(action, options, displayName, null);\r
-    }\r
-\r
-    public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName, Icon icon) {\r
-      myAction = action;\r
-      myOptions = options;\r
-      myDisplayName = displayName;\r
-      myIcon = icon;\r
-    }\r
-\r
-    @NotNull\r
-    public IntentionAction getAction() {\r
-      return myAction;\r
-    }\r
-\r
-    @Nullable\r
-    public List<IntentionAction> getOptions(@NotNull PsiElement element) {\r
-      if (myOptions == null && myKey != null) {\r
-        List<IntentionAction> options = IntentionManager.getInstance().getStandardIntentionOptions(myKey, element);\r
-        InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();\r
-        InspectionProfileEntry tool = profile.getInspectionTool(myKey.toString(), element);\r
-        if (!(tool instanceof LocalInspectionToolWrapper)) {\r
-          HighlightDisplayKey key = HighlightDisplayKey.findById(myKey.toString());\r
-          if (key != null) {\r
-            tool = profile.getInspectionTool(key.toString(), element);\r
-          }\r
-        }\r
-        if (tool instanceof LocalInspectionToolWrapper) {\r
-          final LocalInspectionTool localInspectionTool = ((LocalInspectionToolWrapper)tool).getTool();\r
-          Class aClass = myAction.getClass();\r
-          if (myAction instanceof QuickFixWrapper) {\r
-            aClass = ((QuickFixWrapper)myAction).getFix().getClass();\r
-          }\r
-          options.add(new CleanupInspectionIntention(localInspectionTool, aClass));\r
-          if (localInspectionTool instanceof CustomSuppressableInspectionTool) {\r
-            final IntentionAction[] suppressActions = ((CustomSuppressableInspectionTool)localInspectionTool).getSuppressActions(element);\r
-            if (suppressActions != null) {\r
-              options.addAll(Arrays.asList(suppressActions));\r
-            }\r
-          }\r
-        }\r
-        myKey = null;\r
-        synchronized (this) {\r
-          if (myOptions == null) {\r
-            myOptions = options;\r
-          }\r
-        }\r
-      }\r
-      return myOptions;\r
-    }\r
-\r
-    public String getDisplayName() {\r
-      return myDisplayName;\r
-    }\r
-\r
-    @NonNls\r
-    public String toString() {\r
-      return "descriptor: " + getAction().getText();\r
-    }\r
-\r
-    public Icon getIcon() {\r
-      return myIcon;\r
-    }\r
-  }\r
-}\r
+/*
+ * 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.impl;
+
+import com.intellij.codeInsight.daemon.HighlightDisplayKey;
+import com.intellij.codeInsight.daemon.impl.quickfix.QuickFixAction;
+import com.intellij.codeInsight.intention.IntentionAction;
+import com.intellij.codeInsight.intention.IntentionManager;
+import com.intellij.codeInspection.*;
+import com.intellij.codeInspection.actions.CleanupInspectionIntention;
+import com.intellij.codeInspection.ex.LocalInspectionToolWrapper;
+import com.intellij.codeInspection.ex.QuickFixWrapper;
+import com.intellij.lang.ASTNode;
+import com.intellij.lang.annotation.Annotation;
+import com.intellij.lang.annotation.HighlightSeverity;
+import com.intellij.openapi.application.ApplicationManager;
+import com.intellij.openapi.diagnostic.Logger;
+import com.intellij.openapi.editor.RangeMarker;
+import com.intellij.openapi.editor.colors.CodeInsightColors;
+import com.intellij.openapi.editor.colors.EditorColorsManager;
+import com.intellij.openapi.editor.colors.EditorColorsScheme;
+import com.intellij.openapi.editor.colors.TextAttributesKey;
+import com.intellij.openapi.editor.ex.RangeHighlighterEx;
+import com.intellij.openapi.editor.markup.GutterIconRenderer;
+import com.intellij.openapi.editor.markup.TextAttributes;
+import com.intellij.openapi.util.Comparing;
+import com.intellij.openapi.util.Pair;
+import com.intellij.openapi.util.TextRange;
+import com.intellij.profile.codeInspection.InspectionProjectProfileManager;
+import com.intellij.psi.PsiElement;
+import com.intellij.psi.impl.source.SourceTreeToPsiMap;
+import com.intellij.util.ArrayUtil;
+import com.intellij.xml.util.XmlStringUtil;
+import org.jetbrains.annotations.NonNls;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+import javax.swing.*;
+import java.awt.*;
+import java.util.Arrays;
+import java.util.List;
+
+public class HighlightInfo {
+  public static final HighlightInfo[] EMPTY_ARRAY = new HighlightInfo[0];
+  private static final Logger LOG = Logger.getInstance("#com.intellij.codeInsight.daemon.impl.HighlightInfo");
+  private final boolean myNeedsUpdateOnTyping;
+  public JComponent fileLevelComponent;
+  public final TextAttributes forcedTextAttributes;
+
+  public HighlightSeverity getSeverity() {
+    return severity;
+  }
+
+  public TextAttributes getTextAttributes(final PsiElement element) {
+    return forcedTextAttributes == null ? getAttributesByType(element, type) : forcedTextAttributes;
+  }
+
+  public static TextAttributes getAttributesByType(@Nullable final PsiElement element, @NotNull HighlightInfoType type) {
+    final TextAttributes textAttributes = SeverityRegistrar.getInstance(element != null ? element.getProject() : null).getTextAttributesBySeverity(type.getSeverity(element));
+    if (textAttributes != null) {
+      return textAttributes;
+    }
+    EditorColorsScheme scheme = EditorColorsManager.getInstance().getGlobalScheme();
+    TextAttributesKey key = type.getAttributesKey();
+    return scheme.getAttributes(key);
+  }
+
+  @Nullable
+  public Color getErrorStripeMarkColor(final PsiElement element) {
+    if (forcedTextAttributes != null && forcedTextAttributes.getErrorStripeColor() != null) {
+      return forcedTextAttributes.getErrorStripeColor();
+    }
+    if (severity == HighlightSeverity.ERROR) {
+      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.ERRORS_ATTRIBUTES).getErrorStripeColor();
+    }
+    if (severity == HighlightSeverity.WARNING) {
+      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.WARNINGS_ATTRIBUTES).getErrorStripeColor();
+    }
+    if (severity == HighlightSeverity.INFO){
+      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.INFO_ATTRIBUTES).getErrorStripeColor();
+    }
+    if (severity == HighlightSeverity.GENERIC_SERVER_ERROR_OR_WARNING) {
+      return EditorColorsManager.getInstance().getGlobalScheme().getAttributes(CodeInsightColors.GENERIC_SERVER_ERROR_OR_WARNING).getErrorStripeColor();
+    }
+
+    TextAttributes attributes = getAttributesByType(element, type);
+    return attributes == null ? null : attributes.getErrorStripeColor();
+
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description) {
+    return createHighlightInfo(type, element, description, htmlEscapeToolTip(description));
+  }
+
+  @Nullable
+  @NonNls
+  public static String htmlEscapeToolTip(String description) {
+    return description == null ? null : "<html><body>"+ XmlStringUtil.escapeString(description)+"</body></html>";
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull PsiElement element, String description, String toolTip) {
+    TextRange range = element.getTextRange();
+    int start = range.getStartOffset();
+    int end = range.getEndOffset();
+    return createHighlightInfo(type, element, start, end, description, toolTip);
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description,
+                                                  String toolTip,
+                                                  boolean isEndOfLine,
+                                                  TextAttributes forcedAttributes) {
+    LOG.assertTrue(ArrayUtil.find(HighlightSeverity.DEFAULT_SEVERITIES, type.getSeverity(element)) != -1 || element != null, "Custom type demands element to detect text attributes");
+    HighlightInfo highlightInfo = new HighlightInfo(forcedAttributes, type, start, end, description, toolTip, type.getSeverity(null), isEndOfLine, null, false);
+    for (HighlightInfoFilter filter : getFilters()) {
+      if (!filter.accept(highlightInfo, element != null ? element.getContainingFile() : null)) {
+        return null;
+      }
+    }
+    return highlightInfo;
+  }
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @Nullable PsiElement element, int start, int end, String description, String toolTip) {
+    return createHighlightInfo(type, element, start, end, description, toolTip, false, null);
+  }
+
+  @NotNull private static HighlightInfoFilter[] getFilters() {
+    return ApplicationManager.getApplication().getExtensions(HighlightInfoFilter.EXTENSION_POINT_NAME);
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, int start, int end, String description) {
+    return createHighlightInfo(type, null, start, end, description, htmlEscapeToolTip(description));
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull TextRange textRange, String description) {
+    return createHighlightInfo(type, textRange.getStartOffset(), textRange.getEndOffset(), description);
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull TextRange textRange, String description, String toolTip, TextAttributes textAttributes) {
+    // do not use HighlightInfoFilter
+    return new HighlightInfo(textAttributes, type, textRange.getStartOffset(), textRange.getEndOffset(), description, htmlEscapeToolTip(toolTip),type.getSeverity(null), false, null,
+                             false);
+  }
+
+  public boolean needUpdateOnTyping() {
+    return myNeedsUpdateOnTyping;
+  }
+
+  public final HighlightInfoType type;
+  public int group;
+  public final int startOffset;
+  public final int endOffset;
+
+  public int fixStartOffset;
+  public int fixEndOffset;
+  public RangeMarker fixMarker;
+
+  public final String description;
+  public final String toolTip;
+  public final HighlightSeverity severity;
+
+  public final boolean isAfterEndOfLine;
+  public final boolean isFileLevelAnnotation;
+  public int navigationShift = 0;
+
+  public RangeHighlighterEx highlighter;
+  public String text;
+
+  public List<Pair<IntentionActionDescriptor, TextRange>> quickFixActionRanges;
+  public List<Pair<IntentionActionDescriptor, RangeMarker>> quickFixActionMarkers;
+  private boolean hasHint;
+
+  private GutterIconRenderer gutterIconRenderer;
+
+  public HighlightInfo(HighlightInfoType type, int startOffset, int endOffset, String description, String toolTip) {
+    this(null, type, startOffset, endOffset, description, toolTip, type.getSeverity(null), false, null, false);
+  }
+
+  public HighlightInfo(@Nullable TextAttributes textAttributes,
+                       @NotNull HighlightInfoType type,
+                       int startOffset,
+                       int endOffset,
+                       @Nullable String description,
+                       @Nullable String toolTip,
+                       @NotNull HighlightSeverity severity,
+                       boolean afterEndOfLine,
+                       @Nullable Boolean needsUpdateOnTyping, boolean isFileLevelAnnotation) {
+    if (startOffset < 0 || startOffset > endOffset) {
+      LOG.error("Incorrect highlightInfo bounds. description="+description+"; startOffset="+startOffset+"; endOffset="+endOffset+";type="+type);
+    }
+    forcedTextAttributes = textAttributes;
+    this.type = type;
+    this.startOffset = startOffset;
+    this.endOffset = endOffset;
+    fixStartOffset = startOffset;
+    fixEndOffset = endOffset;
+    this.description = description;
+    this.toolTip = toolTip;
+    this.severity = severity;
+    isAfterEndOfLine = afterEndOfLine;
+    myNeedsUpdateOnTyping = calcNeedUpdateOnTyping(needsUpdateOnTyping, type);
+    this.isFileLevelAnnotation = isFileLevelAnnotation;
+  }
+
+  private static boolean calcNeedUpdateOnTyping(Boolean needsUpdateOnTyping, HighlightInfoType type) {
+    if (needsUpdateOnTyping != null) return needsUpdateOnTyping.booleanValue();
+
+    if (type == HighlightInfoType.TODO) return false;
+    if (type == HighlightInfoType.LOCAL_VARIABLE) return false;
+    if (type == HighlightInfoType.INSTANCE_FIELD) return false;
+    if (type == HighlightInfoType.STATIC_FIELD) return false;
+    if (type == HighlightInfoType.PARAMETER) return false;
+    if (type == HighlightInfoType.METHOD_CALL) return false;
+    if (type == HighlightInfoType.METHOD_DECLARATION) return false;
+    if (type == HighlightInfoType.STATIC_METHOD) return false;
+    if (type == HighlightInfoType.CONSTRUCTOR_CALL) return false;
+    if (type == HighlightInfoType.CONSTRUCTOR_DECLARATION) return false;
+    if (type == HighlightInfoType.INTERFACE_NAME) return false;
+    if (type == HighlightInfoType.ABSTRACT_CLASS_NAME) return false;
+    if (type == HighlightInfoType.CLASS_NAME) return false;
+    return true;
+  }
+
+  public boolean equals(Object obj) {
+    if (obj == this) return true;
+    if (!(obj instanceof HighlightInfo)) return false;
+    HighlightInfo info = (HighlightInfo)obj;
+
+    return info.getSeverity() == getSeverity() &&
+           info.startOffset == startOffset &&
+           info.endOffset == endOffset &&
+           Comparing.equal(info.type, type) &&
+           Comparing.equal(info.gutterIconRenderer, gutterIconRenderer) &&
+           Comparing.equal(info.forcedTextAttributes, forcedTextAttributes) &&
+           Comparing.strEqual(info.description, description);
+  }
+
+  public int hashCode() {
+    return startOffset;
+  }
+
+  @NonNls
+  public String toString() {
+    @NonNls String s = "HighlightInfo(" + startOffset + "," + endOffset+")";
+    if (getActualStartOffset() != startOffset || getActualEndOffset() != endOffset) {
+      s += "; actual: (" + getActualStartOffset() + "," + getActualEndOffset() + ")";
+    }
+    if (text != null) s += " text='" + text + "'";
+    if (description != null) s+= ", description='" + description + "'";
+    if (toolTip != null) s+= ", toolTip='" + toolTip + "'";
+    s += " severity=" + severity;
+    return s;
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull HighlightInfoType type, @NotNull ASTNode childByRole, String localizedMessage) {
+    return createHighlightInfo(type, SourceTreeToPsiMap.treeElementToPsi(childByRole), localizedMessage);
+  }
+
+  public GutterIconRenderer getGutterIconRenderer() {
+    return gutterIconRenderer;
+  }
+
+  public void setGutterIconRenderer(final GutterIconRenderer gutterIconRenderer) {
+    this.gutterIconRenderer = gutterIconRenderer;
+  }
+
+  public static HighlightInfo createHighlightInfo(@NotNull final HighlightInfoType type,
+                                                  @NotNull final PsiElement element,
+                                                  final String message,
+                                                  final TextAttributes attributes) {
+    TextRange textRange = element.getTextRange();
+    // do not use HighlightInfoFilter
+    return new HighlightInfo(attributes, type, textRange.getStartOffset(), textRange.getEndOffset(), message, htmlEscapeToolTip(message),
+                             type.getSeverity(element), false, Boolean.FALSE, false);
+  }
+
+
+
+  public static HighlightInfo fromAnnotation(@NotNull Annotation annotation) {
+    return fromAnnotation(annotation, null);
+  }
+
+  public static HighlightInfo fromAnnotation(@NotNull Annotation annotation, @Nullable TextRange fixedRange) {
+    TextAttributes attributes = annotation.getEnforcedTextAttributes();
+    if (attributes == null) {
+      attributes = EditorColorsManager.getInstance().getGlobalScheme().getAttributes(annotation.getTextAttributes());
+    }
+    HighlightInfo info = new HighlightInfo(attributes, convertType(annotation),
+                                           fixedRange != null? fixedRange.getStartOffset() : annotation.getStartOffset(),
+                                           fixedRange != null? fixedRange.getEndOffset() : annotation.getEndOffset(),
+                                           annotation.getMessage(), annotation.getTooltip(),
+                                           annotation.getSeverity(), annotation.isAfterEndOfLine(), annotation.needsUpdateOnTyping(), annotation.isFileLevelAnnotation());
+    info.setGutterIconRenderer(annotation.getGutterIconRenderer());
+    List<Annotation.QuickFixInfo> fixes = annotation.getQuickFixes();
+    if (fixes != null) {
+      for (final Annotation.QuickFixInfo quickFixInfo : fixes) {
+        QuickFixAction.registerQuickFixAction(info, fixedRange != null? fixedRange : quickFixInfo.textRange, quickFixInfo.quickFix, quickFixInfo.key);
+      }
+    }
+    return info;
+  }
+
+  public static HighlightInfoType convertType(Annotation annotation) {
+    ProblemHighlightType type = annotation.getHighlightType();
+    if (type == ProblemHighlightType.LIKE_UNUSED_SYMBOL) return HighlightInfoType.UNUSED_SYMBOL;
+    if (type == ProblemHighlightType.LIKE_UNKNOWN_SYMBOL) return HighlightInfoType.WRONG_REF;
+    if (type == ProblemHighlightType.LIKE_DEPRECATED) return HighlightInfoType.DEPRECATED;
+    return convertSeverity(annotation.getSeverity());
+  }
+
+  public static HighlightInfoType convertSeverity(final HighlightSeverity severity) {
+    return severity == HighlightSeverity.ERROR
+           ? HighlightInfoType.ERROR
+           : severity == HighlightSeverity.WARNING ? HighlightInfoType.WARNING
+             : severity == HighlightSeverity.INFO ? HighlightInfoType.INFO : HighlightInfoType.INFORMATION;
+  }
+
+  public static ProblemHighlightType convertType(HighlightInfoType infoType) {
+    if (infoType == HighlightInfoType.ERROR || infoType == HighlightInfoType.WRONG_REF) return ProblemHighlightType.ERROR;
+    if (infoType == HighlightInfoType.WARNING) return ProblemHighlightType.GENERIC_ERROR_OR_WARNING;
+    if (infoType == HighlightInfoType.INFORMATION) return ProblemHighlightType.INFORMATION;
+    return ProblemHighlightType.INFO;
+  }
+
+  public static ProblemHighlightType convertSeverityToProblemHighlight(HighlightSeverity severity) {
+    return severity == HighlightSeverity.ERROR? ProblemHighlightType.ERROR :
+           severity == HighlightSeverity.WARNING ? ProblemHighlightType.GENERIC_ERROR_OR_WARNING :
+             severity == HighlightSeverity.INFO ? ProblemHighlightType.INFO : ProblemHighlightType.INFORMATION;
+  }
+
+
+  public boolean hasHint() {
+    return hasHint;
+  }
+
+  public void setHint(final boolean hasHint) {
+    this.hasHint = hasHint;
+  }
+
+  public int getActualStartOffset() {
+    return highlighter == null ? startOffset : highlighter.getStartOffset();
+  }
+  public int getActualEndOffset() {
+    return highlighter == null ? endOffset : highlighter.getEndOffset();
+  }
+
+  public static class IntentionActionDescriptor {
+    private final IntentionAction myAction;
+    private volatile List<IntentionAction> myOptions;
+    private HighlightDisplayKey myKey;
+    private final String myDisplayName;
+    private final Icon myIcon;
+
+    public IntentionActionDescriptor(@NotNull IntentionAction action, final HighlightDisplayKey key) {
+      this(action, null, HighlightDisplayKey.getDisplayNameByKey(key), null);
+      myKey = key;
+    }
+
+    public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName) {
+      this(action, options, displayName, null);
+    }
+
+    public IntentionActionDescriptor(@NotNull IntentionAction action, final List<IntentionAction> options, final String displayName, Icon icon) {
+      myAction = action;
+      myOptions = options;
+      myDisplayName = displayName;
+      myIcon = icon;
+    }
+
+    @NotNull
+    public IntentionAction getAction() {
+      return myAction;
+    }
+
+    @Nullable
+    public List<IntentionAction> getOptions(@NotNull PsiElement element) {
+      if (myOptions == null && myKey != null) {
+        List<IntentionAction> options = IntentionManager.getInstance().getStandardIntentionOptions(myKey, element);
+        InspectionProfile profile = InspectionProjectProfileManager.getInstance(element.getProject()).getInspectionProfile();
+        InspectionProfileEntry tool = profile.getInspectionTool(myKey.toString(), element);
+        if (!(tool instanceof LocalInspectionToolWrapper)) {
+          HighlightDisplayKey key = HighlightDisplayKey.findById(myKey.toString());
+          if (key != null) {
+            tool = profile.getInspectionTool(key.toString(), element);
+          }
+        }
+        if (tool instanceof LocalInspectionToolWrapper) {
+          final LocalInspectionTool localInspectionTool = ((LocalInspectionToolWrapper)tool).getTool();
+          Class aClass = myAction.getClass();
+          if (myAction instanceof QuickFixWrapper) {
+            aClass = ((QuickFixWrapper)myAction).getFix().getClass();
+          }
+          options.add(new CleanupInspectionIntention(localInspectionTool, aClass));
+          if (localInspectionTool instanceof CustomSuppressableInspectionTool) {
+            final IntentionAction[] suppressActions = ((CustomSuppressableInspectionTool)localInspectionTool).getSuppressActions(element);
+            if (suppressActions != null) {
+              options.addAll(Arrays.asList(suppressActions));
+            }
+          }
+        }
+        myKey = null;
+        synchronized (this) {
+          if (myOptions == null) {
+            myOptions = options;
+          }
+        }
+      }
+      return myOptions;
+    }
+
+    public String getDisplayName() {
+      return myDisplayName;
+    }
+
+    @NonNls
+    public String toString() {
+      return "descriptor: " + getAction().getText();
+    }
+
+    public Icon getIcon() {
+      return myIcon;
+    }
+  }
+}