@Nullable
  private ResolveBehaviorNameResult resolveBehaviorName(Node nameNode) {
    String name = getQualifiedNameThroughCast(nameNode);
    if (name == null) {
      return null;
    }
    Name globalName = globalNames.getSlot(name);
    if (globalName == null) {
      return null;
    }

    boolean isGlobalDeclaration = true;

    // Use any set as a backup declaration, even if it's local.
    Ref declarationRef = globalName.getDeclaration();
    if (declarationRef == null) {
      for (Ref ref : globalName.getRefs()) {
        if (ref.isSet()) {
          isGlobalDeclaration = false;
          declarationRef = ref;
          break;
        }
      }
    }
    if (declarationRef == null) {
      return null;
    }

    Node declarationNode = declarationRef.getNode();
    if (declarationNode == null) {
      return null;
    }
    Node rValue = NodeUtil.getRValueOfLValue(declarationNode);
    if (rValue == null) {
      return null;
    }

    if (rValue.isQualifiedName()) {
      // Another identifier; recurse.
      return resolveBehaviorName(rValue);
    }

    JSDocInfo behaviorInfo = NodeUtil.getBestJSDocInfo(declarationNode);
    if (behaviorInfo == null || !behaviorInfo.isPolymerBehavior()) {
      compiler.report(
          JSError.make(declarationNode, PolymerPassErrors.POLYMER_UNANNOTATED_BEHAVIOR));
    }

    return new ResolveBehaviorNameResult(rValue, isGlobalDeclaration);
  }
@ Nullable private ResolveBehaviorNameResult resolveBehaviorName ( Node nameNode ) { String name = getQualifiedNameThroughCast ( nameNode ) ; if ( name == null ) { return null ; } Name globalName = globalNames . getSlot ( name ) ; if ( globalName == null ) { return null ; } boolean isGlobalDeclaration = true ; Ref declarationRef = globalName . getDeclaration ( ) ; if ( declarationRef == null ) { for ( Ref ref : globalName . getRefs ( ) ) { if ( ref . isSet ( ) ) { isGlobalDeclaration = false ; declarationRef = ref ; break ; } } } if ( declarationRef == null ) { return null ; } Node declarationNode = declarationRef . getNode ( ) ; if ( declarationNode == null ) { return null ; } Node rValue = NodeUtil . getRValueOfLValue ( declarationNode ) ; if ( rValue == null ) { return null ; } if ( rValue . isQualifiedName ( ) ) { return resolveBehaviorName ( rValue ) ; } JSDocInfo behaviorInfo = NodeUtil . getBestJSDocInfo ( declarationNode ) ; if ( behaviorInfo == null || ! behaviorInfo . isPolymerBehavior ( ) ) { compiler . report ( JSError . make ( declarationNode , PolymerPassErrors . POLYMER_UNANNOTATED_BEHAVIOR ) ) ; } return new ResolveBehaviorNameResult ( rValue , isGlobalDeclaration ) ; }
Resolve an identifier, which is presumed to refer to a Polymer Behavior declaration, using the
global namespace. Recurses to resolve assignment chains of any length.

@param nameNode The NAME, GETPROP, or CAST node containing the identifier.
@return The behavior declaration node, or null if it couldn't be resolved.