/*
 *
 *  Licensed to the Apache Software Foundation (ASF) under one or more
 *  contributor license agreements.  See the NOTICE file distributed with
 *  this work for additional information regarding copyright ownership.
 *  The ASF licenses this file to You 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 org.apache.flex.compiler.internal.semantics;

import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Set;

import org.apache.flex.abc.ABCConstants;
import org.apache.flex.abc.semantics.Name;
import org.apache.flex.abc.semantics.Namespace;
import org.apache.flex.abc.semantics.Nsset;
import org.apache.flex.compiler.common.DependencyType;
import org.apache.flex.compiler.constants.IASKeywordConstants;
import org.apache.flex.compiler.constants.IASLanguageConstants;
import org.apache.flex.compiler.constants.IASLanguageConstants.BuiltinType;
import org.apache.flex.compiler.definitions.IAccessorDefinition;
import org.apache.flex.compiler.definitions.IClassDefinition;
import org.apache.flex.compiler.definitions.IConstantDefinition;
import org.apache.flex.compiler.definitions.IDefinition;
import org.apache.flex.compiler.definitions.IFunctionDefinition;
import org.apache.flex.compiler.definitions.IFunctionDefinition.FunctionClassification;
import org.apache.flex.compiler.definitions.IInterfaceDefinition;
import org.apache.flex.compiler.definitions.INamespaceDefinition;
import org.apache.flex.compiler.definitions.IParameterDefinition;
import org.apache.flex.compiler.definitions.IScopedDefinition;
import org.apache.flex.compiler.definitions.ITypeDefinition;
import org.apache.flex.compiler.definitions.metadata.IDeprecationInfo;
import org.apache.flex.compiler.definitions.references.INamespaceReference;
import org.apache.flex.compiler.definitions.references.IReference;
import org.apache.flex.compiler.definitions.references.IResolvedQualifiersReference;
import org.apache.flex.compiler.definitions.references.ReferenceFactory;
import org.apache.flex.compiler.exceptions.MissingBuiltinException;
import org.apache.flex.compiler.filespecs.IFileSpecification;
import org.apache.flex.compiler.internal.as.codegen.Binding;
import org.apache.flex.compiler.internal.as.codegen.LexicalScope;
import org.apache.flex.compiler.internal.definitions.AmbiguousDefinition;
import org.apache.flex.compiler.internal.definitions.AppliedVectorDefinition;
import org.apache.flex.compiler.internal.definitions.ClassDefinition;
import org.apache.flex.compiler.internal.definitions.ConstantDefinition;
import org.apache.flex.compiler.internal.definitions.DefinitionBase;
import org.apache.flex.compiler.internal.definitions.FunctionDefinition;
import org.apache.flex.compiler.internal.definitions.GetterDefinition;
import org.apache.flex.compiler.internal.definitions.InterfaceDefinition;
import org.apache.flex.compiler.internal.definitions.NamespaceDefinition;
import org.apache.flex.compiler.internal.definitions.PackageDefinition;
import org.apache.flex.compiler.internal.definitions.ParameterDefinition;
import org.apache.flex.compiler.internal.definitions.SetterDefinition;
import org.apache.flex.compiler.internal.definitions.TypeDefinitionBase;
import org.apache.flex.compiler.internal.definitions.VariableDefinition;
import org.apache.flex.compiler.internal.projects.CompilerProject;
import org.apache.flex.compiler.internal.scopes.ASProjectScope;
import org.apache.flex.compiler.internal.scopes.ASScope;
import org.apache.flex.compiler.internal.scopes.ASScopeBase;
import org.apache.flex.compiler.internal.scopes.FunctionScope;
import org.apache.flex.compiler.internal.scopes.ScopeView;
import org.apache.flex.compiler.internal.scopes.TypeScope;
import org.apache.flex.compiler.internal.tree.as.BaseDefinitionNode;
import org.apache.flex.compiler.internal.tree.as.BaseTypedDefinitionNode;
import org.apache.flex.compiler.internal.tree.as.BinaryOperatorAssignmentNode;
import org.apache.flex.compiler.internal.tree.as.BlockNode;
import org.apache.flex.compiler.internal.tree.as.ExpressionNodeBase;
import org.apache.flex.compiler.internal.tree.as.FunctionCallNode;
import org.apache.flex.compiler.internal.tree.as.FunctionNode;
import org.apache.flex.compiler.internal.tree.as.IdentifierNode;
import org.apache.flex.compiler.internal.tree.as.ImportNode;
import org.apache.flex.compiler.internal.tree.as.IterationFlowNode;
import org.apache.flex.compiler.internal.tree.as.LiteralNode;
import org.apache.flex.compiler.internal.tree.as.MemberAccessExpressionNode;
import org.apache.flex.compiler.internal.tree.as.NamespaceNode;
import org.apache.flex.compiler.internal.tree.as.NodeBase;
import org.apache.flex.compiler.internal.tree.as.TypedExpressionNode;
import org.apache.flex.compiler.internal.tree.as.UnaryOperatorAtNode;
import org.apache.flex.compiler.internal.tree.as.UnaryOperatorNodeBase;
import org.apache.flex.compiler.internal.tree.as.VariableExpressionNode;
import org.apache.flex.compiler.internal.tree.as.VariableNode;
import org.apache.flex.compiler.internal.tree.as.WithNode;
import org.apache.flex.compiler.problems.AmbiguousReferenceProblem;
import org.apache.flex.compiler.problems.BaseClassIsFinalProblem;
import org.apache.flex.compiler.problems.CannotExtendInterfaceProblem;
import org.apache.flex.compiler.problems.CircularTypeReferenceProblem;
import org.apache.flex.compiler.problems.DeprecatedAPIProblem;
import org.apache.flex.compiler.problems.DeprecatedAPIWithMessageProblem;
import org.apache.flex.compiler.problems.DeprecatedAPIWithReplacementProblem;
import org.apache.flex.compiler.problems.DeprecatedAPIWithSinceAndReplacementProblem;
import org.apache.flex.compiler.problems.DeprecatedAPIWithSinceProblem;
import org.apache.flex.compiler.problems.ICompilerProblem;
import org.apache.flex.compiler.problems.ReturnValueHasNoTypeDeclarationProblem;
import org.apache.flex.compiler.problems.ScopedToDefaultNamespaceProblem;
import org.apache.flex.compiler.problems.UnknownSuperclassProblem;
import org.apache.flex.compiler.projects.ICompilerProject;
import org.apache.flex.compiler.scopes.IASScope;
import org.apache.flex.compiler.tree.ASTNodeID;
import org.apache.flex.compiler.tree.as.IASNode;
import org.apache.flex.compiler.tree.as.IClassNode;
import org.apache.flex.compiler.tree.as.ICommonClassNode;
import org.apache.flex.compiler.tree.as.IContainerNode;
import org.apache.flex.compiler.tree.as.IDefinitionNode;
import org.apache.flex.compiler.tree.as.IExpressionNode;
import org.apache.flex.compiler.tree.as.IFileNode;
import org.apache.flex.compiler.tree.as.IFunctionNode;
import org.apache.flex.compiler.tree.as.IIdentifierNode;
import org.apache.flex.compiler.tree.as.IImportNode;
import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode;
import org.apache.flex.compiler.tree.as.ILanguageIdentifierNode.LanguageIdentifierKind;
import org.apache.flex.compiler.tree.as.ILiteralNode;
import org.apache.flex.compiler.tree.as.INamespaceDecorationNode;
import org.apache.flex.compiler.tree.as.INumericLiteralNode;
import org.apache.flex.compiler.tree.as.IParameterNode;
import org.apache.flex.compiler.tree.as.ITryNode;
import org.apache.flex.compiler.tree.as.IVariableNode;
import org.apache.flex.compiler.tree.mxml.IMXMLEventSpecifierNode;

/**
 *  SemanticUtils is a set of utility routines to provide information
 *  about AS3 constructs' semantics.
 *  
 *  Many of these routines come in pairs; a static form that accepts 
 *  an ICompilerProject parameter for name resolution context, and
 *  an instance form that uses the project provided at construction.
 */
public class SemanticUtils
{
    /**
     * Enum that describes different kinds of multiple definitions
     */
    public enum MultiDefinitionType {
        /** The definition is not multiply defined at all */
        NONE,
        
        /** The definition is ambiguous in a way that violates the language spec */
        AMBIGUOUS,
        
        /** The definition is multiply defined, but in a way that is legal and unambiguous  ECMAScript */ 
        MULTIPLE,
        
        /** The definition is also a parameter definition, which is legal
         * The only reason SHADOWS_PARAM and MULTIPLE are different is that the old compiler did not detect shadows
         */
        SHADOWS_PARAM
        }
    /**
     *  ICompilerProject for the current project,
     *  provided by the constructor.
     */
    private final ICompilerProject project;

    /**
     *  Construct a new SemanticUtils object.
     *  @param project - an ICompilerProject for the current project.
     */
    public SemanticUtils(ICompilerProject project)
    {
        this.project = project;
    }

    /**
     * Check if the node is for {@code super(this)} but not
     * {@code super(this).call()}. The incoming tree shape is:
     * 
     * <pre>
     * MemberAccessExpressionID(FunctionCallID(SuperID(void), ContainerID(IdentifierID(void))), qname)
     * </pre>
     * 
     * @return "0" if the node represents {@code super(this)};
     * {@link Integer#MAX_VALUE} otherwise.
     */
    public static int isSuperThisForFieldAccess(IASNode n)
    {
        // super(this).callSomething() is handled by another pattern that emits
        // "callsuper" instruction.
        if (n.getParent() instanceof FunctionCallNode)
            return Integer.MAX_VALUE;

        // The following unguarded casts are safe, because this is a cost 
        // function and the pattern matcher has checked all the node IDs.
        final MemberAccessExpressionNode memberAccessNode = (MemberAccessExpressionNode)n;
        final FunctionCallNode callNode = (FunctionCallNode)memberAccessNode.getLeftOperandNode();
        final IdentifierNode idNode = (IdentifierNode)callNode.getArgumentsNode().getChild(0);

        if (idNode.getName().equals(IASKeywordConstants.THIS))
            return 1;
        else
            return Integer.MAX_VALUE;
    }

    /**
     * Check that a implicit conversion from actual to expected type is valid.
     * 
     * @param expected the expected type.
     * @param actual the actual type.
     * @param project an ICompilerProject for the current project.
     * @return true if there is a valid implicit type conversion from actual to
     * expected, false otherwise.
     */
    private static boolean isValidTypeConversion(IDefinition expected, IDefinition actual, ICompilerProject project)
    {
        if  (
                actual == null ||
                expected == null ||
                actual.equals(getBuiltinType(BuiltinType.ANY_TYPE, project)) ||
                expected.equals(getBuiltinType(BuiltinType.ANY_TYPE, project)) ||
                isInstanceOf(actual, expected, project) ||
                isBuiltin(actual, BuiltinType.NULL, project) ||
                isBuiltin(expected, BuiltinType.BOOLEAN, project) ||
                isBuiltin(expected, BuiltinType.VOID, project)
                )
            {
                return true;
            }
            // else if ( isVectorSplat(expected) && isVector(actual) ) // This is allowed by the AVM.
            else if (
                isBuiltin(expected, BuiltinType.STRING, project) &&
                (isBuiltin(actual, BuiltinType.XML, project) || isBuiltin(actual, BuiltinType.XMLLIST, project))
            )
            {
                // allow this, e4x values are string values transparently (i.e. without having to call toString()/toXMLString()).
                return true;
            }

            //  Types are unrelated, unless they're both numeric.
            return isNumericType(expected, project) && isNumericType(actual, project);
    }

    /**
     *  Check that implicit conversion done as part of an op= style assignment is valid.
     *  @param lhsType - the type of the lvalue (and one operand of the implicit binary operator).
     *  @param rhsType - the type of the result of the implicit binary operation.
     *  @param opcode - the operator of the implicit binary operator.
     *  @param project an ICompilerProject for the current project.
     *  @return true if there is a valid implicit binary operation that can assign
     *    its result to lhsType.
     */
    public static boolean isValidImplicitOpAssignment(IDefinition lhsType, IDefinition rhsType, final int opcode, ICompilerProject project, final boolean compareNormalized)
    {
        boolean result = isValidTypeConversion(lhsType, rhsType, project, compareNormalized);

        if ( ! result )
        {
            switch (opcode)
            {
                case ABCConstants.OP_add:
                    //  Special cases for +=:
                    //  anything can be added to String
                    //  XML can be added to XMLList
                    result = 
                        isBuiltin(lhsType, BuiltinType.STRING, project ) ||
                        (isBuiltin(lhsType, BuiltinType.XMLLIST, project) && isBuiltin(rhsType, BuiltinType.XML, project));
                    break;
            }
        }

        return result;
    }
    
    /**
     * If the specified {@link IDefinition} is a public or internal definition,
     * then construct a qualified name to lookup a definition with the same name
     * in the {@link ICompilerProject}. The {@link IDefinition} that can be
     * found within the {@link ICompilerProject} is the "normalized"
     * {@link IDefinition}.
     * <p>
     * This method asserts that is only called with definitions that are not
     * local variables, parameters, or class members.
     * <p>
     * This method is necessary because
     * {@link org.apache.flex.compiler.units.IInvisibleCompilationUnit}s create the
     * possibility that we will be processing a file whose definitions are not
     * in the {@link ASProjectScope} in the {@link ICompilerProject}. This in
     * turn creates the possibility there are two or more {@link IDefinition}s
     * floating around for the same class, variable, or function. One the
     * {@link IDefinition}, the "normalized" one, should be registered with the
     * {@link ASProjectScope} in the {@link ICompilerProject}. The other
     * {@link IDefinition}s are from
     * {@link org.apache.flex.compiler.units.IInvisibleCompilationUnit}s. When doing
     * semantic analysis if we don't "normalize" {@link IDefinition}s in some
     * cases, we'll get spurious errors because the semantic analysis code
     * generally compares {@link IDefinition}s by identity ( which is faster )
     * rather than by name. This method should only be called when doing
     * semantic analysis of an
     * {@link org.apache.flex.compiler.units.IInvisibleCompilationUnit}.
     * 
     * @param def The {@link IDefinition} whose corresponding normalized
     * definition should be returned.
     * @param project The {@link ICompilerProject} in which to find normalized
     * {@link IDefinition}s.
     * @return The normalized {@link IDefinition} ( which may be the same as the
     * specified {@link IDefinition} ) or null.
     */
    private static IDefinition normalizeDefinition(IDefinition def, ICompilerProject project)
    {
        assert !(def.getContainingScope() instanceof FunctionScope);
        assert !(def.getContainingScope() instanceof ScopeView);
        assert !(def.getContainingScope() instanceof TypeScope);
        assert !(def instanceof ParameterDefinition);

        INamespaceReference qualifier = def.getNamespaceReference();
        if (!qualifier.isPublicOrInternalNamespace())
            return def;
        INamespaceDefinition qualifierDef = (INamespaceDefinition)qualifier;
        IResolvedQualifiersReference refToDefinition =
                ReferenceFactory.resolvedQualifierQualifiedReference(project.getWorkspace(), qualifierDef, def.getBaseName());
        return refToDefinition.resolve(project);
    }
    
    /**
     * Check that a implicit conversion from actual to expected type is valid.
     * 
     * @param expected the expected type.
     * @param actual the actual type.
     * @param project an ICompilerProject for the current project.
     * @param normalizeDefinitions If true, we'll try normalizing both
     * {@link IDefinition}s before returning false.  See the java doc for
     * {@code normalizeDefinition(IDefinition, ICompilerProject)} for more info.
     * @return true if there is a valid implicit type conversion from actual to
     * expected, false otherwise.
     */
    public static boolean isValidTypeConversion(IDefinition expected, IDefinition actual, ICompilerProject project, boolean normalizeDefinitions)
    {
        if (isValidTypeConversion(expected, actual, project))
            return true;
        if (!normalizeDefinitions)
            return false;
        final IDefinition normalizedExpected = normalizeDefinition(expected, project);
        if (normalizedExpected == null)
            return false;
        final IDefinition normalizedActual = normalizeDefinition(actual, project);
        if (normalizedActual == null)
            return false;
        if ((normalizedExpected == expected) && (normalizedActual == actual))
            return false;
        return isValidTypeConversion(normalizedExpected, normalizedActual, project);
    }

    /**
     * Helper method to get the node to report a problem with a Function.  This will get the name node,
     * if it exists, otherwise it will return the function node.
     */
    public static IASNode getFunctionProblemNode(IFunctionNode iNode)
    {
        IASNode result = iNode;
        IExpressionNode nameExpression = iNode.getNameExpressionNode();
        if( nameExpression != null )
            result = nameExpression;
        return result;
    }

    /**
     * Helper method to determine if an IdentifierNode refers to the Class it is contained
     * in from a context where we are generating code that may be run during the cinit method.
     *
     * This is important because cinit code must refer to the class via getlocal0 instead of a
     * named lookup like findprop, getprop.  This is because the Class property is initialized with the
     * result of the cinit, but since we are potentially in the cinit, the property will not have been initialized.
     *
     * class C {
     *     static var a = C;  // C won't have been initialized yet, so we need to use getlocal0
     * }
     *
     * The above class generates code like:
     *
     * findprop C
     * newclass C // this runs the cinit, and leaves the result on the stack, at this point 'C' is undefined
     * setprop  C // this will init the property
     *
     * @param id  the identifier node that we are resolving
     * @param def the definition the identifier node resolved to
     * @return    true if this is a reference to the Class that is being initialized, and needs special treatment.
     */
    public static boolean isRefToClassBeingInited (IdentifierNode id, IDefinition def)
    {
        boolean refToClassBeingInited = false;
        if( def instanceof IClassDefinition)
        {
            ASScope scope = id.getASScope();
            IDefinition containingDef = null;

            while( scope != null )
            {
                if( containingDef == null )
                    containingDef = scope.getDefinition();

                if( scope instanceof ScopeView)
                {
                    if (((ScopeView)scope).isInstanceScope() )
                    {
                        // stop looking, we're in an instance method, so we're ok
                        break;
                    }
                    else if( ((ScopeView)scope).isStaticScope() && def == scope.getDefinition() )
                    {
                        // we're in static code, and are referencing the class we are in
                        refToClassBeingInited = true;
                        break;
                    }
                }

                scope = scope.getContainingScope();
            }
        }
        return refToClassBeingInited;
    }

    /**
     *  Determine if an IDefinition is a specific builtin type.
     *  @param def - the IDefinition of interest.
     *  @param builtin - the builtin type.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if def is the desired builtin type.
     */
    public static boolean isBuiltin(IDefinition def, BuiltinType builtin, ICompilerProject project)
    {
        return def != null && def.equals(project.getBuiltinType(builtin));
    }

    /**
     * Find potential conflict for a FunctionDefinition. In some contexts it is ok to redeclare a Function (global, or
     * inside another function body).  For those cases the function will not be reported as ambiguous.  However, in strict
     * mode we do want to issue a diagnostic that the function has been redeclared - this method is to find the redlarations
     * even though those redecls don't make references ambiguous.
     * @param project   The project to resolve things in
     * @param funcDef   The function definition to find potential conlicts for
     * @return          A List of Definitions from the same scope that have the same name as the function definition, including
     *                  the function definition (so if there are no conflicts, the list should have 1 item).
     */
    public static List<IDefinition> findPotentialFunctionConflicts (ICompilerProject project, IFunctionDefinition funcDef)
    {
        ASScope scope = (ASScope)funcDef.getContainingScope();
        INamespaceDefinition qualifier = funcDef.getNamespaceReference().resolveNamespaceReference(project);
        Set<INamespaceDefinition> namespaceSet = Collections.singleton(qualifier);
        return scope.getPropertiesByNameForMemberAccess((CompilerProject) project, funcDef.getBaseName(), namespaceSet);
    }

    /**
     * Is the binding a potential reference to
     * the 'arguments' object
     * @param b         the Binding to check
     * @return          true if the reference could be a reference to 'arguments'
     */
    public static boolean isArgumentsReference (Binding b)
    {
        Name name = b.getName();
        if (name != null && IASLanguageConstants.arguments.equals(name.getBaseName()))
        {
            // the name is "arguments", but make sure it's not a user defined definition
            // by checking whether the def is implicit
            IDefinition definition = b.getDefinition();
            if (definition != null)
            {
                return definition.isImplicit();
            }
            else
            {
                // if there's no definition, as can happen when referencing "arguments" from
                // within a 'with', then fall back to checking on the node.
                IASNode node = b.getNode();
                return node instanceof IdentifierNode && !((IdentifierNode) node).isMemberRef();
            }
        }

        return false;
    }

    /**
     *  Determine if an IDefinition is a specific builtin type.
     *  @param def - the IDefinition of interest.
     *  @param builtin - the builtin type.
     *  @return true if def is the desired builtin type.
     */
    public boolean isBuiltin(IDefinition def, BuiltinType builtin)
    {
        return isBuiltin(def, builtin, this.project);
    }

    /**
     *  @return true if the given definition is a numeric type.
     *  @param def - the IDefinition of interest.
     *  @param project - an ICompilerProject for the current project.
     */
    public static boolean isNumericType(IDefinition def, ICompilerProject project)
    {
        return isBuiltin(def, BuiltinType.INT, project) ||
               isBuiltin(def, BuiltinType.UINT, project) ||
               isBuiltin(def, BuiltinType.NUMBER, project);
    }

    /**
     *  @return true if the given definition is a numeric or boolean type.
     *  @param def - the IDefinition of interest.
     *  @param project - an ICompilerProject for the current project.
     */
    public static boolean isNumericTypeOrBoolean(IDefinition def, ICompilerProject project)
    {
        return isNumericType(def, project) ||
            isBuiltin(def, BuiltinType.BOOLEAN, project);
    }
    
    /**
     *  @return true if the given definition is a numeric type.
     *  @param def - the IDefinition of interest.
     *  @see #isNumericType(IDefinition, ICompilerProject)
     */
    public boolean isNumericType(IDefinition def)
    {
        return isNumericType(def, this.project);
    }

    /**
     *  Determine if one IDefinition is a subclass of another.
     *  @param maybe_derived The first definition.
     *  @param maybe_base The second definition.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if  maybe_derived is an instance of maybe_base.
     */
    public static boolean isInstanceOf(IDefinition maybe_derived, IDefinition maybe_base, ICompilerProject project)
    {
        if (!(maybe_base instanceof ITypeDefinition))
            return false;
        if (!(maybe_derived instanceof ITypeDefinition))
            return false;
        
        ITypeDefinition base    = (ITypeDefinition) maybe_base;
        ITypeDefinition derived = (ITypeDefinition) maybe_derived;

        if (derived.isInstanceOf(base, project))
            return true;
        
        
        //  Consider null to be an "instanceof" any Object subtype.
        boolean base_is_object = isInstanceOf(base, getBuiltinType(BuiltinType.OBJECT, project), project);
        if (base_is_object && derived.equals(getBuiltinType(BuiltinType.NULL, project)))
            return true;
        
        
        if (AppliedVectorDefinition.vectorInstanceOfCheck(base, derived))
            return true;
        
        return false;
        
    }

    /**
     *  Determine if one IDefinition is a subclass of another.
     *  @param maybe_derived The first definition.
     *  @param maybe_base The second definition.
     *  @return true if  maybe_derived is an instance of maybe_base.
     *  @see #isInstanceOf(IDefinition, IDefinition, ICompilerProject)
     */
    public boolean isInstanceOf(IDefinition maybe_derived, IDefinition maybe_base)
    {
        return isInstanceOf(maybe_derived, maybe_base, this.project);
    }

    /**
     *  Fetch a builtin type.
     *  @param builtin - the BuiltinType identifier of the type.
     *  @param project - an ICompilerProject for the current project.
     *  @return the specified builtin type.
     */
    public static IDefinition getBuiltinType(BuiltinType builtin, ICompilerProject project)
    {
        return project.getBuiltinType(builtin);
    }

    /**
     *  Fetch a builtin type.
     *  @param builtin - the BuiltinType identifier of the type.
     *  @return the specified builtin type.
     */
    public IDefinition getBuiltinType(BuiltinType builtin)
    {
        return getBuiltinType(builtin, this.project);
    }

    /**
     *  Get the current number type.
     *  @param project - an ICompilerProject for the current project.
     *  @return the current number type; currently hardcoded
     *    to BuiltinTypes.NUMBER.
     */
    public static IDefinition numberType(ICompilerProject project)
    {
        return getBuiltinType(BuiltinType.NUMBER, project);
    }

    /**
     *  Get the current number type.
     *  @return the current number type; currently hardcoded
     *    to BuiltinTypes.NUMBER.
     *  @see #numberType(ICompilerProject)
     */
    public IDefinition numberType()
    {
        return numberType(this.project);
    }

    /**
     *  Given the definition of a getter or setter, resolve its 
     *  corresponding accessor (e.g., the setter for a getter).
     *  @param def - the definition of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the corresponding accessor, or null if 
     *    there is no corresponding accessor.
     *  @throws IllegalArgumentException if the definition is
     *    not for a getter or setter.
     */
    public static IDefinition resolveCorrespondingAccessor(IDefinition def, ICompilerProject project)
    {
        if ( def instanceof GetterDefinition )
            return ((GetterDefinition)def).resolveCorrespondingAccessor(project);
        else if ( def instanceof SetterDefinition )
            return ((SetterDefinition)def).resolveCorrespondingAccessor(project);
        else
            throw new IllegalArgumentException("Definition " + def + " was not a getter or setter.");
    }

    /**
     *  Given the definition of a getter or setter, resolve its 
     *  corresponding accessor (e.g., the setter for a getter).
     *  @param def - the definition of interest.
     *  @return the corresponding accessor, or null if 
     *    there is no corresponding accessor.
     *  @throws IllegalArgumentException if the definition is
     *    not for a getter or setter.
     *  @see #resolveCorrespondingAccessor(IDefinition, ICompilerProject)
     */
    public IDefinition resolveCorrespondingAccessor(IDefinition def)
    {
        return resolveCorrespondingAccessor(def, this.project);
    }

    /**
     *  Is the given node in a with scope?
     *  @param iNode - the node of interest.
     *  @return the node's own answer if it's an
     *    ExpressionNodeBase; otherwise return true 
     *    if the node has a WithNode ancestor.
     */
    public static boolean isInWith(IASNode iNode)
    {
        if ( iNode instanceof ExpressionNodeBase )
        {
            return ((ExpressionNodeBase)iNode).inWith();
        }
        else
        {
            return iNode.getAncestorOfType(WithNode.class) != null;
        }
    }

    /**
     *  Is the given node in a filter expression?
     *  @param iNode - the node of interest.
     *  @return the node's own answer if it's an
     *    ExpressionNodeBase; otherwise return false.
     */
    public static boolean isInFilter(IASNode iNode)
    {
        if ( iNode instanceof ExpressionNodeBase )
        {
            return ((ExpressionNodeBase)iNode).inFilter();
        }
        else
        {
            return false;
        }
    }

    /**
     * Check if a nested function can have it's init instructions hoisted to the top of the
     * function it is contained in.  This is not possible when the function is inside some control-flow,
     * as the OP_newfunction must be executed only when control flows there (and with whatever scope stack is in effect
     * if we're in a with/catch scope).
     * @param iNode  The node to check
     * @return       true if it is ok to hoist the init instructions for the node to the top of the function
     */
    public static boolean canNestedFunctionBeHoisted(IASNode iNode)
    {
        IASNode n = iNode.getParent();
        // Walk up the parent chain looking for anything other than block nodes,
        // until we get to the containing function - we don't have to look past the containing
        // function because any control flow around it should have been handled when setting up the outer function
        while( n != null && !(n instanceof FunctionNode) )
        {
            if( !(n instanceof BlockNode) )
                return false;

            n = n.getParent();
        }
        return true;
    }

    /**
     *  Is this definition a member of a class?
     *  @param def - the definition of interest.
     *  @return true if the definition's parent is a class definition.
     */
    public static boolean isMemberDefinition(IDefinition def)
    {
        return def != null && def.getParent() instanceof ClassDefinition;
    }

    /**
     *  Is this definition a member of a package?
     *  @param def - the definition of interest.
     *  @return true if the definition's parent is a package definition.
     */
    public static boolean isPackageDefinition(IDefinition def)
    {
        return def != null && def.getParent() instanceof PackageDefinition;
    }

    /**
     *  Is the definition going to be a method binding in the ABC?
     *  method bindings can be called with findprop/callprop instead of having to
     *  use op_call.
     *
     *  A method biniding is a member function, or a global function defined in a package
     *
     *  @param def - the definition of interest.
     *  @return true if the definition is a method binding.
     */
    public static boolean isMethodBinding(IDefinition def)
    {
        return def instanceof IFunctionDefinition &&
                (isMemberDefinition(def) || isPackageDefinition(def));
    }

    /**
     *  Is this definition read-only?
     *  @param def - the definition of interest.
     */
    public boolean isReadOnlyDefinition(IDefinition def)
    {
        boolean result = false;

        if ( def instanceof GetterDefinition )
        {
        	IDefinition otherDef = resolveCorrespondingAccessor(def);
            if (otherDef == null) return true;
            if (otherDef.getNamespaceReference().getBaseName() != def.getNamespaceReference().getBaseName())
            	return true;
        }
        else if ( def instanceof ConstantDefinition )
        {
            result = true;
        }

        return result;
    }

    /**
     *  Is this Binding's definition statically analyzable?
     *  @param binding - the Binding of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if the Binding has no definition and
     *    it is in a context that implies its definition
     *    is statically resolvable.
     */
    public static boolean definitionCanBeAnalyzed(Binding binding, ICompilerProject project)
    {
        assert(binding.getNode()) != null;

        IASNode node = binding.getNode();

        if ( node instanceof ExpressionNodeBase )
        {
            //  Ensure we're not in a with scope or part of a filter expression.
            final ExpressionNodeBase expressionNode = (ExpressionNodeBase)node;
            if (expressionNode.inWith() || expressionNode.inFilter())
                return false;
        }

        //  Attribute names aren't statically knowable.
        if ( binding.getName() != null && binding.getName().isAttributeName() )
            return false;

        return !hasDynamicBase(binding, project);
    }

    /**
     *  Is this Binding's definition statically analyzable?
     *  @param binding - the Binding of interest.
     *  @return true if the Binding has no definition and
     *    it is in a context that implies its definition
     *    is statically resolvable.
     *  @see #definitionCanBeAnalyzed(Binding, ICompilerProject)
     */
    public boolean definitionCanBeAnalyzed(Binding binding)
    {
        return definitionCanBeAnalyzed(binding, this.project);
    }

    /**
     *  Is this definition write-only?
     *  @param def - the definition of interest.
     *  @return true if the definition is a set 
     *    that does not have a corresponding get.
     */
    public boolean isWriteOnlyDefinition(IDefinition def)
    {
        return def instanceof SetterDefinition && resolveCorrespondingAccessor(def) == null;
    }

    /**
     *  Check an ExpressionNodeBase's base expression (if any)
     *  to determine if it's a dynamic expression, which
     *  means we don't know much about its definition.
     *  @param binding - the binding whose base node is to be checked.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if node's base expression is dynamic.
     */
    public static boolean hasDynamicBase(Binding binding, ICompilerProject project)
    {
        ExpressionNodeBase base = getBaseNode(binding);
        return base != null && base.isDynamicExpression(project);
    }

    /**
     *  Check an ExpressionNodeBase's base expression (if any)
     *  to determine if it's a dynamic expression, which
     *  means we don't know much about its definition.
     *  @param binding - the binding whose base node is to be checked.
     *  @return true if node's base expression is dynamic.
     *  @see #hasDynamicBase(Binding, ICompilerProject)
     */
    public boolean hasDynamicBase(Binding binding)
    {
        return hasDynamicBase(binding, this.project);
    }
    
    /**
     *  Get an ExpressionNodeBase's base node.
     *  @return the node's base expression, or null
     *    if the Binding does not wrap an ExpressionNodeBase.
     */
    public static ExpressionNodeBase getBaseNode(Binding binding)
    {
        if ( binding.getNode() instanceof ExpressionNodeBase )
            return ((ExpressionNodeBase)binding.getNode()).getBaseExpression();
        else
            return null;
    }
    

    /**
     *  Get the definition associated with a IASNode.
     *  @param iNode - the node whose definition is desired.
     *  @return the node's definition, or null if the node
     *    is of an unknown type or has no definition.
     */
    public IDefinition getDefinition(IASNode iNode)
    {
        return getDefinition(iNode, project);
    }

    /**
     *  Get the definition associated with a IASNode.
     *  @param iNode - the node whose definition is desired.
     *  @param project - an ICompilerProject for the current project.
     *  @return the node's definition, or null if the node
     *    is of an unknown type or has no definition.
     *    
     *    TODO: don't require a ASDefinition cache, base on ICompilerProject
     */
    public static IDefinition getDefinition(IASNode iNode, ICompilerProject project)
    {
        if ( iNode instanceof ExpressionNodeBase )
        {
            return ((ExpressionNodeBase)iNode).resolve(project);
        }
        else if ( iNode instanceof BaseTypedDefinitionNode )
        {
            return ((BaseTypedDefinitionNode)iNode).getDefinition();
        }
        else if ( iNode instanceof NamespaceNode )
        {
            return ((NamespaceNode)iNode).getDefinition();
        }

        return null;
    }
    
    public static IDefinition resolveType(IASNode iNode, ICompilerProject project)
    {
        if ( iNode instanceof ExpressionNodeBase )
        {
            return ((ExpressionNodeBase)iNode).resolveType(project);
        }
        else if ( iNode instanceof BaseTypedDefinitionNode )
        {
            return ((BaseTypedDefinitionNode)iNode).getDefinition().resolveType(project);
        }

        return null;
    }

    public IDefinition resolveType(IASNode iNode)
    {
        return resolveType(iNode, this.project);
    }

    /**
     * Resolve the type of the underlying expression in a UnaryOperatorNode.
     *
     * for '++i', this would return the type of 'i' as opposed to the result of the ++
     *
     * @param iNode  The UnaryOperatorNode you want the underlying type for
     *  @param project - an ICompilerProject for the current project.
     * @return       The type of the underlying expression, or null if the node passed in isn't
     *               a UnaryOperatorNode
     */
    public static IDefinition resolveUnaryExprType(IASNode iNode, ICompilerProject project)
    {
        if ( iNode instanceof UnaryOperatorNodeBase )
        {
            return ((UnaryOperatorNodeBase)iNode).getOperandNode().resolveType(project);
        }

        return null;
    }

    /**
     *  Get the type of a node's base expression as a string.
     *  @param node the node whose base's type is desired.
     *  @return the type string, or null if none found.
     */
    public String getTypeOfBase(IASNode node)
    {
        return getTypeOfBase(node, project);
    }
    
    /**
     *  Get the type of a node's base expression as a string.
     *  @param node the node whose base's type is desired.
     *  @param project an ICompilerProject for the current project.
     *  @return the type string, or null if none found.
     */
    public static String getTypeOfBase(IASNode node, ICompilerProject project)
    {
        if (!(node instanceof ExpressionNodeBase))
            return null;
        
        ExpressionNodeBase base = ((ExpressionNodeBase)node).getBaseExpression();
        if (base == null)
            return null;
        
        IDefinition def = base.resolve(project);
        if (def == null)
            return null;
        
        return def.getTypeAsDisplayString();
    }
    
    /**
     *  Get the type of an expression's stem.
     *  @param iNode - the node of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the type of the node's underlying reference base as a string.
     *  @pre hasUnderlyingType(iNode, cache) must be true.
     */
    public static String getTypeOfStem(IASNode iNode, ICompilerProject project)
    {
        IDefinition type_def = getDefinitionOfUnderlyingType(iNode, ASSERT_ON_UNKNOWN_INODE, project);
        return ( type_def != null )?  type_def.getBaseName(): "?";
    }
    
    /**
     *  Get the type of an expression's stem.
     *  @param node - the node of interest.
     *  @return the type of the node's underlying reference base as a string.
     *  @see #getTypeOfStem(IASNode, ICompilerProject)
     */

    public String getTypeOfStem(IASNode node)
    {
        return getTypeOfStem(node, this.project);
    }

    /**
     *  Get the definition of the explicit or implicit type underlying
     *  an iNode's reference(s).
     *  @param iNode - the inode of interest.
     *  @param allow_unknown_iNode - tolerate a node type that doesn't
     *    have a procedure for extracting its underlying scope.
     *  @param project - an ICompilerProject for the current project.
     *  @return the definition of the type that underlies the node's references,
     *    or null if no underlying scope is available.
     */
    public static IDefinition getDefinitionOfUnderlyingType(IASNode iNode, final boolean allow_unknown_iNode, ICompilerProject project)
    {
        IDefinition result;

        if ( iNode instanceof MemberAccessExpressionNode )
        {
            MemberAccessExpressionNode member_node = (MemberAccessExpressionNode) iNode;
            result = member_node.getLeftOperandNode().resolveType(project);
        }
        else if ( iNode instanceof FunctionCallNode && ((FunctionCallNode)iNode).getNameNode() instanceof MemberAccessExpressionNode )
        {
            MemberAccessExpressionNode member_node = (MemberAccessExpressionNode) ((FunctionCallNode)iNode).getNameNode();
            result = member_node.getLeftOperandNode().resolveType(project);
        }
        else if ( isInInstanceFunction(iNode, project) )
        {
            result = getEnclosingFunctionDefinition(iNode, project).getAncestorOfType(ClassDefinition.class);
        }
        else if ( isInStaticClassFunction(iNode, project) )
        {
            result = getEnclosingFunctionDefinition(iNode, project).getAncestorOfType(ClassDefinition.class);
        }
        else
        {
            assert(allow_unknown_iNode): "Unknown iNode:" + iNode;
            result = null;
        }

        return result;
    }

    /**
     *  Get the definition of the explicit or implicit type underlying
     *  an iNode's reference(s).
     *  @param iNode - the inode of interest.
     *  @param allow_unknown_iNode - tolerate a node type that doesn't
     *    have a procedure for extracting its underlying scope.
     *  @return the definition of the type that underlies the node's references,
     *    or null if no underlying scope is available.
     *  @see #getDefinitionOfUnderlyingType(IASNode, boolean, ICompilerProject)
     */
    public IDefinition getDefinitionOfUnderlyingType(IASNode iNode, final boolean allow_unknown_iNode)
    {
        return getDefinitionOfUnderlyingType(iNode, allow_unknown_iNode, this.project);
    }

    /** Manifest constant, getDefinitionOfUnderlyingType asserts if this is passed */
    public static final boolean ASSERT_ON_UNKNOWN_INODE = false;
    /** Manifest constant, getDefinitionOfUnderlyingType tolerates unknown tree shapes if this is passed */
    public static final boolean ALLOW_UNKNOWN_INODE = true;

    /**
     *  Does the given inode have an underlying type that could
     *  resolve its references?
     *  @param iNode - the inode of interest.
     *  @param project - an ICompilerProject for the current project.
     */
    public static boolean hasUnderlyingType(IASNode iNode, ICompilerProject project)
    {
        return getDefinitionOfUnderlyingType(iNode, ALLOW_UNKNOWN_INODE, project) != null;
    }

    /**
     *  Does the given inode have an underlying type that could
     *  resolve its references?
     *  @param iNode - the inode of interest.
     *  @see #hasUnderlyingType(IASNode, ICompilerProject)
     */
    public boolean hasUnderlyingType(IASNode iNode)
    {
        return hasUnderlyingType(iNode, this.project);
    }

    /**
     *  Does the given node have an explicit stem reference, e.g., foo.bar?
     *  @param iNode - the node of interest.
     *  @return true if the node has an explicit stem (the foo in foo.bar).
     *  @see #hasUnderlyingType which checks for explicit or implicit contexts for resolution.
     */
    public static boolean hasExplicitStem(IASNode iNode)
    {
        return  ( iNode instanceof MemberAccessExpressionNode ) ||
                ( iNode instanceof FunctionCallNode && ((FunctionCallNode)iNode).getNameNode() instanceof MemberAccessExpressionNode );
    }

    /**
     *  Does this binding have a base node?
     *  @param binding - the Binding of interest.
     *  @return true if the Binding's i-node has a base node.
     */
    public static boolean hasBaseNode(Binding binding)
    {
        return getBaseNode(binding) != null;
    }

    /**
     *  Is this node enclosed in a function definition?
     *  @param iNode - the node of interest.
     *  @return true if the node is in a function definition.
     */
    public static boolean isInFunction(IASNode iNode)
    {
        return iNode.getAncestorOfType(FunctionNode.class) != null;
    }

    /**
     * Is this node declaring a property in a class, but also nested inside
     * another statement.
     * @param iNode the node
     * @param def   the
     */
    public static boolean isNestedClassProperty(IASNode iNode, VariableDefinition def)
    {
        if(def != null && def.getParent() instanceof IClassDefinition)
        {
            return def.declaredInControlFlow();
        }
        return false;
    }

    /**
     *  Is this container an implicit container?
     *  @param iNode - the container of interest.
     *  @return true if the container is implicit.
     */
    public static boolean isImplicitContainer(IASNode iNode)
    {
        //  TODO: The result of CMP-1004 goes here.
        return
            ( iNode instanceof IContainerNode ) &&
            false;
          
    }
    
   
    
    /**
     *  Is the given multiply defined, or ambiguous?
     *  @param def - the definition of interest.
     *  @param project - the active compiler project.
     *  @return An enum telling the nature of any discovered multple definitions
     */
    public static MultiDefinitionType getMultiDefinitionType(IDefinition def, ICompilerProject project)
    {
        // A null definition cannot be ambiguous.
        if (def == null)
           return MultiDefinitionType.NONE;
        
        // Look for other definitions with the same base name
        // and the same namespace as the specified definition.
        IDefinition found = findPropertyQualified(def, project);
        
        if (AmbiguousDefinition.isAmbiguous(found))
            return MultiDefinitionType.AMBIGUOUS;
      
        // if we found something, andit's not us, and it's not null, then there are multi deinitions.
        if (def != found && found != null && !isGetterSetterPair(def, found, project))
        {
            return found instanceof IParameterDefinition ? MultiDefinitionType.SHADOWS_PARAM :
                    MultiDefinitionType.MULTIPLE;
        }
        
        return MultiDefinitionType.NONE ;
    }


    /**
     * Determine if a given binding is ambiguous
     * @param b  the binding to check
     * @return   true if the binding refers to more than 1 definiton
     */
    public static boolean isAmbiguousReference(Binding b)
    {
        return AmbiguousDefinition.isAmbiguous(b.getDefinition());
    }

    /**
     *  Does this node represent the "this" keyword?
     *  @param iNode - the node of interest.
     *  @return true if the node represents "this"
     */
    public static boolean isThisKeyword(IASNode iNode)
    {
        return 
            (iNode instanceof ILanguageIdentifierNode) &&
            (((ILanguageIdentifierNode)iNode).getKind() == LanguageIdentifierKind.THIS);
    }

    /**
     *  Is the given node in a class with a base class definition?
     *  @param iNode - the node of interest.
     *  @return true if the node is in a class with a base class.
     *  @see #hasBaseClassDefinition(IASNode, ICompilerProject)
     */
    public boolean hasBaseClassDefinition(IASNode iNode)
    {
        return hasBaseClassDefinition(iNode, this.project);
    }

    /**
     *  Is the given node in a class with a base class definition?
     *  @param iNode - the node of interest.
     *  @param project - the active compiler project.
     *  @return true if the node is in a class with a base class.
     */
    public static boolean hasBaseClassDefinition(IASNode iNode, ICompilerProject project)
    {
        return getBaseClassDefinition(iNode, project) != null;
    }

    /**
     *  Fetch the definition of the given node's
     *    class' base class.
     *  @param iNode - the node of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the definition of the node's class' base class,
     *    or null if it not in a class or its class 
     *    has no base class.
     */
    public static IDefinition getBaseClassDefinition(IASNode iNode, ICompilerProject project)
    {
        IDefinition result = null;
        IDefinition member_def = getDefinition(iNode, project);

        if ( member_def != null )
        {
            ASScope super_scope = getSuperClassScope(project, member_def);
            if( super_scope != null )
            {
                result = getPropertyQualified(
                    super_scope,
                    getNamespaceInClassContext(member_def, project),
                    member_def.getBaseName(),
                    project
                );
            }
        }

        return result;
    }

    /**
     *  Resolve a definition's namespace, and if its parent is a class, normalize
     *  that namespace against the parent class' superclass' protected namespace.
     *  @param def - the definition of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the definition's class' superclass' namespace if the definition is
     *    in a class and its namespace is the same as the enclosing class' superclass'
     *    protected namespace; otherwise, return the definition's namespace.
     */
    public static INamespaceDefinition getNamespaceInClassContext(IDefinition def, ICompilerProject project)
    {
        INamespaceDefinition namespace = def.resolveNamespace(project);

        IDefinition parent = def.getParent();

        if ( namespace != null && parent instanceof ClassDefinition )
        {
            // Iterate over the superclasses of this method's class.
            ClassDefinition cls  = (ClassDefinition)parent;
            ClassDefinition base = (ClassDefinition)cls.resolveBaseClass(project);

            if (base != null)
            {
                // Adjust the namespace if this is the protected namespace
                INamespaceDefinition protectedNS = cls.getProtectedNamespaceReference().resolveNamespaceReference(project);
                if (namespace.equals(protectedNS))
                    namespace = base.getProtectedNamespaceReference().resolveNamespaceReference(project);
            }
        }

        return namespace;
    }
    
    /**
     * Get the super class scope for the definition passed in.  This will return an ASScope
     * for the super class of whatever class declared the member passed in.
     * @param project       The project to resolve references in
     * @param member_def    The member to find a super class for
     * @return              The scope of the base class of the class the member_def is declared in.
     *                      This will return null if the member_def was not declared in a class.
     */
    public static ASScope getSuperClassScope(ICompilerProject project, IDefinition member_def)
    {
        IASScope containingScope = member_def.getContainingScope();
        if( containingScope instanceof ScopeView )
        {
            return ((ScopeView) containingScope).resolveSuperScope(project);
        }
        return null;
    }

    /**
     *  Find a member definition, given its name.
     *  @param iNode - the node that forms the reference.
     *    Should be a MemberAccessExpressionNode to get any useful result.
     *  @param member_name - the name of the member of interest.
     *  @param match_static_to_static - when true, only accept definitions 
     */
    public static IDefinition findMemberByName(IASNode iNode, String member_name,  boolean match_static_to_static, ICompilerProject project)
    {
        //  Find a scope to work with.
        IASScope starting_scope = null;

        //  Is this a static reference, e.g., ClassName.staticField?
        boolean is_static_reference = false;

        if ( iNode instanceof MemberAccessExpressionNode )
        {
            TypeDefinitionBase type = (TypeDefinitionBase)((MemberAccessExpressionNode)iNode).getLeftOperandNode().resolveType(project);

            if ( type != null )
            {
                starting_scope = ((TypeDefinitionBase)((MemberAccessExpressionNode)iNode).getLeftOperandNode().resolveType(project)).getContainedScope();
                is_static_reference = ((MemberAccessExpressionNode)iNode).getLeftOperandNode().resolve(project) instanceof ClassDefinition;
            }
        }
        else if ( iNode instanceof FunctionCallNode && ((FunctionCallNode)iNode).getNameNode() instanceof MemberAccessExpressionNode )
        {
            MemberAccessExpressionNode member_node = (MemberAccessExpressionNode) ((FunctionCallNode)iNode).getNameNode();
            
            TypeDefinitionBase type = (TypeDefinitionBase)member_node.getLeftOperandNode().resolveType(project);
            if ( type != null )
            {
                starting_scope = type.getContainedScope();
                is_static_reference = member_node.getLeftOperandNode().resolve(project) instanceof ClassDefinition;
            }
        }
        else if ( isInInstanceFunction(iNode, project) )
        {
            starting_scope = getClassScope(iNode, project);
            is_static_reference = false;
        }
        else if ( isInStaticClassFunction(iNode, project) )
        {
            starting_scope = getClassScope(iNode, project);
            is_static_reference = true;
        }

        //  Did we find a scope to work with?
        if ( starting_scope != null )
            return findMemberByName(starting_scope, member_name, match_static_to_static, is_static_reference, project);
        else
            return null;
    }

    /**
     *  Get the ASScope of the class that contains an inode.
     *  @param iNode - the inode of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the ASScope (holding both static and instance definitions)
     *    of the class enclosing the inode, or null if no such scope is found.
     */
    public static ASScope getClassScope(IASNode iNode, ICompilerProject project)
    {
        if ( isInInstanceFunction(iNode, project) || isInStaticClassFunction(iNode, project) )
        {
            ClassDefinition class_def = (ClassDefinition) getEnclosingFunctionDefinition(iNode, project).getAncestorOfType(ClassDefinition.class);
            if ( class_def != null )
                return class_def.getContainedScope();
        }

        return null;
    }

    /**
     *  Get the ASScope of the class that contains an inode.
     *  @param iNode - the inode of interest.
     *  @return the ASScope (holding both static and instance definitions)
     *    of the class enclosing the inode, or null if no such scope is found.
     *  @see #getClassScope(IASNode, ICompilerProject)
     */
    public ASScope getClassScope(IASNode iNode)
    {
        return getClassScope(iNode, this.project);
    }

    /**
     *  Search a scope and its enclosing scopes for a member whose name is known.
     *  @param scope - the innermost scope to search.
     *  @param member_name - the (string) name of interest.
     *  @param match_static_to_static - if set, then only return static definitions if is_static_reference is set.
     *  @param is_static_reference - caller sets this if the reference occurs in a context that is known to be static.
     *  @param project - an ICompilerProject for the current project.
     */
    public static IDefinition findMemberByName(IASScope scope, String member_name,  boolean match_static_to_static, boolean is_static_reference, ICompilerProject project)
    {
        if ( scope == null )
            return null;
        
        IDefinition result = null;

        //  A definition by the right name but in the wrong scope
        //  (e.g., an instance def found while looking for a static def).
        IDefinition possible_result = null;

        for ( IDefinition def: getPropertiesByNameForMemberAccess(scope, member_name, project) )
        {
            //  Check for matching scope: static references should only
            //  match static definitions, and vice versa.
            //  Note: the diagnostic could be improved by doing a subsequent
            //  check for definitions with matching names and conflicting scopes
            //  (i.e., a static reference to an instance field).
            if ( is_static_reference )
            {
                if ( def.isStatic() )
                {
                    result = def;
                    break;
                }
                else if ( match_static_to_static && possible_result != null )
                {
                    possible_result = def;
                    //  Keep looking for a static definition as a better match.
                    continue;
                }
            }
            else 
            {
                if ( !def.isStatic() )
                {
                    result = def;
                    break;
                }
            }
        }

        return result != null? result: possible_result;
    }

    /**
     *  Is the given binding an inaccessible reference?
     *  @param iNode - the iNode that anchors the reference.
     *  @param member - the Binding.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if the binding has no definition, but
     *    a search for the member by name in the iNode's 
     *    underlying type scopes finds something.
     */
    public static boolean isInaccessible(IASNode iNode, Binding member, ICompilerProject project)
    {
        assert(member.getName() != null);
        return member.getDefinition() == null && findMemberByName(iNode, member.getName().getBaseName(), true, project) != null;
    }
    
    /**
     *  Is the given binding an inaccessible reference?
     *  @param iNode - the iNode that anchors the reference.
     *  @param member - the Binding.
     *  @return true if the binding has no definition, but
     *    a search for the member by name in the iNode's 
     *    underlying type scopes finds something.
     *  @see #isInaccessible(IASNode, Binding, ICompilerProject)
     */
    public boolean isInaccessible(IASNode iNode, Binding member)
    {
        return isInaccessible(iNode, member, this.project);
    }


    /**
     *  Fetch the definiton of the given node's
     *    class' base class.
     *  @param iNode - the node of interest.
     *  @return the definition of the node's class' base class,
     *    or null if it not in a class or its class 
     *    has no base class.
     *  @see #getBaseClassDefinition(IASNode, ICompilerProject)
     */
    public IDefinition getBaseClassDefinition(IASNode iNode)
    {
        return getBaseClassDefinition(iNode, this.project);
    }

    /**
     *  Find a property in a defintion's containing scope.
     *  @param member_def - the definition of interest.
     *  @param project - the active compiler project.
     *  @return the definition found in the containing scope, or null if not found.
     */
    public static IDefinition findPropertyQualified(IDefinition member_def, ICompilerProject project)
    {
        ASScope containingScope = (ASScope)member_def.getContainingScope();
        return findPropertyQualified(containingScope, member_def, project);
    }

    /**
     *  Find a property in a defintion's containing scope.
     *  @param member_def - the definition of interest.
     *  @return the definition found in the containing scope, or null if not found.
     *  @see #findPropertyQualified(IDefinition, ICompilerProject)
     */
    public IDefinition findPropertyQualified(IDefinition member_def)
    {
        return findPropertyQualified(member_def, this.project);
    }

    /**
     *  Find a property in a (presumably) enclosing defintion's scope.
     *  @param enclosing_def - the definition to query.
     *  @param member_def - the prototype definition of the member desired.
     *  @param project - the active compiler project.
     *  @return the definition found in the enclosing scope, or null if not found.
     */
    public static IDefinition findPropertyQualified(IScopedDefinition enclosing_def, IDefinition member_def, ICompilerProject project)
    {
        return findPropertyQualified((ASScope)enclosing_def.getContainedScope(), member_def, project);
    }

    public static IDefinition getPropertyQualified(IScopedDefinition enclosing_def, IDefinition member_def, ICompilerProject project)
    {
        return getPropertyQualified((ASScope)enclosing_def.getContainedScope(), member_def, project);
    }

    /**
     *  Find a property in a (presumably) enclosing defintion's scope.
     *  @param enclosing_def - the definition to query.
     *  @param member_def - the prototype definition of the member desired.
     *  @return the definition found in the enclosing scope, or null if not found.
     *  @see #findPropertyQualified(IScopedDefinition, IDefinition, ICompilerProject)
     */
    public IDefinition findPropertyQualified(IScopedDefinition enclosing_def, IDefinition member_def)
    {
        return findPropertyQualified(enclosing_def, member_def, this.project);
    }

    /**
     *  Find a qualified property in a scope.
     *  @param scope - the scope to query.
     *  @param member_def - the prototype definition of the member desired.
     *  @param project - the active compiler project.
     *  @return the definition found in the enclosing scope, or null if not found.
     */
    public static IDefinition findPropertyQualified(ASScope scope, IDefinition member_def, ICompilerProject project)
    {
        IDefinition result = null; 

        if ( scope != null && member_def != null && member_def.getNamespaceReference() != null )
        {
            INamespaceDefinition namespace =
                member_def.getNamespaceReference().resolveNamespaceReference(project);
            if (namespace != null)
            {
                String baseName = member_def.getBaseName();

                result = scope.findPropertyQualified(
                        project, namespace, baseName, DependencyType.EXPRESSION);
            }
        }

        return result;
    }

    /**
     * Get a qualified property in a scope - this will look for properties with the same qualified name as member_def
     * in the scope passed in.
     * @param scope         the scope to look for the property in
     * @param member_def    the prototype definition of the member desired
     * @param project       the active compiler project
     * @return              the definition found in the passed in scope ,or null if not found
     */
    public static IDefinition getPropertyQualified(ASScope scope, IDefinition member_def, ICompilerProject project)
    {
        IDefinition result = null;

        if ( scope != null && member_def != null && member_def.getNamespaceReference() != null )
        {
            INamespaceDefinition namespace =
                    member_def.getNamespaceReference().resolveNamespaceReference(project);

            if (namespace != null)
            {
                result = getPropertyQualified( scope, namespace, member_def.getBaseName(), project);
            }
        }

        return result;
    }

    /**
     * Get a qualified property in a scope, given the namespace and base name to search for.
     * @param scope         the scope to look for the property in
     * @param namespace     the namespace of the member desired
     * @param baseName      the base name of the member desired
     * @param project       the active compiler project
     * @return              the definition found in the passed in scope ,or null if not found
     */
    public static IDefinition getPropertyQualified(ASScope scope, INamespaceDefinition namespace, String baseName, ICompilerProject project)
    {
        IDefinition result = null;

        if ( scope != null && namespace != null && baseName != null )
        {
            result = scope.getPropertyByNameForMemberAccess(
                (CompilerProject)project,
                baseName,
                Collections.singleton(namespace)
            );
        }

        return result;
    }

    /**
     *  Find a qualified property by name in a scope.
     *  @param scope - the scope to query.
     *  @param member_name - the name of the desired member.
     *  @param project - the active compiler project.
     *  @return the definition found in the scope, or null if not found.
     */
    public static IDefinition findProperty(ASScope scope, String member_name, ICompilerProject project, boolean lookForStatics)
    {
        IDefinition result = null; 

        if ( scope != null )
        {
            result = scope.findProperty(
                project,
                member_name,
                DependencyType.EXPRESSION,
                false
            );
        }

        return result;
    }

    /**
     *  Find the definition of the function that encloses the given node, if any.
     *  @param iNode - the inode of interest. 
     *  @param project - an ICompilerProject for the current project.
     *  @return the definition of any function that encloses the inode, or null
     *    if not found (or if the function is undefined for some reason).
     */
    public static FunctionDefinition getEnclosingFunctionDefinition(IASNode iNode, ICompilerProject project)
    {
        IASNode func_node = iNode.getAncestorOfType(FunctionNode.class);

        if ( func_node != null )
        {
            return  (FunctionDefinition) getDefinition(func_node, project);
        }

        return null;
    }

    /**
     *  Find the definition of the function that encloses the given node, if any.
     *  @param iNode - the inode of interest. 
     *  @return the definition of any function that encloses the inode, or null
     *    if not found (or if the function is undefined for some reason).
     *  @see #getEnclosingFunctionDefinition(IASNode, ICompilerProject)
     */
    public FunctionDefinition getEnclosingFunctionDefinition(IASNode iNode)
    {
        return getEnclosingFunctionDefinition(iNode, this.project);
    }

    /**
     *  Is the given inode in an instance function?
     *  @param iNode - the inode of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if the inode has an enclosing function
     *    and that function is a non-static class member.
     */
    public static boolean isInInstanceFunction(IASNode iNode, ICompilerProject project)
    {
        FunctionDefinition func_def = getEnclosingFunctionDefinition(iNode, project);
        return func_def != null && func_def.getFunctionClassification() == FunctionClassification.CLASS_MEMBER && !func_def.isStatic();
    }

    
    /**
     *  Is the given inode in an instance function?
     *  @param iNode - the inode of interest.
     *  @return true if the inode has an enclosing function
     *    and that function is a non-static class member.
     *  @see #isInInstanceFunction(IASNode, ICompilerProject)
     */
    public boolean isInInstanceFunction(IASNode iNode)
    {
        return isInInstanceFunction(iNode, this.project);
    }

    /**
     *  Is the given inode in a static function?
     *  @param iNode - the inode of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if the inode has an enclosing function
     *    and that function is a static class member.
     */
    public static boolean isInStaticClassFunction(IASNode iNode, ICompilerProject project)
    {
        FunctionDefinition func_def = getEnclosingFunctionDefinition(iNode, project);
        return func_def != null && func_def.getFunctionClassification() == FunctionClassification.CLASS_MEMBER && func_def.isStatic();
    }


    /**
     *  Is the given Binding inaccessible, i.e., known to 
     *  an underlying type scope but not defined here
     *  due to access restrictions?
     *  @param scope - the innermost underlying type scope.
     *  @param b - the Binding of interest
     *  @param project - an ICompilerProject for the current project.
     */
    private static boolean isInaccessible(IASScope scope, Binding b, ICompilerProject project)
    {
        return b.getDefinition() == null && findMemberByName(scope, b.getName().getBaseName(), true, false, project) != null;
    }

    /**
     *  Is the given Binding inaccessible, i.e., known to 
     *  an underlying type scope but not defined here
     *  due to access restrictions?
     *  @param containingScope - the innermost underlying type scope.
     *  @param b - the Binding of interest
=     */
    public boolean isInaccessible(ASScope containingScope, Binding b)
    {
        return isInaccessible(containingScope,  b, this.project);
    }

    /**
     *  Get the name of the class enclosing an instance function in which 
     *  some problematic construct resides.
     *  @param iNode - the problematic construct.
     *  @param project - an ICompilerProject for the current project.
     *  @return the name of the enclosing class.
     */
    public static String getEnclosingClassName(IASNode iNode, ICompilerProject project)
    {
        assert(isInInstanceFunction(iNode, project));  //  assert precondition.

        IDefinition class_def = getEnclosingFunctionDefinition(iNode, project).getAncestorOfType(ClassDefinition.class);
        return class_def.getBaseName();
    }

    /**
     *  Get the name of the class enclosing an instance function in which 
     *  some problematic construct resides.
     *  @param iNode - the problematic construct.
     *  @return the name of the enclosing class.
     *  @see #getEnclosingClassName(IASNode, ICompilerProject)
     */
    public String getEnclosingClassName(IASNode iNode)
    {
        return getEnclosingClassName(iNode, this.project);
    }

    /**
     *  Fetch the collection of definitions in the given scope or its underlying scopes
     *  that match the given name.
     *  @param scope - the innermost scope to search.
     *  @param member_name - the (string) name of interest.
     *  @param project - an ICompilerProject for the current project.
     */
    public static Collection<IDefinition> getPropertiesByNameForMemberAccess(IASScope scope, String member_name, ICompilerProject project)
    {
        assert(scope != null);  //  check precondition.
        return ((ASScope)scope).getPropertiesByNameForMemberAccess(
            (CompilerProject)project, 
            member_name, 
            ASScopeBase.allNamespacesSet
        );
    }

    /**
     *  Get an abstract string description of a node, suitable for a diagnostic.
     *  @return the best guess we can come up with for a node's user-friendly string representation.
     */
    public static String getDiagnosticString(IASNode iNode)
    {
        String content = null;

        switch ( iNode.getNodeID() )
        {
            case IdentifierID:
            case NamespaceIdentifierID:
            case NonResolvingIdentifierID:
            case QualifiedNameExpressionID:
                content = ((IdentifierNode)iNode).getName();
                break;

            case FunctionCallID:
            {
                FunctionCallNode func = (FunctionCallNode)iNode;
                
                if ( func.getNameNode() != null )
                {
                    // return to avoid quoting the result twice.
                    return getDiagnosticString(func.getNameNode());
                }
                else
                {
                    content = iNode.getNodeID().getParaphrase();
                }
                
                break;
            }

            case LiteralArrayID:
            case LiteralBooleanID:
            case LiteralNumberID:
            case LiteralObjectID:
            case LiteralRegexID:
            case LiteralStringID:
            case LiteralXMLID:
            case LiteralID:
                content = ((LiteralNode)iNode).getValue();
                break;

            case LiteralNullID:
                content = "null";
                break;

            case LiteralVoidID:
                content = "void";
                break;

            case MemberAccessExpressionID:
                content = ((MemberAccessExpressionNode)iNode).getDisplayString();
                break;

            default:
                content = iNode.getNodeID().getParaphrase();
        }

        return  "'" + content + "'";
    }

    /**
     *  Get the set of open namespaces for the given node.  
     *  @param iNode - the node of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the open namespaces at this node as a Nsset,
     *    or null if the node doesn't have a containing scope.
     */
    public static Nsset getOpenNamespaces(IASNode iNode, ICompilerProject project)
    {
        ASScope scope = getASScope(iNode);
        if (scope == null)
            return null;

        Set<INamespaceDefinition> namespaceSet = scope.getNamespaceSet(project);
        Nsset nsSet = convertSetINamespaceToNsset(namespaceSet);
        return nsSet;        
    }
    
    /**
     *  Get the set of open namespaces for the given node,
     *  as appropriate for <code>super[...]</code> access.
     *  @param iNode - the node of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the open namespaces at this node as a Nsset,
     *    or null if the node doesn't have a containing scope.
     */
    public static Nsset getOpenNamespacesForSuper(IASNode iNode, ICompilerProject project,
                                                  IDefinition superDef)
    {
        ASScope scope = getASScope(iNode);
        if (scope == null)
            return null;

        Set<INamespaceDefinition> namespaceSet = scope.getNamespaceSetForSuper(project, superDef);
        Nsset nsSet = convertSetINamespaceToNsset(namespaceSet);
        return nsSet;        
    }
    

    /**
     *  Convert a set of INamespaceDefinition objects into a Nsset.
     *  @param namespaceSet - the set of INamespaceDefinition objects.
     *  @return the namespaces as a Nsset.
     */
    public static Nsset convertSetINamespaceToNsset(Set<INamespaceDefinition> namespaceSet)
    {
        ArrayList<Namespace> ns_set = new ArrayList<Namespace>(namespaceSet.size());

        for (INamespaceDefinition namespace : namespaceSet)
        {
            Namespace aetNamespace = ((NamespaceDefinition)namespace).getAETNamespace();
            ns_set.add(aetNamespace);
        }

        return new Nsset(ns_set);
    }

    /**
     *  Get the given node's containing scope.
     *  (Convenience method that hides a downcast.)
     *  @param iNode - the node of interest.
     *  @return the node's scope, or null if not available.
     */
    public static ASScope getASScope(IASNode iNode)
    {
        return ((NodeBase)iNode).getASScope();
    }

    /**
     *  Is the given definition const?
     *  @param iNode - the root of the definition.
     *  @param project - an ICompilerProject for the current project.
     *  @return true if iNode can be resolved to a const definition.
     */
    public static boolean isConst(IASNode iNode, ICompilerProject project)
    {
        return isConstDefinition(getDefinition(iNode, project));
    }

    /**
     *  Is the given definition const?
     *  @param iNode - the root of the definition.
     *  @return true if iNode can be resolved to a const definition.
     *  @see #isConst(IASNode iNode,  ICompilerProject cache)
     */
    public boolean isConst(IASNode iNode)
    {
        return isConst(iNode, this.project);
    }

    /**
     *  Is the given definition a constant?
     *  @param def - the definition of interest.
     *  @return true if the definition is of a const.
     */
    public static boolean isConstDefinition(IDefinition def)
    {
        return def instanceof IConstantDefinition;
    }

    /**
     *  Is the given node in a constructor?
     *  @param iNode - the i-node of interest.
     *  @return true if the node is in a constructor function.
     */
    @SuppressWarnings("unchecked")
    public static boolean isInConstructor(IASNode iNode)
    {
        FunctionNode fnode = (FunctionNode) searchUpForType(iNode, FunctionNode.class);
        return fnode != null && fnode.isConstructor();
    }

    /**
     *  Is the given i-node inside a variable declaration?
     *  @param iNode - the i-node of interest.
     *  @return true if the node has a VariableNode or VariableExpressionNode parent.
     */
    @SuppressWarnings("unchecked")
    public static boolean isInVariableDeclaration(IASNode iNode)
    {
        return searchUpForType(iNode, VariableNode.class, VariableExpressionNode.class) != null;
    }

    /**
     *  Search a node's parent chain for an ancestor of any of a group of classes.
     *  @param iNode - the node of interest.
     *  @param desired - the group of classes desired.
     *  @return the first node in the node and its ancestors that matches a desired class.
     */
    private static IASNode searchUpForType(IASNode iNode, Class<? extends IASNode> ... desired)
    {
        if ( iNode == null )
            return null;

        IASNode found = null;
        for ( Class<? extends IASNode> candidate: desired)
        {
            if ( candidate.isInstance(iNode) )
                found = iNode;
            else
                found = iNode.getAncestorOfType(candidate);

            if ( found != null )
                break;
        }

        return found;
    }

    /**
     *  Fetch the most appropriate part of a type name for diagnostics.
     *  @return the type part of a parameterized type, or the input node.
     */
    public IASNode getPotentiallyParameterizedType(IASNode iNode)
    {
        IASNode result = iNode;

        if ( iNode instanceof TypedExpressionNode )
        {
            result = ((TypedExpressionNode)iNode).getTypeNode();
        }

        return result;
        
    }

    /**
     *  Get the Nth child of a node per the BURM's semantics.
     */
	public static IASNode getNthChild( IASNode node, int index)
	{
        IASNode result = null;
        
        switch( node.getNodeID() )
        {
            case BindableVariableID:
            case VariableID:
            {
                IVariableNode var = (IVariableNode) node;
                switch( index )
                {
                    case 0:
                    {
                        result = var.getNameExpressionNode();
                        break;
                    }
                    default:
                    {
                        //  We have to go hunt among the children
                        //  for the nodes that are relevant to the BURM.
                        int lastFoundChildPos = 0;

                        result = var.getVariableTypeNode();
                        if ( result != null )
                        {
                            lastFoundChildPos++;
                            if ( index == lastFoundChildPos)
                                break;
                        }

                        result = var.getAssignedValueNode();
                        if ( result != null )
                        {
                            lastFoundChildPos++;
                            if ( index == lastFoundChildPos)
                                break;
                        }

                        //  Look for chained variable declarations.
                        int needle = 0;
                        while ( needle < node.getChildCount() && lastFoundChildPos < index )
                        {
                            if ( node.getChild(needle) instanceof IVariableNode )
                                lastFoundChildPos++;
                            if ( lastFoundChildPos < index )
                                needle++;
                        }

                        assert(lastFoundChildPos == index): "getNthChild() failed, should have been constrained by getChildCount(node)";
                        return ( node.getChild(needle));
                    }
                    
                }
                break;
            }
            case FunctionID:
            case GetterID:
            case SetterID:
            {
                FunctionNode func = (FunctionNode) node;
                switch( index )
                {
                    case 0:
                        result = func.getNameExpressionNode();
                        break;
                    case 1:
                        result = func.getParametersContainerNode();
                        break;
                    case 2:
                        result = func.getReturnTypeNode();
                        if ( result != null )
                            break;
                    case 3:
                        assert (func.hasBeenParsed()) : "getScopedNode() called on a function before the body has been parsed";
                        result = func.getScopedNode();
                        break;
                }
                break;
            }
            case Op_CommaID:
            {
                switch( index )
                {
                    case 0:
                    {
                        result = node.getChild(node.getChildCount()-1);
                        break;
                    }
                    default:
                        result = node.getChild(index - 1);
                    
                }
                break;
            }
            case TryID:
			{
                ITryNode tryNode = (ITryNode) node;
				switch( index )
				{
					case 0:
					{
						result = tryNode.getStatementContentsNode();
						break;
					}
					case 1:
					{
						if  ( tryNode.getFinallyNode() != null )
                        {
                            result = tryNode.getFinallyNode();
                        }
                        else 
                        {
                            assert ( tryNode.getCatchNodeCount() > 0 );
                            result = tryNode.getCatchNode(0);
                        }
                        break;
					}
					default:
					{
                        //  Note: If the try has a contents and finally nodes,
                        //  they are presented to the CG by getNthChild() as child
                        //  nodes 0 and 1 before the n-ary tail of catch nodes.
                        if (tryNode.getStatementContentsNode() != null)
                            index--;
                        if (tryNode.getFinallyNode() != null)
                            index--;
                        result = tryNode.getCatchNode(index);
                    }
				}
				break;
			}
            case NamespaceID:
            {
                // Skip over MetaTagsNode and NamespaceIdentifierNode
                final NamespaceNode nsNode = (NamespaceNode)node;
                final IASNode nsName = nsNode.getNameExpressionNode();
                final IASNode nsURI = nsNode.getNamespaceURINode();
                switch(index)
                {
                    case 0:
                        if(nsName != null)
                            result = nsName;
                        else 
                            result = nsURI;
                        break;
                    case 1:
                        if(nsName != null && nsURI != null)
                            result = nsURI;
                        else 
                            throw new ArrayIndexOutOfBoundsException(index);
                        break;
			default:
                        throw new ArrayIndexOutOfBoundsException(index);
                }
                break;
            }
            default:
			{
				result = node.getChild(index);
				break;
			}
		}

        assert(result != null): String.format("getNthChild(%s,%d) null result", node.getNodeID(), index);
        return result;
    }

    /**
     *  Get the child count for nodes whose
     *  CodeModel-centric child count isn't 
     *  reliable.
     */
    public static int getChildCount(IASNode node)
    {
        int result = 0;
        
        switch( node.getNodeID() )
        {
            case BindableVariableID:
            case VariableID:
            {
                IVariableNode var = (IVariableNode) node;

                assert ( var.getNameExpressionNode() != null ): "Variable has null name expression.";
                result = 1;

                if ( var.getVariableTypeNode() != null )
                    result++;

                if ( var.getAssignedValueNode() != null )
                    result++;

                //  Scan for chained declarations.
                for ( int i = 0; i < node.getChildCount(); i++ )
                {
                    if ( node.getChild(i) instanceof IVariableNode )
                        result++;
                }
                break;
            }
            case FunctionID:
            case GetterID:
            case SetterID:
            {
                FunctionNode func = (FunctionNode)node;
                assert ( func.getNameExpressionNode() != null ): "Function has null name expression";
                assert ( func.getParametersContainerNode() != null ): "Function has null parameters";
                result = 2;

                if ( func.getReturnTypeNode() != null )
                    result++;

                if ( func.getScopedNode() != null )
                    result++;
            }
            break;
            case NamespaceID:
            {
                final NamespaceNode nsNode = (NamespaceNode)node;
                assert nsNode.getNameExpressionNode() != null : "'name' node is required";
                result = 1;
                if (nsNode.getNamespaceURINode() != null)
                    result = 2;
                break;
            }
            default:
                result = node.getChildCount();
        }
        return( result);
   	}

    /**
     *  @return a parameter's definition.
     *  @param iNode - the parameter node.
     */
    public static IDefinition getParameterContent(IASNode iNode)
    {
        return ((( IParameterNode )iNode).getDefinition());
    }
    
    /**
     *  @return the string content of a literal.
     *  @param iNode - the literal node.
     */
    public static String getStringLiteralContent(IASNode iNode)
    {
        return (( ILiteralNode )iNode).getValue();
    }

    /**
     *  @return the uint content of a numeric literal.
     *  @param iNode - the literal node.
     */
    public static Long getUintContent(IASNode iNode)
    {
        return Long.valueOf((( INumericLiteralNode )iNode).getNumericValue().toUint32());
    }

    /**
     *  @return the double content of a numeric literal.
     *  @param iNode - the literal node.
     */
    public static Double getDoubleContent(IASNode iNode)
    {
        return Double.valueOf((( INumericLiteralNode )iNode).getNumericValue().toNumber());
    }

    /**
     *  @return the boolean content of a literal.
     *  @param iNode - the literal node.
     */
    public static Boolean getBooleanContent(IASNode iNode)
    {
        if ( "true".equalsIgnoreCase(getStringLiteralContent(iNode)) )
        {
            return Boolean.TRUE;
        }
        else
            return Boolean.FALSE;
    }

    /**
     *  @return the name of an identifier.
     *  @param iNode - the IIdentifier node.
     */
    public static String getIdentifierContent(IASNode iNode)
    {
        return (( IIdentifierNode )iNode).getName();
    }

    /**
     *  @return the int content of a numeric literal.
     *  @param iNode - the literal node.
     */
    public static Integer getIntegerContent(IASNode iNode)
    {
        return Integer.valueOf((( INumericLiteralNode )iNode).getNumericValue().toInt32());
    }

    /**
     *  @return a node cast to MXMLEventSpecifierNode type.
     *  @param iNode - the MXMLEventSpecifierNode node.
     */
    public static IMXMLEventSpecifierNode getMXMLEventSpecifierContent(IASNode iNode)
    {
        return (IMXMLEventSpecifierNode)iNode;
    }

    /**
     *  Explore a MemberAccessNode and decide if
     *  its stem is a referenceto a package.
     *  @return a "feasible" cost of this node
     *    is of the form foo.bar, where foo is a package.
     */
    public static int isDottedName(IASNode n)
    {
        if ( n instanceof MemberAccessExpressionNode && ((MemberAccessExpressionNode)n).stemIsPackage() )
            return 1;

        //  Return "unfeasible" cost.
        return Integer.MAX_VALUE;
    }
    
    /**
     *  Get the definition associated with a node's qualifier
     *  and decide if the qualifier is a compile-time constant.
     *  @param iNode - the node to check.
     *  @pre - the node has an IdentifierNode 0th child.
     *  @return an attractive cost if the child has a known namespace, i.e.,
     *    it's a compile-time constant qualifier.
     */
    public static int qualifierIsCompileTimeConstant(IASNode iNode, ICompilerProject project)
    {
        IdentifierNode qualifier = (IdentifierNode) SemanticUtils.getNthChild(iNode, 0);
        IDefinition def = qualifier.resolve(project);

        if ( def instanceof NamespaceDefinition )
            return 1;
        else
            return Integer.MAX_VALUE;
    }

    /**
     *  Get the definition associated with a node's qualifier
     *  and decide if the qualifier is a compile-time constant.
     *  @param iNode - the node to check.
     *  @pre - the node has an IdentifierNode 0th child.
     *  @return an attractive cost if the child has a known namespace, i.e.,
     *    it's a compile-time constant qualifier.
     *  @see #qualifierIsCompileTimeConstant(IASNode, ICompilerProject)
     */
    public int qualifierIsCompileTimeConstant(IASNode iNode)
    {
        return qualifierIsCompileTimeConstant(iNode, this.project);
    }

    /**
     *  Get the definition associated with a node's qualifier
     *  and decide if the qualifier is an interface name.
     *  @param iNode - the node to check.
     *  @pre - the node has an IdentifierNode 0th child.
     *  @return an attractive cost if the child is an interface.
     */
    public static int qualifierIsInterface(IASNode iNode, ICompilerProject project)
    {
        IdentifierNode qualifier = (IdentifierNode) SemanticUtils.getNthChild(iNode, 0);
        IDefinition def = qualifier.resolve(project);

        if ( def instanceof InterfaceDefinition )
            return 1;
        else 
            return Integer.MAX_VALUE;
    }

    /**
     *  Get the definition associated with a node's qualifier
     *  and decide if the qualifier is an interface name.
     *  @param iNode - the node to check.
     *  @pre - the node has an IdentifierNode 0th child.
     *  @return an attractive cost if the child is an interface.
     *  @see #qualifierIsInterface(IASNode, ICompilerProject)
     */
    public  int qualifierIsInterface(IASNode iNode)
    {
        return qualifierIsInterface(iNode, this.project);
    }
    
    /**
     *  Transform a leaf AST into a compile-time constant;
     *  note that more complex constant folding is done by
     *  a series of rules in the BURM.  This routine looks
     *  at "terminal" constants, e.g., 1 or foo where foo
     *  is a namespace.
     *  @param iNode - the i-node of interest.
     *  @param project - an ICompilerProject for the current project.
     *  @return the constant value, if there is one.
     */
    public static Object transformNameToConstantValue(IASNode iNode, ICompilerProject project)
    {
        Object result = null;
        if ( iNode instanceof ExpressionNodeBase )
        {
            IASNode parentNode = iNode.getParent();
            if (parentNode instanceof BaseTypedDefinitionNode)
            {
                BaseTypedDefinitionNode parentDefinitionNode = (BaseTypedDefinitionNode)parentNode;
                if (parentDefinitionNode.getNameExpressionNode() == iNode)
                    return null;
                if (parentDefinitionNode.getTypeNode() == iNode)
                    return null;
            }
            else if (parentNode instanceof IterationFlowNode)
            {
                IterationFlowNode parentIterationFlowNode = (IterationFlowNode)parentNode;
                if (parentIterationFlowNode.getLabelNode() == iNode)
                    return null;
            }
            //  Try for a compile-time constant value.
            IDefinition val = ((ExpressionNodeBase)iNode).resolve(project);

            if ( val instanceof NamespaceDefinition )
            {
                NamespaceDefinition ns = (NamespaceDefinition)val;
                result = ns.resolveAETNamespace(project);
            }
            else if( val instanceof ConstantDefinition )
            {
                ConstantDefinition cd = (ConstantDefinition)val;
                result = cd.resolveValueFrom(project, (NodeBase)iNode);
            }
        }

        return result;
    }

    /**
     *  Transform a leaf AST into a compile-time constant;
     *  note that more complex constant folding is done by
     *  a series of rules in the BURM.  This routine looks
     *  at "terminal" constants, e.g., 1 or foo where foo
     *  is a namespace.
     *  @param iNode - the i-node of interest.
     *  @return the constant value, if there is one.
     *  @see #transformNameToConstantValue(IASNode, ICompilerProject)
     */
    public Object transformNameToConstantValue(IASNode iNode)
    {
        return transformNameToConstantValue(iNode, this.project);
    }

    /**
     * Check for identifiers that don't have a namespace quailifier. Generates problem if found.
     * 
     * @param scope is the scope where problems will be added
     * @param node is the definition node for the defintion we are checking
     * @param definition is the dfintion we are checking
     * @param className is the class in which the identifier lives, or null if not in a class. Used for error reporting
     */
    public static void checkScopedToDefaultNamespaceProblem(LexicalScope scope, BaseDefinitionNode node, IDefinition definition, String className)
    {
        if (node == null)       // if we don't have a node, it means we didn't come from source code, so there is no point
                                // in doing a semantic check
            return;
        INamespaceReference nsref = definition.getNamespaceReference();
        INamespaceDecorationNode dec = node.getNamespaceNode();
        if ((dec ==null) &&(nsref instanceof INamespaceDefinition.IInternalNamespaceDefinition))
        {
            String type = "declaration";        // should never see this string...
            if (definition instanceof IFunctionDefinition)
                type = "function";
            else if (definition instanceof IClassDefinition)
                type = "class";
            else if (definition instanceof IInterfaceDefinition)
                type = "interface";
            String identifierName = type + " '" + definition.getBaseName() + "'";
            scope.addProblem( new ScopedToDefaultNamespaceProblem( node, identifierName, className));
        }
    }
    
    /**
     * Checks that a given function definition has a return type, and logs a problem if not
     * 
     * @param scope is the scope where problems are to be logged
     * @param node is the function node that is being checked (used for location reporting(
     * @param func is the definition of the function to be checked.
     */
    public static void checkReturnValueHasNoTypeDeclaration(LexicalScope scope, IFunctionNode node, IFunctionDefinition func)
    {
        // constructors aren't supposed to have return types, so skip this check for them
        if (node.isConstructor())
            return;

        // Compiler synthesized nodes may not report return types as we expect. For example
        // the class generated for embedding has an implicit return type node, which causes our 
        // check to think the "user code" has no return type. So skip these kinds of nodes....
        if (node.getStart() == node.getEnd())
            return;
        
        IExpressionNode returnType = node.getReturnTypeNode();
        
        // check for return type declaration
        if (returnType == null)       
        {
            // if none found, derive best source location for problem report
            IASNode sourceLoc = node;
            IExpressionNode nameNode = node.getNameExpressionNode();
            if (nameNode != null)
                sourceLoc = nameNode;
            scope.addProblem(new ReturnValueHasNoTypeDeclarationProblem(sourceLoc, func.getBaseName()));
        }
    }
    
    /**
     * Determines if a list of definitions consists of a matched getter/setter pair.
     * 
     * @param defs The list of definitions to analyze.
     * @param project The context in which they are analyzed.
     * @return <code>true</code> if the definitions are a getter/setter pair.
     */
    public static boolean isGetterSetterPair(List<IDefinition> defs, ICompilerProject project)
    {
        // Must be a pair to be a getter setter pair. A pair plus others doesn't count.
        if (defs.size() != 2)
            return false;
        
        IDefinition def0 = defs.get(0);
        IDefinition def1 = defs.get(1);
        return isGetterSetterPair(def0, def1, project);
    }
    
    /**
     * Determines if a pair of definitions consists of a matched getter/setter pair.
     * 
     * @param def0 The first definitions to analyze.
     * @param def1 The first definitions to analyze.
     * @param project The context in which they are analyzed.
     * @return <code>true</code> if the definitions are a getter/setter pair.
     */
    public static boolean isGetterSetterPair(IDefinition def0, IDefinition def1, ICompilerProject project)
    {
        if (!(def0 instanceof IAccessorDefinition))
            return false;
      
        if (!(def1 instanceof IAccessorDefinition))
            return false;
        
        return ((IAccessorDefinition)def0).resolveCorrespondingAccessor(project) == def1;
    }
    
    /**
     * This is similar to the <code>resolveBaseClass()</code> method of <code>IClassDefinition</code>,
     * except it reports problems if the base class doesn't exist,
     * if it isn't actually a class, or if it is final;
     * it also returns the class definition for <code>Object</code> in these error cases.
     */
    public static ClassDefinition resolveBaseClass(ICommonClassNode classNode,
                                                   ClassDefinition classDefinition,
                                                   ICompilerProject project,
                                                   Collection<ICompilerProblem> problems)
    {
        IReference baseClassReference = classDefinition.getBaseClassReference();
        
        // Object has no base class.
        if (baseClassReference == null)
            return null;
        
        ITypeDefinition superclassDefinition = classDefinition.resolveType(
            baseClassReference, project, DependencyType.INHERITANCE);
        
        if (superclassDefinition == null)
        {
            IASNode problemNode = getBaseClassProblemNode(classNode, classDefinition);
            String baseClassReferenceName = baseClassReference.getName();

            //  The base class reference might be ambiguous.
            IDefinition foundDefinition = baseClassReference.resolve(project, (ASScope)classDefinition.getContainingScope(), DependencyType.INHERITANCE, true);
            if ( AmbiguousDefinition.isAmbiguous(foundDefinition))
                problems.add(new AmbiguousReferenceProblem(problemNode, baseClassReferenceName));
            else
                problems.add(new UnknownSuperclassProblem(problemNode, baseClassReferenceName));
            
            // Repair by making the class extend Object.
            superclassDefinition = getObjectDefinition(project);
        }
        else if (superclassDefinition instanceof IInterfaceDefinition)
        {
            IASNode problemNode = getBaseClassProblemNode(classNode, classDefinition);
            problems.add(new CannotExtendInterfaceProblem(problemNode));
            
            // Repair by making the class extend Object.
            superclassDefinition = getObjectDefinition(project);
        }
        else if (superclassDefinition.isFinal())
        {
            IASNode problemNode = getBaseClassProblemNode(classNode, classDefinition);
            problems.add(new BaseClassIsFinalProblem(problemNode));
            
            // Repair by making the class extend Object.
            superclassDefinition = getObjectDefinition(project);
        }
        else if (superclassDefinition == classDefinition)
        {
            problems.add(new CircularTypeReferenceProblem(classDefinition, classDefinition.getQualifiedName()));
            
            // Repair by making the class extend Object.
            superclassDefinition = getObjectDefinition(project);
        }
        
        // Report a problem if the superclass is deprecated
        // and the reference to it is not within a deprecated API.
        if (superclassDefinition != null && superclassDefinition.isDeprecated())
        {
            IASNode problemNode = getBaseClassProblemNode(classNode, classDefinition);
            if (!SemanticUtils.hasDeprecatedAncestor(problemNode))
            {
                ICompilerProblem problem = SemanticUtils.createDeprecationProblem(superclassDefinition, problemNode);
                problems.add(problem);
            }
        }

        return (ClassDefinition)superclassDefinition;
    }
    
    private static IASNode getBaseClassProblemNode(ICommonClassNode classNode, ClassDefinition classDefinition)
    {
        // If we have a source node for 'class A extends B', return the node for B.
        if (classNode instanceof IClassNode)
            return ((IClassNode)classNode).getBaseClassExpressionNode();
        
        // Otherwise, try to get the class node from the definition.
        return classDefinition.getNode();
    }
    
    private static IClassDefinition getObjectDefinition(ICompilerProject project)
    {
        IClassDefinition objectDefinition = (IClassDefinition)project.getBuiltinType(
            IASLanguageConstants.BuiltinType.OBJECT);
        
        if (objectDefinition == null)
        {
            // Abort codegen with a more comprehensible diagnostic.
            throw new MissingBuiltinException(IASLanguageConstants.Object);
        }
        
        return objectDefinition;
    }
        
    public static boolean isValidImport(IImportNode importNode, ICompilerProject project,
                                        boolean inInvisibleCompilationUnit)
    {
        String importName = importNode.getImportName();
        importName = project.getActualPackageName(importName);
        
        // First check whether the import name matches
        // a definition in the project scope.
        ASProjectScope projectScope = (ASProjectScope)project.getScope();
        if (projectScope.isValidImport(importName))
            return true;
        
        // For an invisible compilation unit, which doesn't contribute
        // definitions to the project scope, we must also check
        // whether it matches an externally visible definition
        // in the file.
        if (inInvisibleCompilationUnit)
        {
            IFileNode fileNode = (IFileNode)importNode.getAncestorOfType(IFileNode.class);
            IDefinition[] externallyVisibleDefinitionsInThisFile =
                fileNode.getTopLevelDefinitions(false, true);
            for (IDefinition d : externallyVisibleDefinitionsInThisFile)
            {
                String qName = d.getQualifiedName();
                if (qName.equals(importName))
                    return true;
                
                String wildcardQName = ImportNode.makeWildcardName(qName);
                if (wildcardQName.equals(importName))
                    return true;
            }
        }
        
        return false;
    }

    /**
     * Determine if a given IDefinition is the definition of a type (class or interface)
     * @param d     the definition to check
     * @return      true if the Definition represents a Type
     */
    public static boolean isType(IDefinition d)
    {
        return d instanceof ITypeDefinition;
    }
    

    /**
     * Check if {@code node} is in an E4X filter expression.
     * 
     * @param node AST node to be checked.
     * @return True if the node is in an E4X filter expression without crossing
     * a block.
     */
    public static boolean isE4XWildcardProperty(final IdentifierNode node)
    {
        assert node != null : "node can't be null";
        IASNode blockOrFilterNode = node.getParent();
        
        // "*::bar", "foo::*", "foo.*", "foo.(@* == 10) are not E4X wildcard properties
        if (blockOrFilterNode instanceof MemberAccessExpressionNode ||
            blockOrFilterNode instanceof UnaryOperatorAtNode)
            return false;
        
        while (blockOrFilterNode != null &&
               blockOrFilterNode.getNodeID() != ASTNodeID.BlockID &&
               blockOrFilterNode.getNodeID() != ASTNodeID.E4XFilterID)
        {
            blockOrFilterNode = blockOrFilterNode.getParent();
        }

        if (blockOrFilterNode != null && blockOrFilterNode.getNodeID() == ASTNodeID.E4XFilterID)
            return true;
        else
            return false;
    }

    /**
     *  Decide if an assignment node is in a context that merits a warning.
     *  @return true if an assignment has a path to a parent's conditional
     *  expression that contains only Boolean operators.
     */
    public static boolean isUnprotectedAssignmentInConditional(final IASNode node)
    {
        IASNode current = node;
        IASNode parent  = current.getParent();

        while ( parent != null )
        {
            switch ( parent.getNodeID() )
            {
                case Op_LogicalAndID:
                case Op_LogicalOrID:
                case Op_LogicalNotID:
                case ContainerID:
                case ConditionalID:
                    current = parent;
                    parent  = current.getParent();
                    break;
                
                case WhileLoopID:
                    return current == getNthChild(parent,0);

                case DoWhileLoopID:
                    return current == getNthChild(parent,1);

                case IfStatementID:
                    return current == getNthChild(parent,0);

                default:
                    return false;
            }
        }

        return false;
    }

    /**
     *  Downcast an IDefinition and get an AET name from it.
     *  @param def - the definition.
     *  @param project - the active project.
     *  @return the definition's AET name.
     */
    public static Name getAETName(IDefinition def, ICompilerProject project)
    {
        return ((DefinitionBase)def).getMName(project);
    }

    /**
     *  Downcast an IDefinition and get an AET name from it.
     *  @param def - the definition.
     *  @return the definition's AET name.
     *  @see #getAETName(IDefinition, ICompilerProject) to which this delegates.
     */
    public Name getAETName(IDefinition def)
    {
        return ((DefinitionBase)def).getMName(this.project);
    }

    /**
     * Determines whether the specified node has an ancestor
     * which is a definition node with <code>[Deprecated]</code> metadata.
     * <p>
     * The node itself is not checked for such metadata.
     * 
     * @param node The node whose ancestors should be checked.
     * @return <code>true</code> if an ancestor is deprecated.
     */
    public static boolean hasDeprecatedAncestor(IASNode node)
    {
        for (IASNode ancestor = node.getParent();
             ancestor != null;
             ancestor = ancestor.getParent())
        {
            if (ancestor instanceof IDefinitionNode)
            {
                IDefinition definition = ((IDefinitionNode)ancestor).getDefinition();
                if (definition.isDeprecated())
                    return true;
            }
        }
        
        return false;
    }

    /**
     * Uses the <code>[Deprecated]</code> metadata of the specified definition
     * to create one of five different deprecation problems, depending on
     * the presence of <code>message</code>, <code>since</code>, and
     * <code>replacement</code> attributes in the metadata.
     * 
     * @param definition A deprecated definition.
     * @param site The node referring to the deprecated definition,
     * which determines the problem location.
     * @return An {@link ICompilerProblem}.
     */
    public static ICompilerProblem createDeprecationProblem(IDefinition definition, IASNode site)
    {
        ICompilerProblem problem = null;

        IDeprecationInfo deprecationInfo = definition.getDeprecationInfo();

        String message = deprecationInfo.getMessage();
        if (message != null)
        {
            problem = new DeprecatedAPIWithMessageProblem(site, message);
        }
        else
        {
            String name = definition.getBaseName();
            String since = deprecationInfo.getSince();
            String replacement = deprecationInfo.getReplacement();

            if (since == null && replacement == null)
                problem = new DeprecatedAPIProblem(site, name);
            
            else if (since != null && replacement == null)
                problem = new DeprecatedAPIWithSinceProblem(site, name, since);
            
            else if (since == null && replacement != null)
                problem = new DeprecatedAPIWithReplacementProblem(site, name, replacement);
            
            else if (since != null && replacement != null)
                problem = new DeprecatedAPIWithSinceAndReplacementProblem(site, name, since, replacement);
        }
        
        return problem;
    }

    /**
     *  Locate a FunctionDefinition that encloses the given i-node.
     *  @param iNode - the i-node of interest.
     *  @return the nearest enclosing function definition, or null.
     */
    public static FunctionDefinition getFunctionDefinition(IASNode iNode)
    {
        FunctionNode func_node;
        
        if ( iNode instanceof FunctionNode )
            func_node = (FunctionNode) iNode;
        else
            func_node = (FunctionNode) iNode.getAncestorOfType(FunctionNode.class);

        if ( func_node != null )
            return func_node.getDefinition();
        else
            return null;
    }

    /**
     *  Does the subject function require a non-void return value?
     *  @param iNode - an AST node in (or at the border of) the function.
     *  @return true if the function's definition is known, the definition's
     *    return type is known (and the function is not a constructor),
     *    and the return type is not void or *
     */
    public static boolean functionMustReturnValue(IASNode iNode, ICompilerProject project)
    {
        FunctionDefinition func_def = SemanticUtils.getFunctionDefinition(iNode);

        if ( func_def != null )
        {
            IDefinition return_type = func_def.resolveReturnType(project);
            //  The function must return a value unless its return type is void or *,
            //  or if it's a constructor (its definition lies).
            return !( 
                return_type == null ||
                return_type.equals(ClassDefinition.getVoidClassDefinition()) ||
                return_type.equals(ClassDefinition.getAnyTypeClassDefinition()) ||
                func_def.isConstructor()
            );
        }
        else
        {
            //  Nothing known about this function.
            return false;
        }
    }

    /**
     * Calculate the type of the RHS of an assignment.  Works with either BinaryOperatorAssignmentNodes
     * or VariableNodes
     * @param project   the active project
     * @param iNode     the node representing the assignment
     * @return          the type of the RHS, or null if one couldn't be determined.
     */
    public static ITypeDefinition resolveRHSTypeOfAssignment (ICompilerProject project, IASNode iNode)
    {
        ITypeDefinition srcType = null;
        if( iNode instanceof BinaryOperatorAssignmentNode)
        {
            if ( iNode.getChildCount() > 1 && iNode.getChild(1) instanceof IExpressionNode)
            {
                IExpressionNode rhs = (IExpressionNode)iNode.getChild(1);
                srcType = rhs.resolveType(project);
            }
        }
        else if(iNode instanceof IVariableNode)
        {
            IExpressionNode rhs = ((IVariableNode)iNode).getAssignedValueNode();
            srcType = rhs != null ? rhs.resolveType(project) : null;
        }
        return srcType;
    }

    /**
     * Helper method to get the file path from an IASNode
     * @param iNode the node you want the file path for
     * @return A String representing the file path for the file the node came from
     */
    public static String getFileName(IASNode iNode)
    {
        String file_name = iNode.getSourcePath();

        if ( file_name == null )
        {
            //  Fall back on the file specification.
            //  This may also be null (or assert if it's feeling moody),
            //  in which case the file name remains null and file/line
            //  processing noops.
            try
            {
                IFileSpecification fs = iNode.getFileSpecification();
                if ( fs != null)
                    file_name = fs.getPath();
            }
            catch (Exception e)
            {
                //  No file specification available, probably
                //  because this node is some kind of syntho.
            }
        }
        return file_name;
    }
}
