package com.intellij.xml.util;

import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.*;
import com.intellij.psi.xml.*;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.Nullable;

import java.util.ArrayList;
import java.util.List;

/**
 * @author mike
 */
public class XmlIncludeHandler implements PsiIncludeManager.PsiIncludeHandler {
  @NonNls private static final String INCLUDE_TAG_NAME = "include";

  public boolean shouldCheckFile(final VirtualFile psiFile) {
    return psiFile.getFileType() == StdFileTypes.XML;
  }

  public PsiIncludeManager.IncludeInfo[] findIncludes(final PsiFile psiFile) {
    final List<PsiIncludeManager.IncludeInfo> result = new ArrayList<PsiIncludeManager.IncludeInfo>();

    psiFile.accept(new PsiRecursiveElementVisitor() {
      public void visitXmlTag(final XmlTag tag) {

        if (isXInclude(tag)) {
          final XmlFile xmlFile = resolveXIncludeFile(tag);
          if (xmlFile != null) {
            result.add(new PsiIncludeManager.IncludeInfo(
              xmlFile,
              tag,
              new String[] {xmlFile.getName()}
            ));
          }
        }
        else {
          super.visitXmlTag(tag);
        }
      }
    });

    return result.toArray(new PsiIncludeManager.IncludeInfo[result.size()]);
  }

  public static boolean isXInclude(PsiElement element) {
    if (element instanceof XmlTag) {
      XmlTag xmlTag = (XmlTag)element;

      if (xmlTag.getParent() instanceof XmlDocument) return false;

      if (xmlTag.getLocalName().equals(INCLUDE_TAG_NAME)) {
        if (xmlTag.getNamespace().equals(XmlUtil.XINCLUDE_URI)) {
          return true;
        }
      }
    }

    return false;
  }

  @Nullable
  public static XmlFile resolveXIncludeFile(XmlTag xincludeTag) {
    final XmlAttribute hrefAttribute = xincludeTag.getAttribute("href", XmlUtil.XINCLUDE_URI);
    if (hrefAttribute == null) return null;

    final XmlAttributeValue xmlAttributeValue = hrefAttribute.getValueElement();
    if (xmlAttributeValue == null) return null;

    final PsiReference reference = xmlAttributeValue.getReference();
    if (reference == null) return null;

    final PsiElement target = reference.resolve();

    if (!(target instanceof XmlFile)) return null;
    return (XmlFile)target;
  }
}

@@ -25,16 +25,74 @@
 .util;%0A%0A
+import com.intellij.openapi.fileEditor.impl.LoadTextUtil;%0A
 import c
@@ -135,16 +135,16 @@
 eTypes;%0A
-
 import c
@@ -744,24 +744,115 @@
  psiFile) %7B%0A
+    if (!canContainIncludeTag(psiFile)) return PsiIncludeManager.IncludeInfo.EMPTY_ARRAY;%0A%0A
     final Li
@@ -1429,24 +1429,24 @@
  %7D%0A    %7D);%0A%0A
-
     return r
@@ -1511,24 +1511,352 @@
 e()%5D);%0A  %7D%0A%0A
+  private static boolean canContainIncludeTag(final PsiFile psiFile) %7B%0A    final VirtualFile virtualFile = psiFile.getVirtualFile();%0A%0A    final String text = LoadTextUtil.loadText(virtualFile).toString();%0A%0A    if (text.indexOf(INCLUDE_TAG_NAME) %3C 0 %7C%7C text.indexOf(XmlUtil.XINCLUDE_URI) %3C 0) return false;%0A    return true;%0A  %7D%0A%0A
   public sta

include checking optimization fix