@Nullable
  public static PsiFile resolveFile(XmlAttribute location, PsiFile baseFile) {
    if (location == null) return null;
    final XmlAttributeValue valueElement = location.getValueElement();
    if (valueElement == null) return null;

    // prefer direct relative path
    final String value = valueElement.getValue();
    final PsiFile file = resolveFile(value, baseFile);
    if (file != baseFile && file instanceof XmlFile) {
      return file;
    }

    final PsiReference[] references = valueElement.getReferences();
    for (PsiReference reference : references) {
      final PsiElement target = reference.resolve();
      if (target == null && reference instanceof PsiPolyVariantReference) {
        final ResolveResult[] results = ((PsiPolyVariantReference) reference).multiResolve(false);
        for (ResolveResult result : results) {
          if (result.isValidResult()) {
            // TODO: how to weigh/prioritize the results?
            final PsiElement element = result.getElement();
            if (element != baseFile && element instanceof XmlFile) {
              return (PsiFile) target;
            }
          }
        }
      } else if (target != baseFile && target instanceof XmlFile) {
        return (PsiFile) target;
      }
    }
    return null;
  }
 @NotNull
 public QualifiedResolveResult followAssignmentsChain(PyResolveContext resolveContext) {
   PyReferenceExpression seeker = this;
   QualifiedResolveResult ret = null;
   List<PyExpression> qualifiers = new ArrayList<PyExpression>();
   PyExpression qualifier = seeker.getQualifier();
   if (qualifier != null) {
     qualifiers.add(qualifier);
   }
   Set<PsiElement> visited = new HashSet<PsiElement>();
   visited.add(this);
   SEARCH:
   while (ret == null) {
     ResolveResult[] targets = seeker.getReference(resolveContext).multiResolve(false);
     for (ResolveResult target : targets) {
       PsiElement elt = target.getElement();
       if (elt instanceof PyTargetExpression) {
         PsiElement assigned_from = null;
         final PyTargetExpression expr = (PyTargetExpression) elt;
         final TypeEvalContext context = resolveContext.getTypeEvalContext();
         if (context.maySwitchToAST(expr) || expr.getStub() == null) {
           assigned_from = expr.findAssignedValue();
         }
         // TODO: Maybe findAssignedValueByStub() should become a part of the PyTargetExpression
         // interface
         else if (elt instanceof PyTargetExpressionImpl) {
           assigned_from = ((PyTargetExpressionImpl) elt).findAssignedValueByStub(context);
         }
         if (assigned_from instanceof PyReferenceExpression) {
           if (visited.contains(assigned_from)) {
             break;
           }
           visited.add(assigned_from);
           seeker = (PyReferenceExpression) assigned_from;
           if (seeker.getQualifier() != null) {
             qualifiers.add(seeker.getQualifier());
           }
           continue SEARCH;
         } else if (assigned_from != null)
           ret = new QualifiedResolveResultImpl(assigned_from, qualifiers, false);
       } else if (ret == null && elt instanceof PyElement && target.isValidResult()) {
         // remember this result, but a further reference may be the next resolve result
         ret =
             new QualifiedResolveResultImpl(
                 elt, qualifiers, target instanceof ImplicitResolveResult);
       }
     }
     // all resolve results checked, reassignment not detected, nothing more to do
     break;
   }
   if (ret == null) ret = EMPTY_RESULT;
   return ret;
 }
 /**
  * Returns number of different parameters in i18n message. For example, for string <i>Class {0}
  * info: Class {0} extends class {1} and implements interface {2}</i> number of parameters is 3.
  *
  * @param expression i18n literal
  * @return number of parameters
  */
 public static int getPropertyValueParamsMaxCount(final PsiLiteralExpression expression) {
   int maxCount = -1;
   for (PsiReference reference : expression.getReferences()) {
     if (reference instanceof PsiPolyVariantReference) {
       for (ResolveResult result : ((PsiPolyVariantReference) reference).multiResolve(false)) {
         if (result.isValidResult() && result.getElement() instanceof IProperty) {
           String value = ((IProperty) result.getElement()).getValue();
           MessageFormat format;
           try {
             format = new MessageFormat(value);
           } catch (Exception e) {
             continue; // ignore syntax error
           }
           try {
             int count = format.getFormatsByArgumentIndex().length;
             maxCount = Math.max(maxCount, count);
           } catch (IllegalArgumentException ignored) {
           }
         }
       }
     }
   }
   return maxCount;
 }