/*
 * Copyright 2000-2009 JetBrains s.r.o.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 * http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

package com.intellij.codeInspection.reference;

import com.intellij.openapi.diagnostic.Logger;
import org.jdom.Element;
import org.jetbrains.annotations.NonNls;
import org.jetbrains.annotations.NotNull;

public class SmartRefElementPointerImpl implements SmartRefElementPointer {
  @NonNls public static final String FQNAME_ATTR = "FQNAME";
  @NonNls public static final String TYPE_ATTR = "TYPE";
  @NonNls public static final String ENTRY_POINT = "entry_point";
  private static final Logger LOG = Logger.getInstance(SmartRefElementPointerImpl.class);

  private final boolean myIsPersistent;
  private RefEntity myRefElement;
  private final String myFQName;
  private final String myType;

  public SmartRefElementPointerImpl(RefEntity ref, boolean isPersistent) {
      myIsPersistent = isPersistent;
      myRefElement = ref;
      myFQName = ref.getExternalName();
      myType = ref.getRefManager().getType(ref);
      LOG.assertTrue(myFQName != null, "Name: " + ref.getName() + ", qName: " + ref.getQualifiedName() + "; type: " + myType);
    }

  public SmartRefElementPointerImpl(Element jDomElement) {
    myIsPersistent = true;
    myRefElement = null;
    myFQName = jDomElement.getAttributeValue(FQNAME_ATTR);
    myType = jDomElement.getAttributeValue(TYPE_ATTR);
 }

  public SmartRefElementPointerImpl(final String type, final String fqName) {
     myIsPersistent = true;
     myFQName = fqName;
     myType = type;
   }

  @Override
  public boolean isPersistent() {
    return myIsPersistent;
  }

  @Override
  public String getFQName() {
    return myFQName;
  }

  @Override
  public RefEntity getRefElement() {
    return myRefElement;
  }

  @Override
  public void writeExternal(Element parentNode) {
    Element element = new Element(ENTRY_POINT);
    element.setAttribute(TYPE_ATTR, myType);
    element.setAttribute(FQNAME_ATTR, getFQName());
    parentNode.addContent(element);
  }

  @Override
  public boolean resolve(@NotNull RefManager manager) {
    if (myRefElement != null) {
      return myRefElement instanceof RefElement && myRefElement.isValid();
    }
    myRefElement = manager.getReference(myType, getFQName());
    return myRefElement != null;
  }

  @Override
  public void freeReference() {
    myRefElement = null;
  }
}

@@ -690,16 +690,97 @@
 Logger;%0A
+import com.intellij.psi.PsiFile;%0Aimport com.intellij.psi.SmartPsiElementPointer;%0A
 import o
@@ -796,16 +796,16 @@
 lement;%0A
-
 import o
@@ -878,16 +878,59 @@
 NotNull;
+%0Aimport org.jetbrains.annotations.Nullable;
 %0A%0Apublic
@@ -1709,67 +1709,286 @@
 () +
- %22, qName: %22 + ref.getQualifiedName() + %22; type: %22 + myType
+%0A                                       %22, qName: %22 + ref.getQualifiedName() +%0A                                       %22; type: %22 + myType +%0A                                       (ref instanceof RefElement ? (%22; containing file: %22 + getContainingFileName((RefElement)ref)) : %22%22)
 );%0A 
@@ -1989,24 +1989,25 @@
 %22));%0A    %7D%0A%0A
+%0A
   public Sma
@@ -3173,24 +3173,24 @@
 ference() %7B%0A
-
     myRefEle
@@ -3205,11 +3205,288 @@
 ull;%0A  %7D
+%0A%0A  @Nullable%0A  private String getContainingFileName(RefElement ref) %7B%0A    SmartPsiElementPointer pointer = ref.getPointer();%0A    if (pointer == null) return null;%0A    PsiFile file = pointer.getContainingFile();%0A    if (file == null) return null;%0A    return file.getName();%0A  %7D
 %0A%7D%0A

add more info to log message