@Override
 TypedScope getGlobalScope() {
   TypedScope result = this;
   while (result.getParent() != null) {
     result = result.getParent();
   }
   return result;
 }
  /**
   * Declares a variable.
   *
   * @param n The node corresponding to the variable name.
   */
  private void declareVar(Node n) {
    Preconditions.checkState(n.isName());

    CompilerInput input = compiler.getInput(inputId);
    String name = n.getString();
    if (scope.isDeclared(name, false) || (scope.isLocal() && name.equals(ARGUMENTS))) {
      redeclarationHandler.onRedeclaration(scope, name, n, input);
    } else {
      if (isTyped) {
        ((TypedScope) scope).declare(name, n, null, input);
      } else {
        scope.declare(name, n, input);
      }
    }
  }
  @Override
  @SuppressWarnings("unchecked")
  // The cast to T is OK because we cannot mix typed and untyped scopes in the same chain.
  public <T extends Scope> T createScope(Node n, T parent) {
    inputId = null;
    if (parent == null) {
      scope = isTyped ? TypedScope.createGlobalScope(n) : Scope.createGlobalScope(n);
    } else {
      scope = isTyped ? new TypedScope((TypedScope) parent, n) : new Scope(parent, n);
    }

    scanRoot(n);

    inputId = null;
    Scope returnedScope = scope;
    scope = null;
    return (T) returnedScope;
  }