public DeclarationLocation getLocation() {
      PythonTree node = element.getNode();
      int lineOffset = node != null ? node.getCharStartIndex() : -1;
      DeclarationLocation loc =
          new DeclarationLocation(element.getFileObject(), lineOffset, element);

      return loc;
    }
  private DeclarationLocation getDeclarationLocation(
      PythonParserResult info, IndexedElement candidate, Set<? extends IndexedElement> methods) {
    BaseDocument doc = (BaseDocument) info.getSnapshot().getSource().getDocument(false);
    if (doc == null) {
      return DeclarationLocation.NONE;
    }

    if (candidate != null) {
      FileObject fileObject = candidate.getFileObject();
      if (fileObject == null) {
        return DeclarationLocation.NONE;
      }

      PythonTree node = candidate.getNode();
      int nodeOffset = 0;
      if (node != null) {
        nodeOffset = PythonAstUtils.getNameRange(info, node).getStart();
      }

      DeclarationLocation loc = new DeclarationLocation(fileObject, nodeOffset, candidate);

      if (PythonUtils.isRstFile(fileObject)) {
        loc.setInvalidMessage(
            NbBundle.getMessage(
                PythonDeclarationFinder.class, "BuiltinPython", candidate.getName()));
        return loc;
      }

      if (methods.size() > 1) {
        // Could the :nodoc: alternatives: if there is only one nodoc'ed alternative
        // don't ask user!
        int not_nodoced = 0;
        for (final IndexedElement mtd : methods) {
          if (!mtd.isNoDoc()) {
            not_nodoced++;
          }
        }
        if (not_nodoced >= 2) {
          for (final IndexedElement mtd : methods) {
            loc.addAlternative(new PythonAltLocation(mtd, mtd == candidate));
          }
        }
      }

      return loc;
    }

    return DeclarationLocation.NONE;
  }
  /**
   * Compute the declaration location for a test string (such as MosModule::TestBaz/test_qux).
   *
   * @param fileInProject a file in the project where to perform the search
   * @param testString a string represening a test class and method, such as TestFoo/test_bar
   * @param classLocation if true, returns the location of the class rather then the method.
   */
  public static DeclarationLocation getTestDeclaration(
      FileObject fileInProject, String testString, boolean classLocation) {
    int methodIndex = testString.indexOf('/'); // NOI18N
    if (methodIndex == -1) {
      return DeclarationLocation.NONE;
    }

    String className = testString.substring(0, methodIndex);
    String methodName = testString.substring(methodIndex + 1);

    PythonIndex index = PythonIndex.get(fileInProject);
    Set<IndexedElement> elements =
        index.getAllMembers(methodName, QuerySupport.Kind.EXACT, null, true);
    // Look for one that matches our class name
    if (elements.size() > 0) {
      IndexedElement candidate = null;
      for (IndexedElement element : elements) {
        if (element instanceof IndexedMethod) {
          IndexedMethod method = (IndexedMethod) element;
          if (className.startsWith(method.getModule() + ".")) {
            // Close!
            candidate = method;
            if (className.equals(method.getModule() + "." + method.getClz())) {
              break;
            }
          }
        }
      }

      if (candidate != null) {
        int offset = 0;
        PythonTree node = candidate.getNode();
        if (node != null) {
          offset = PythonAstUtils.getRange(node).getStart();
        }
        return new DeclarationLocation(candidate.getFileObject(), offset);
      }
    }

    return DeclarationLocation.NONE;
  }
  private IndexedElement findBestMatch(
      PythonParserResult info,
      String name,
      Set<? extends IndexedElement> methodSet,
      BaseDocument doc,
      int astOffset,
      int lexOffset,
      AstPath path,
      PythonTree call,
      PythonIndex index) {
    // Make sure that the best fit method actually has a corresponding valid source location
    // and parse tree

    Set<IndexedElement> methods = new HashSet<IndexedElement>(methodSet);

    while (!methods.isEmpty()) {
      IndexedElement method =
          findBestMatchHelper(info, name, methods, doc, astOffset, lexOffset, path, call, index);
      PythonTree node = method.getNode();

      if (node != null) {
        return method;
      }

      if (!methods.contains(method)) {
        // Avoid infinite loop when we somehow don't find the node for
        // the best method and we keep trying it
        methods.remove(methods.iterator().next());
      } else {
        methods.remove(method);
      }
    }

    // Dynamic methods that don't have source (such as the TableDefinition methods "binary",
    // "boolean", etc.
    if (methodSet.size() > 0) {
      return methodSet.iterator().next();
    }

    return null;
  }
  private DeclarationLocation findImport(
      PythonParserResult info, String moduleName, String symbol) {
    PythonIndex index = PythonIndex.get(info.getSnapshot().getSource().getFileObject());

    Set<IndexedElement> elements = null;

    if (moduleName != null && symbol != null) {
      elements =
          index.getImportedElements(
              symbol, QuerySupport.Kind.EXACT, Collections.<String>singleton(moduleName), null);
    }

    if (symbol != null && (elements == null || elements.size() == 0)) {
      elements = index.getInheritedElements(null, symbol, QuerySupport.Kind.EXACT);
    }

    if (elements == null || elements.size() == 0) {
      elements = index.getModules(moduleName, QuerySupport.Kind.EXACT);
    }

    if (elements != null && elements.size() > 0) {
      AstPath path = null;
      PythonTree node = null;
      int astOffset = -1;
      int lexOffset = -1;
      return getDeclaration(info, null /*name*/, elements, path, node, index, astOffset, lexOffset);
    }

    // This never gets executed, right? Delete after EA
    for (IndexedElement candidate : elements) {
      // TODO - pick the best of the alternatives here?
      FileObject fileObject = candidate.getFileObject();
      if (fileObject == null) {
        return DeclarationLocation.NONE;
      }

      PythonTree node = candidate.getNode();
      int nodeOffset = node != null ? node.getCharStartIndex() : 0;

      DeclarationLocation loc = new DeclarationLocation(fileObject, nodeOffset, candidate);

      if (elements.size() > 1) {
        // Could the :nodoc: alternatives: if there is only one nodoc'ed alternative
        // don't ask user!
        int not_nodoced = 0;
        for (final IndexedElement mtd : elements) {
          if (!mtd.isNoDoc()) {
            not_nodoced++;
          }
        }
        if (not_nodoced >= 2) {
          for (final IndexedElement mtd : elements) {
            loc.addAlternative(new PythonAltLocation(mtd, mtd == candidate));
          }
        }
      }

      return loc;
    }

    return DeclarationLocation.NONE;
  }