/*
 *
 *  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.royale.compiler.internal.semantics;

import static org.apache.royale.abc.ABCConstants.OP_findproperty;
import static org.apache.royale.abc.ABCConstants.OP_findpropstrict;
import static org.apache.royale.abc.ABCConstants.OP_getlex;
import static org.apache.royale.abc.ABCConstants.OP_getouterscope;
import static org.apache.royale.abc.ABCConstants.OP_getscopeobject;
import static org.apache.royale.abc.ABCConstants.OP_newactivation;
import static org.apache.royale.abc.ABCConstants.OP_newcatch;
import static org.apache.royale.abc.ABCConstants.OP_newclass;
import static org.apache.royale.abc.ABCConstants.OP_newfunction;
import static org.apache.royale.abc.ABCConstants.OP_popscope;
import static org.apache.royale.abc.ABCConstants.OP_pushscope;
import static org.apache.royale.abc.ABCConstants.OP_pushwith;
import static org.apache.royale.abc.ABCConstants.OP_returnvalue;
import static org.apache.royale.abc.ABCConstants.OP_returnvoid;

import java.util.ArrayList;
import java.util.List;
import java.util.Vector;
import java.util.concurrent.atomic.AtomicInteger;

import org.apache.royale.abc.ABCConstants;
import org.apache.royale.abc.graph.IBasicBlock;
import org.apache.royale.abc.instructionlist.InstructionList;
import org.apache.royale.abc.semantics.ECMASupport;
import org.apache.royale.abc.semantics.Instruction;
import org.apache.royale.abc.semantics.MethodInfo;
import org.apache.royale.abc.semantics.MethodBodyInfo;
import org.apache.royale.abc.semantics.Name;
import org.apache.royale.abc.semantics.PooledValue;
import org.apache.royale.compiler.common.ISourceLocation;
import org.apache.royale.compiler.common.ModifiersSet;
import org.apache.royale.compiler.common.ASModifier;
import org.apache.royale.compiler.constants.IASKeywordConstants;
import org.apache.royale.compiler.constants.IASLanguageConstants;
import org.apache.royale.compiler.constants.IASLanguageConstants.BuiltinType;
import org.apache.royale.compiler.definitions.IAccessorDefinition;
import org.apache.royale.compiler.definitions.IClassDefinition;
import org.apache.royale.compiler.definitions.IConstantDefinition;
import org.apache.royale.compiler.definitions.IDefinition;
import org.apache.royale.compiler.definitions.IFunctionDefinition;
import org.apache.royale.compiler.definitions.IGetterDefinition;
import org.apache.royale.compiler.definitions.IInterfaceDefinition;
import org.apache.royale.compiler.definitions.INamespaceDefinition;
import org.apache.royale.compiler.definitions.ISetterDefinition;
import org.apache.royale.compiler.definitions.ITypeDefinition;
import org.apache.royale.compiler.definitions.IVariableDefinition;
import org.apache.royale.compiler.definitions.references.INamespaceReference;
import org.apache.royale.compiler.internal.as.codegen.*;
import org.apache.royale.compiler.internal.definitions.AmbiguousDefinition;
import org.apache.royale.compiler.internal.definitions.VariableDefinition;
import org.apache.royale.compiler.internal.scopes.ASProjectScope;
import org.apache.royale.compiler.problems.*;
import org.apache.royale.compiler.projects.ICompilerProject;
import org.apache.royale.compiler.scopes.IASScope;
import org.apache.royale.compiler.scopes.IDefinitionSet;
import org.apache.royale.compiler.tree.ASTNodeID;
import org.apache.royale.compiler.tree.as.IASNode;
import org.apache.royale.compiler.tree.as.IBinaryOperatorNode;
import org.apache.royale.compiler.tree.as.ICompoundAssignmentNode;
import org.apache.royale.compiler.tree.as.IContainerNode;
import org.apache.royale.compiler.tree.as.IExpressionNode;
import org.apache.royale.compiler.tree.as.IFunctionCallNode;
import org.apache.royale.compiler.tree.as.IFunctionNode;
import org.apache.royale.compiler.tree.as.IIdentifierNode;
import org.apache.royale.compiler.tree.as.IImportNode;
import org.apache.royale.compiler.tree.as.IMemberAccessExpressionNode;
import org.apache.royale.compiler.tree.as.INamespaceDecorationNode;
import org.apache.royale.compiler.tree.as.INumericLiteralNode;
import org.apache.royale.compiler.tree.as.IParameterNode;
import org.apache.royale.compiler.tree.as.IReturnNode;
import org.apache.royale.compiler.tree.as.IScopedNode;
import org.apache.royale.compiler.tree.as.ITypedExpressionNode;
import org.apache.royale.compiler.tree.as.IUnaryOperatorNode;
import org.apache.royale.compiler.tree.as.IVariableNode;
import org.apache.royale.compiler.internal.definitions.AccessorDefinition;
import org.apache.royale.compiler.internal.definitions.ClassDefinition;
import org.apache.royale.compiler.internal.definitions.ClassTraitsDefinition;
import org.apache.royale.compiler.internal.definitions.ConstantDefinition;
import org.apache.royale.compiler.internal.definitions.DefinitionBase;
import org.apache.royale.compiler.internal.definitions.FunctionDefinition;
import org.apache.royale.compiler.internal.definitions.GetterDefinition;
import org.apache.royale.compiler.internal.definitions.InterfaceDefinition;
import org.apache.royale.compiler.internal.definitions.NamespaceDefinition;
import org.apache.royale.compiler.internal.definitions.ParameterDefinition;
import org.apache.royale.compiler.internal.definitions.SetterDefinition;
import org.apache.royale.compiler.internal.definitions.TypeDefinitionBase;
import org.apache.royale.compiler.internal.scopes.ASScope;
import org.apache.royale.compiler.internal.semantics.SemanticUtils.MultiDefinitionType;
import org.apache.royale.compiler.internal.tree.as.BaseDefinitionNode;
import org.apache.royale.compiler.internal.tree.as.BinaryOperatorLogicalAndNode;
import org.apache.royale.compiler.internal.tree.as.BinaryOperatorLogicalOrNode;
import org.apache.royale.compiler.internal.tree.as.ClassNode;
import org.apache.royale.compiler.internal.tree.as.ExpressionNodeBase;
import org.apache.royale.compiler.internal.tree.as.FunctionCallNode;
import org.apache.royale.compiler.internal.tree.as.FunctionNode;
import org.apache.royale.compiler.internal.tree.as.IdentifierNode;
import org.apache.royale.compiler.internal.tree.as.LanguageIdentifierNode;
import org.apache.royale.compiler.internal.tree.as.LiteralNode;
import org.apache.royale.compiler.internal.tree.as.MemberAccessExpressionNode;
import org.apache.royale.compiler.internal.tree.as.ModifierNode;
import org.apache.royale.compiler.internal.tree.as.ModifiersContainerNode;
import org.apache.royale.compiler.internal.tree.as.NamespaceAccessExpressionNode;
import org.apache.royale.compiler.internal.tree.as.NamespaceNode;
import org.apache.royale.compiler.internal.tree.as.NodeBase;
import org.apache.royale.compiler.internal.tree.as.NumericLiteralNode;
import org.apache.royale.compiler.internal.tree.as.PackageNode;
import org.apache.royale.compiler.internal.tree.as.ParameterNode;
import org.apache.royale.compiler.internal.tree.as.ScopedBlockNode;
import org.apache.royale.compiler.internal.tree.as.TernaryOperatorNode;
import org.apache.royale.compiler.internal.tree.as.VariableNode;
import org.apache.royale.compiler.internal.tree.as.VectorLiteralNode;
import org.apache.royale.compiler.internal.tree.mxml.MXMLDocumentNode;

/**
 *  The MethodBodySemanticChecker contains the logic that checks method body semantics.
 */
public class MethodBodySemanticChecker
{
    /**
     *  The current LexicalScope for this compilation.
     */
    private LexicalScope currentScope;

    /**
     *  The current ICompilerProject for this compilation.
     */
    private final ICompilerProject project;

    /**
     *  Semantic utilities, which know how to interface with name resolution
     */
    private final SemanticUtils utils;


    /**
     *  Current state of diagnostics regarding "super" 
     */
    private enum SuperState { Invalid, Initial, Armed };

    /**
     *  Current state of diagnostics regarding "super" 
     */
    private SuperState superState = SuperState.Invalid;

    /**
     *  Construct a new MethodBodySemanticChecker from the current lexical scope.
     */
    public MethodBodySemanticChecker(LexicalScope current_scope)
    {
        this.currentScope = current_scope;
        this.project = currentScope.getProject();
        this.utils = new SemanticUtils(this.project);
    }

    /**
     * Do a semantic analysis of all the arguments of a function
     *
     * @param funcNode is the function to be analyzed
     */
    public void checkFunctionDecl(IFunctionNode funcNode )
    {
        IParameterNode[] paramNodes = funcNode.getParameterNodes();
        for (IParameterNode paramNode : paramNodes)
        {
            IDefinition paramDef = paramNode.getDefinition();

            ITypeDefinition paramTypeDef = ((IVariableDefinition)paramDef).resolveType(project);
            if (!SemanticUtils.isType(paramTypeDef) )
            {
                IExpressionNode typeExpression = paramNode.getVariableTypeNode();
                String typeName =  paramDef.getTypeAsDisplayString();
                addTypeProblem(typeExpression, paramTypeDef, typeName, true);
            }
        }
    }

    /**
     * Semantic analysis of a function declared inside another function.  This is only for function declarations,
     * and not function expressions.
     * @param funcNode  The node of the nested function
     */
    public void checkNestedFunctionDecl(IFunctionNode funcNode)
    {
        IFunctionDefinition funcDef = funcNode.getDefinition();
        List<IDefinition> defs = SemanticUtils.findPotentialFunctionConflicts(currentScope.getProject(), funcDef);

        // Check for potential dups - functions can be redeclared and won't be ambiguous, but in strict mode
        // we want to issue an error.
        // Don't need to worry about getter/setter pairs as you can't declare nested getter/setters
        if( defs.size() > 1 )
        {
            ICompilerProblem problem = new DuplicateFunctionDefinitionProblem(funcNode, funcDef.getBaseName());
            this.currentScope.addProblem(problem);
        }
    }

    /**
     *  Convenience method to add a problem.
     *  @param problem - the problem to add.
     */
    private void addProblem(ICompilerProblem problem)
    {
        //  Some of the "figure out this error scenario"
        //  methods pass in null to mean "ignore."
        if ( problem != null )
            this.currentScope.addProblem(problem);
    }

    /**
     *  Perform semantic checks on an assignment.
     */
    public void checkAssignment(IASNode iNode, Binding binding)
    {
        checkLValue(iNode, binding);

        if ( SemanticUtils.isUnprotectedAssignmentInConditional(iNode) )
            addProblem(new AssignmentInConditionalProblem(SemanticUtils.getNthChild(iNode, 0)));

        //  Check the assignment's type logic and values.
        ITypeDefinition leftType = null;
        if ( binding.getDefinition() != null )
        {
            IDefinition leftDef = binding.getDefinition();
            leftType = binding.getDefinition().resolveType(project);
            
            IASNode rightNode = SemanticUtils.getNthChild(iNode, 1);
       
            checkImplicitConversion(rightNode, leftType, null);
            checkAssignmentValue(leftDef, rightNode);
        }
    }
    
    /**
     * Checks that the value (RHS) is appropriate, given the type of the LHS
     * @param leftDefinition is the definition of the variable on the LHS
     * @param rightNode is the tree node for the RHS of the assignment
     */
    public void checkAssignmentValue( IDefinition leftDefinition, IASNode rightNode)
    {
        ITypeDefinition leftType = leftDefinition.resolveType(project);
        
        if (rightNode instanceof IExpressionNode)
        {
            IDefinition rightType = ((IExpressionNode)rightNode).resolveType(project);
            final boolean leftIsNumericOrBoolean = SemanticUtils.isNumericTypeOrBoolean(leftType, project);   
            final boolean rightIsNull =  SemanticUtils.isBuiltin(rightType, BuiltinType.NULL, project);
            
            if (leftIsNumericOrBoolean && rightIsNull)
            {
                final boolean leftIsConstant = leftDefinition instanceof IConstantDefinition;
                addProblem(leftIsConstant ?
                        new IncompatibleDefaultValueOfTypeNullProblem(rightNode, leftType.getBaseName()) :
                        new NullUsedWhereOtherExpectedProblem(rightNode, leftType.getBaseName()));
            }
        }
    }
    
    /**
     * Perform semantic checks on an initialization
     */
    public void checkInitialization(IASNode iNode, Binding binding)
    {
        //  Check the assignment's type logic.
        if ( binding.getDefinition() != null )
            checkImplicitConversion(SemanticUtils.getNthChild(iNode, 2), binding.getDefinition().resolveType(project), null);
    }
    
    /**
     *  Perform semantic checks on an x[i] = rvalue assignment expression.
     */
    public void checkAssignToBracketExpr(IASNode iNode)
    {
    }

    /**
     *  Check a binary operator.
     *  @param iNode - the operator node.
     *  @param opcode - the opcode.
     */
    public void checkBinaryOperator(IASNode iNode, int opcode)
    {
        final IASNode left = ((IBinaryOperatorNode)iNode).getLeftOperandNode();
        final IASNode right = ((IBinaryOperatorNode)iNode).getRightOperandNode();
        checkBinaryOperator(iNode, left, right, opcode);
    }

    /**
     *  Check a (possibly implicit) binary operator.
     *  @param root - the operator node.
     *  @param left - the left-hand operand.
     *  @param right - the right-hand operand.
     *  @param opcode - the opcode.
     */
    public void checkBinaryOperator(IASNode root, IASNode left, IASNode right, final int opcode)
    {
        switch(opcode)
        {
            case ABCConstants.OP_multiply:
            case ABCConstants.OP_divide:
            case ABCConstants.OP_modulo:
            case ABCConstants.OP_subtract:
            case ABCConstants.OP_lshift:
            case ABCConstants.OP_rshift:
            case ABCConstants.OP_urshift:
            case ABCConstants.OP_bitand:
            case ABCConstants.OP_bitor:
            case ABCConstants.OP_bitxor:
                checkImplicitConversion(left, utils.numberType(), null);
                checkImplicitConversion(right, utils.numberType(), null);
                break;

            case ABCConstants.OP_istypelate:
            case ABCConstants.OP_astypelate:
                checkTypeCheckImplicitConversion(right);
                break;
            case ABCConstants.OP_equals:
            case ABCConstants.OP_strictequals:
            case ABCConstants.OP_lessthan:
            case ABCConstants.OP_lessequals:
            case ABCConstants.OP_greaterthan:
            case ABCConstants.OP_greaterequals:

                if ((left instanceof IExpressionNode) && (right instanceof IExpressionNode))
                {
                    checkComparison((IExpressionNode)left, (IExpressionNode)right);
                }
                break;
            case ABCConstants.OP_instanceof:
                addProblem(new InstanceOfProblem(root));
                break;
        }
    }

    /**
     *  Check an implicit conversion.
     *  @param iNode - the expression being checked.
     *  @param expected_type - the type to convert to.
     */
    
    public void checkImplicitConversion(IASNode iNode, IDefinition expected_type, FunctionDefinition func)
    {
        if (iNode instanceof BinaryOperatorLogicalOrNode ||
             iNode instanceof BinaryOperatorLogicalAndNode ||
             iNode instanceof TernaryOperatorNode)
        {
            // For these logical nodes, just check both sides with a recursive call.
            // Note that we need to recurse, because this may be a tree of binary logical nodes
            final IExpressionNode leftOp = ((IBinaryOperatorNode)iNode).getLeftOperandNode();
            checkImplicitConversion(leftOp, expected_type, null);
            final IExpressionNode rightOp = ((IBinaryOperatorNode)iNode).getRightOperandNode();
            checkImplicitConversion(rightOp, expected_type, null);
        }

        else if (iNode instanceof ExpressionNodeBase)
        {
            checkImplicitConversion(iNode, ((ExpressionNodeBase)iNode).resolveType(project), expected_type, func);
        }
    }

    /**
     * Check an implicit conversion in an 'is' or 'as' binop
     * @param iNode - the expression being checked.
     */
    public void checkTypeCheckImplicitConversion(IASNode iNode)
    {
        if (!(iNode instanceof ExpressionNodeBase))
            return;

        final IDefinition actual_type = ((ExpressionNodeBase)iNode).resolveType(project);
        // expected type is always of type CLASS;
        final IDefinition expected_type = utils.getBuiltinType(BuiltinType.CLASS);

        if (!SemanticUtils.isValidTypeConversion(expected_type, actual_type, project, currentScope.getInInvisibleCompilationUnit()))
        {
            addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
        }
        else
        {
            SpecialValue value = getSpecialValue((IExpressionNode)iNode);
            if (value == SpecialValue.UNDEFINED) // test for undefined
            {
                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASLanguageConstants.UNDEFINED, expected_type.getQualifiedName()));                
            }
            else if (iNode instanceof LiteralNode && IASKeywordConstants.NULL.equals(((LiteralNode)iNode).getValue())) // test for null
            {
                addProblem(new ImplicitTypeCheckCoercionToUnrelatedTypeProblem(iNode, IASKeywordConstants.NULL, expected_type.getQualifiedName()));
            }
        }
    }

    enum SpecialValue { NONE, NAN, UNDEFINED }
    SpecialValue getSpecialValue(IExpressionNode node)
    {
        SpecialValue ret = SpecialValue.NONE;
        IDefinition def = node.resolve(project);
        
        if (def instanceof IConstantDefinition)
        {
            // it's easy to find the word "undefined", just compare to the
            // singleton definition
            if (def == project.getUndefinedValue())
            {
                ret = SpecialValue.UNDEFINED;
            }
            else
            {
                Object initialValue = ((ConstantDefinition) def).resolveValueFrom(project, (NodeBase)node);
                if (initialValue != null)
                {
                    if (initialValue instanceof Double)
                    {
                        Double d = (Double)initialValue;
                        if (ECMASupport.isNan(d))
                            ret = SpecialValue.NAN;
                    }
                }
            }
        }
        return ret;
    }
    
    /**
     * determine if it is reasonable to compare two operands of perhaps different types.
     * Create a CompilerProblem if not.
     * 
     */
    private void checkComparison(IExpressionNode leftNode, IExpressionNode rightNode)
    {
        SpecialValue leftValue = getSpecialValue(leftNode);
        SpecialValue rightValue = getSpecialValue(rightNode);
        
        if (leftValue == SpecialValue.NAN || rightValue == SpecialValue.NAN)
        {
           addProblem( new IllogicalComparionWithNaNProblem(leftNode));
        }
        
       
        
        IDefinition left_type = leftNode.resolveType(project);
        IDefinition right_type = rightNode.resolveType(project);
        
        if (left_type==null || right_type==null)
        {
            return; // if we can't resolve both side, some other check will catch it.
        }
        
       
        final IDefinition anyType = project.getBuiltinType(BuiltinType.ANY_TYPE);
        if (rightValue == SpecialValue.UNDEFINED && !left_type.equals(anyType))
        {
           addProblem(new IllogicalComparisonWithUndefinedProblem(leftNode));
        }
        
        if (leftValue == SpecialValue.UNDEFINED && !right_type.equals(anyType))
        {
           addProblem(new IllogicalComparisonWithUndefinedProblem(rightNode));
        }
        // Harmless pre-optimizition. If both types are the same they must be comparable.
        // (but only after we have checked special value cases above.
        if (left_type.equals(right_type))
        {
            return;
        }
        
        final boolean leftIsNumeric = SemanticUtils.isNumericType(left_type, project);
        final boolean rightIsNumeric = SemanticUtils.isNumericType(right_type, project);
        final boolean leftIsNull =  SemanticUtils.isBuiltin(left_type, BuiltinType.NULL, project);
        final boolean rightIsNull =  SemanticUtils.isBuiltin(right_type, BuiltinType.NULL, project);
        
        // Interfaces can be compared against any Object
        if ((left_type instanceof IInterfaceDefinition && !rightIsNumeric) ||
                ( right_type instanceof IInterfaceDefinition && !leftIsNumeric))
        {
            return;
        }
        
         
        boolean isBad = false;
        
        // Numeric types can never be null
        if ((leftIsNumeric&&rightIsNull) || (rightIsNumeric&&leftIsNull))
        {
            isBad = true;
        }
        
        // If all the speical cases have passed, the try isValidTypeConversion in both directions.
        if (!isBad)
        {
            if (SemanticUtils.isValidTypeConversion(left_type, right_type, project, this.currentScope.getInInvisibleCompilationUnit()))
                return;
            if (SemanticUtils.isValidTypeConversion(right_type, left_type, project, this.currentScope.getInInvisibleCompilationUnit()))
                return;
        }
        
        addProblem(new ComparisonBetweenUnrelatedTypesProblem(leftNode, left_type.getBaseName(), right_type.getBaseName()));
    }

    /**
     *  Check a compound assignment.
     *  @param iNode - the node at the root of the assignment subtree.
     *  @param lvalue - the resolved lvalue (which is also an implicit rvalue).
     *  @param opcode - the opcode of the implied binary operator.
     */
    public void checkCompoundAssignment(IASNode iNode, Binding lvalue, final int opcode)
    {
        ICompoundAssignmentNode compoundNode = (ICompoundAssignmentNode)iNode;
        IBinaryOperatorNode  binop = (IBinaryOperatorNode)iNode;

        checkLValue(iNode, lvalue);

        if ( SemanticUtils.isUnprotectedAssignmentInConditional(iNode) )
            addProblem(new AssignmentInConditionalProblem(binop.getLeftOperandNode()));

        //  Check the implicit binary operator.
        checkBinaryOperator(iNode, binop.getLeftOperandNode(), binop.getRightOperandNode(), opcode);

        //  Check the assignment's types are compatible.
        if ( lvalue.getDefinition() != null )
        {
            //  Do own checks, then call common logic to emit diagnostics.
            ITypeDefinition lhsType = lvalue.getDefinition().resolveType(this.project);
            ITypeDefinition compoundType = compoundNode.resolveTypeOfRValue(this.project);

            if ( ! SemanticUtils.isValidImplicitOpAssignment(lhsType, compoundType, opcode, this.project, this.currentScope.getInInvisibleCompilationUnit()) )
            {
                checkImplicitConversion(binop.getRightOperandNode(), lhsType, null);
            }
            else if ( opcode == ABCConstants.OP_iffalse || opcode == ABCConstants.OP_iftrue )
            {
                //  check the RHS type of a logical operation on its own;
                //  this is rather strange behavior, but it replicates ASC's logic.
                checkImplicitConversion(binop.getRightOperandNode(), lhsType, null);
            }
        }
    }

    /**
     *  Check an implicit conversion.
     *  @param actual_type   - the type of the expression being checked.
     *  @param expected_type - the type to convert to.
     */
    private void checkImplicitConversion(IASNode iNode, IDefinition actual_type, IDefinition expected_type, FunctionDefinition func)
    {
        if ( !SemanticUtils.isValidTypeConversion(expected_type, actual_type, this.project, this.currentScope.getInInvisibleCompilationUnit()) )
        {
            if (project.isValidTypeConversion(iNode, actual_type, expected_type, func))
                return;
            
            // If we're assigning to a class, this will generate an "Illegal assignment to class" error,
            // so we don't need another error for implicit coercion
            if( !(expected_type instanceof ClassTraitsDefinition) )
            {
                if ( utils.isInstanceOf(expected_type, actual_type) )
                {
                    addProblem(new ImplicitCoercionToSubtypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
                }
                else
                {
                    addProblem(new ImplicitCoercionToUnrelatedTypeProblem(iNode, actual_type.getQualifiedName(), expected_type.getQualifiedName()));
                }
            }
        }
    }

    /**
     * Check if we are allowed to declare a bindable variable at this location.
     */
    public void checkBindableVariableDeclaration(IASNode iNode, IDefinition d)
    {

        assert d != null;

        if( !(d.getParent() instanceof IClassDefinition))
        {
            this.currentScope.addProblem(new LocalBindablePropertyProblem(iNode));
        }
    }
    
    /**
     * Check a constant value used in a non-initializer context.
     */
    public void checkConstantValue(IASNode iNode)
    {
        // Check for a node resolving to a deprecated constant definition.
        if (iNode instanceof IExpressionNode)
        {
            IDefinition definition = ((IExpressionNode)iNode).resolve(project);
            checkDeprecated(iNode, definition);
        }
    }

    /**
     *  Check that a synthetic super() call is allowed by the class' superclass.
     */
    public void checkDefaultSuperCall(IASNode iNode)
    {
        //  This occurs in some error cases.
        if ( iNode == null )
            return;

        ClassNode enclosing_class = (ClassNode) iNode.getAncestorOfType(ClassNode.class);

        if ( enclosing_class != null )
        {
            IClassDefinition super_def = enclosing_class.getDefinition().resolveBaseClass(project);
            if (super_def != null)
            {
                IFunctionDefinition ctor = super_def.getConstructor();

                if (ctor instanceof FunctionDefinition)
                {
                    FunctionDefinition func = (FunctionDefinition)ctor;
                    if (func.getParameters() != null && func.getParameters().length != 0)
                    {
                        ParameterDefinition first_param = func.getParameters()[0];

                        if ( !first_param.hasDefaultValue() && ! first_param.isRest() )
                        {
                            if ( enclosing_class.getDefinition().getConstructor().isImplicit()) {
                                //in this case the Error reporting site should point to the class node,
                                //because there is no 'real' constructor node to reference in the source code
                                addProblem(new NoDefaultConstructorInBaseClassProblem(enclosing_class, super_def.getBaseName()));
                            }
                            else addProblem(new NoDefaultConstructorInBaseClassProblem(iNode, super_def.getBaseName()));
                        }
                    }
                }
            }
        }
    }
    
    /**
     *  Perform semantic checks on a delete expression.
     */
    public void checkDeleteExpr(IASNode iNode, Binding binding)
    {
        IDefinition def = binding.getDefinition();

        if (def != null)
        {
            // If we can resolve to a definition, check to be sure we are not trying
            // to delete a non-dynamic properly
            if (!(utils.hasDynamicBase(binding) || SemanticUtils.isInWith(iNode)))
                addProblem(new AttemptToDeleteFixedPropertyProblem(iNode, binding.getName()));
        }
        else if (SemanticUtils.hasBaseNode(binding) && !utils.hasDynamicBase(binding))
        {
            // If we are trying to delete a member of a class, but the member doesn't exists,
            // The log the problem for that
            addProblem(new AccessUndefinedMemberProblem(
                    roundUpUsualSuspects(binding, iNode),
                    binding.getName().getBaseName(),
                    utils.getTypeOfBase(binding.getNode())));
        }
        else
        {
            // This checked knows about packages and undefined properties,
            // could use the more specific  
            //     addProblem(accessUndefinedProperty(binding, roundUpUsualSuspects(binding, iNode)));
            checkLValue(iNode, binding);
        }
    }

    /**
     *  Check a super() or super(a,b,c) call.
     */
    public void checkExplicitSuperCall(IASNode iNode, Vector<? extends Object> args)
    {
        LanguageIdentifierNode super_node = (LanguageIdentifierNode)((IFunctionCallNode)iNode).getNameNode();

        //  Check that this super() call is in a constructor.
        if ( !SemanticUtils.isInConstructor(iNode) )
        {
            addProblem(new InvalidSuperStatementProblem(iNode));
        }
        else
        {
            //  Check that this super call does not follow a construct
            //  that invalidates it.
            if ( this.superState != SuperState.Initial )
                addProblem(new ExtraneousSuperStatementProblem(iNode));
            else
                this.superState = SuperState.Armed;
        }

        //  Check parameters if possible.
        ClassDefinition super_def = (ClassDefinition) super_node.resolveType(project);

        if (super_def != null)
        {
            IFunctionDefinition ctor = super_def.getConstructor();

            if (ctor instanceof FunctionDefinition)
            {
                checkFormalsVsActuals(super_node, (FunctionDefinition)ctor, args);
            }
        }
    }

    /**
     *  Check that formal and actual parameters correspond and are compatible.
     */
    private void checkFormalsVsActuals(IASNode iNode, FunctionDefinition func, Vector<? extends Object> actuals)
    {

        //  If the call is through a function variable then we don't know much about it.
        //  If we get a setter function assume a getter is what was meant since calling a setter
        //  directly is not legal and resolving the name for a getter/setter could
        //  return either. Code generation does the right thing so changing this check
        //  to just return for setters as well.
        if ( func instanceof GetterDefinition || func instanceof SetterDefinition)
            return;

        //  Check the formal parameter definitions, and ensure we have
        //  a corresponding number of actual parameters.
        ParameterDefinition[] formals = func.getParameters();

        if ( formals == null )
            return;
        
        boolean last_is_rest   = formals.length > 0 && formals[formals.length - 1].isRest();

        int required_count = 0;

        if ( actuals.size() > formals.length && !last_is_rest )
        {
        	if (project.isParameterCountMismatchAllowed(func, formals.length, actuals.size()))
        		return;
            addProblem(new TooManyFunctionParametersProblem(iNode, formals.length));
        }

        //  Compute the number of required parameters.
        for ( int i = 0; i < formals.length; i++ )
        {
            if ( formals[i].hasDefaultValue() || formals[i].isRest() )
                break;

            required_count++;
        }

        if ( actuals.size() < required_count )
        {
            addProblem(new TooFewFunctionParametersProblem(iNode, required_count));
        }

        //  Check that the actuals are compatible with the formals.
        IASNode actuals_container = null;
        if( iNode instanceof FunctionCallNode )
            actuals_container = ((FunctionCallNode)iNode).getArgumentsNode();

        if ( actuals_container != null )
        {
            for ( int i = 0; i < actuals_container.getChildCount() && i < formals.length; i++ )
            {
                if ( !formals[i].isRest() )
                    checkImplicitConversion( actuals_container.getChild(i), formals[i].resolveType(project), func );
            }
        }
    }

    /**
     *  Check a function body's overall characteristics.
     */
    public void checkFunctionBody(IASNode iNode)
    {
        if ( iNode instanceof FunctionNode )
        {
            FunctionNode func = (FunctionNode)iNode;

            if (SemanticUtils.isFunctionClosure(func))
            {
                for (IASNode thisNode : findThisIdentifierNodes(func))
                {
                    addProblem(new ThisUsedInClosureProblem(thisNode));
                }
            }

            IDefinition def = func.getDefinition();

            if ( project.getAllowAbstractClasses()
                    && def.isAbstract()
                    && SemanticUtils.canBeAbstract(iNode, currentScope.getProject()))
            {
                if ( func.hasBody() )
                {
                    addProblem(new AbstractMethodWithBodyProblem(SemanticUtils.getFunctionProblemNode(func)));
                }
            }
            else if ( !( def.hasModifier(ASModifier.NATIVE ) || def.hasModifier(ASModifier.DYNAMIC) || func.isConstructor() ) )
            {
                if ( !func.hasBody() )
                {
                    addProblem(new FunctionWithoutBodyProblem(SemanticUtils.getFunctionProblemNode(func)));
                }
            }
        }
    }

    private static List<IASNode> findThisIdentifierNodes(IASNode iNode)
    {
        List<IASNode> result = new ArrayList<IASNode>();
        for(int i = 0, count = iNode.getChildCount(); i < count; i++)
        {
            IASNode child = iNode.getChild(i);
            if(SemanticUtils.isThisKeyword(child))
            {
                result.add(child);
            }
            else if(!child.isTerminal() && !(child instanceof IFunctionNode))
            {
                result.addAll(findThisIdentifierNodes(child));
            }
        }
        return result;
    }

    public void checkNativeMethod(IASNode iNode)
    {
        if( iNode instanceof FunctionNode )
        {
            if ( ((FunctionNode)iNode).hasBody() )
            {
                addProblem(new NativeMethodWithBodyProblem(iNode));
            }
        }
    }

    private IInterfaceDefinition iEventDispatcher(){
        String iEventDispatcherPackage = BindableHelper.NAME_IEVENT_DISPATCHER.getQualifiers().getSingleQualifier().getName();
        String iEventDispatcherName = BindableHelper.NAME_IEVENT_DISPATCHER.getBaseName();
        IDefinition iEventDispatcher =  ((ASProjectScope)(project.getScope())).findDefinitionByName(iEventDispatcherPackage + "." + iEventDispatcherName);
        if (iEventDispatcher instanceof IInterfaceDefinition) return (IInterfaceDefinition) iEventDispatcher;
        return null;
    }

    /**
     *  Check a function call.
     */
    public void checkFunctionCall(IASNode iNode, Binding method_binding, Vector<? extends Object>actuals)
    {
        //  Skip synthetic calls.
        if ( method_binding.getName() == null )
            return;

        //  Check for calls to attributes.
        if ( method_binding.getName().isAttributeName() )
        {
            addProblem(new AttributesAreNotCallableProblem(roundUpUsualSuspects(method_binding, iNode)));
        }

        IDefinition def = method_binding.getDefinition();
        if (def == null) {
            IDefinition defCheck = SemanticUtils.getDefinitionOfUnderlyingType(iNode,true, project);
            if (defCheck instanceof IClassDefinition) {
                //if we have the bindable IEventDispatcher implementation either at this level or via ancestry, then we should allow those IEventDispatcher methods
                boolean assumeBindableIEventDispatcher = false;
                IClassDefinition.IClassIterator classIterator = ((IClassDefinition) defCheck).classIterator(project, true);
                while (classIterator.hasNext())
                {
                    defCheck = classIterator.next();
                    if (((IClassDefinition)defCheck).needsEventDispatcher(project)) {
                        assumeBindableIEventDispatcher = true;
                        break;
                    }
                }
                if (assumeBindableIEventDispatcher) {
                    IInterfaceDefinition iEventDispatcher =  iEventDispatcher();
                    IDefinitionSet bindingMethodCheck = iEventDispatcher.getContainedScope().getLocalDefinitionSetByName( method_binding.getName().getBaseName());
                    if (bindingMethodCheck!=null && bindingMethodCheck.getSize() == 1) {
                        def = bindingMethodCheck.getDefinition(0);
                    }
                }
            }
        }

        if ( def == null && utils.definitionCanBeAnalyzed(method_binding) )
        {
            if ( utils.isInaccessible(iNode, method_binding) )
            {
            	if (!method_binding.getName().getBaseName().equals("toString"))
	                addProblem(new InaccessibleMethodReferenceProblem( 
	                    roundUpUsualSuspects(method_binding, iNode), 
	                    method_binding.getName().getBaseName(),
	                    utils.getTypeOfStem(iNode)
	                ));
            }
            else if ( SemanticUtils.hasExplicitStem(iNode) && utils.hasUnderlyingType(iNode) )
            {

                addProblem(new StrictUndefinedMethodProblem( 
                    roundUpUsualSuspects(method_binding, iNode), 
                    method_binding.getName().getBaseName(),
                    utils.getTypeOfStem(iNode)
                ));
            }
            else
            {
                addProblem(new CallUndefinedMethodProblem( 
                    roundUpUsualSuspects(method_binding, iNode), 
                    method_binding.getName().getBaseName()
                ));
            }
        }
        else if ( def instanceof AccessorDefinition )
        {
            AccessorDefinition accessorDef = (AccessorDefinition)def;
            IDefinition accessorType = accessorDef.resolveType(project);
            if (accessorType != null && // Null here means the ANY_TYPE
                    (accessorType.equals(project.getBuiltinType(BuiltinType.NUMBER)) ||
                    accessorType.equals(project.getBuiltinType(BuiltinType.BOOLEAN)) ||
                    accessorType.equals(project.getBuiltinType(BuiltinType.INT)) ||
                    accessorType.equals(project.getBuiltinType(BuiltinType.UINT)) ||
                    accessorType.equals(project.getBuiltinType(BuiltinType.STRING))))
            {
                addProblem(new CallNonFunctionProblem(iNode, method_binding.getName().getBaseName()));
            }
        }
        else if ( def instanceof FunctionDefinition )
        {
            FunctionDefinition func = (FunctionDefinition)def;
            checkFormalsVsActuals(iNode, func, actuals);
        }
        else if ( def instanceof VariableDefinition )
        {
            VariableDefinition varDef = (VariableDefinition)def;
            IDefinition varType = varDef.resolveType(project);
            if (varType != null && // Null here means the ANY_TYPE
                    (varType.equals(project.getBuiltinType(BuiltinType.NUMBER)) ||
                    varType.equals(project.getBuiltinType(BuiltinType.BOOLEAN)) ||
                    varType.equals(project.getBuiltinType(BuiltinType.INT)) ||
                    varType.equals(project.getBuiltinType(BuiltinType.UINT)) ||
                    varType.equals(project.getBuiltinType(BuiltinType.STRING))))
            {
                addProblem(new CallNonFunctionProblem(iNode, method_binding.getName().getBaseName()));
            }
        }
        else if ( def == project.getBuiltinType(BuiltinType.ARRAY) )
        {
            // Warn about calling Array as a function because developers
            // may not understand that this always creates a new array.
            // The warning is different when there is one argument
            // of type Array, Object, or *; in that case developers
            // may think they are downcasting.
            boolean downcast = false;
            if (actuals.size() == 1)
            {
                IExpressionNode argument = ((IFunctionCallNode)iNode).getArgumentNodes()[0];
                IDefinition argumentType = argument.resolveType(project);
                
                if (argumentType == null || // Null here means the ANY_TYPE
                    argumentType.equals(project.getBuiltinType(BuiltinType.ARRAY)) ||
                    argumentType.equals(project.getBuiltinType(BuiltinType.OBJECT)) ||
                    argumentType.equals(project.getBuiltinType(BuiltinType.ANY_TYPE)))
                {
                     downcast = true;
                }
            }
            if (downcast)
                addProblem(new ArrayDowncastProblem(iNode));
            else
                addProblem(new ArrayCastProblem(iNode));
        }
        else if (def != null &&
                 // If def is an AmbiguousDefinition,
                 // getQualifiedName() will throw an exception.
                 !AmbiguousDefinition.isAmbiguous(def) &&
                 def.getQualifiedName().equals(IASLanguageConstants.Date))
        {
            if (actuals.size() > 0)
                addProblem(new DateCastProblem(iNode));
        }
        else if ( def instanceof ITypeDefinition )
        {
            // We've already handled the special cases of Array(...) and Date(...)
            // For other cast-like calls, there should be one and only one parameter.
            switch ( actuals.size() )
            {
                case 0:
                {
                        addProblem(new TooFewFunctionParametersProblem(iNode, 1));
                    break;
                    }
                case 1:
                {
                    //  Correct number of parameters.
                        break;
                }
                default:
                {
                    addProblem(new TooManyFunctionParametersProblem(iNode, 1));
                    break;
            }
        }
        }
        checkReference(method_binding);
    }

    /**
     *  Check a function definition.
     *  @param iNode - the top-level definition node.
     *  @param def - the function's definition.
     */
    public void checkFunctionDefinition(IFunctionNode iNode, FunctionDefinition def )
    {
        SemanticUtils.checkReturnValueHasNoTypeDeclaration(this.currentScope, iNode, def);
        SemanticUtils.checkParametersHaveNoTypeDeclaration(this.currentScope, iNode, def);
        
        if (SemanticUtils.isInFunction(iNode))
        {
            if (iNode instanceof BaseDefinitionNode)
                checkForNamespaceInFunction((BaseDefinitionNode)iNode, currentScope);
        }
        ParameterDefinition[] formals = def.getParameters();

        if ( formals == null )
            return;

        boolean found_optional = false;

        for ( int i = 0; i < formals.length; i++ )
        {
            //  Check the structure of the formals; 
            //  required parameters, then optionals,
            //  then the rest parameter, if present.
            if ( formals[i].hasDefaultValue() )
            {
                found_optional = true;
                if( def instanceof ISetterDefinition )
                {
                    addProblem(new SetterCannotHaveOptionalProblem(formals[i].getNode()));
                }
            }
            else if ( formals[i].isRest() )
            {
                if ( i != formals.length -1 )
                    addProblem(new RestParameterMustBeLastProblem(formals[i].getNode()));
                // TODO: Add a check for kError_InvalidRestDecl once CMP-279 is fixed.
            }
            else
            {
                if ( found_optional )
                {
                    addProblem(new RequiredParameterAfterOptionalProblem(formals[i].getNode()));
                }
            }

        }

        //  Check the return type.
        TypeDefinitionBase return_type = (TypeDefinitionBase)def.resolveReturnType(project);
        if ( return_type == null )
        {
            //  Error already emitted.
        }
        // Setter return type can only be 'void' or '*'
        else if( def instanceof ISetterDefinition &&
                // Error says return type must be void, but ASC allows '*' as well
                (return_type != project.getBuiltinType(BuiltinType.VOID) &&
                 return_type != project.getBuiltinType(BuiltinType.ANY_TYPE)) )
        {
            addProblem(new BadSetterReturnTypeProblem(iNode.getReturnTypeNode()));
        }

        if( def instanceof IAccessorDefinition )
        {
            IAccessorDefinition accessorDef = (IAccessorDefinition)def;
            ITypeDefinition thisType = accessorDef.resolveType(project);
            IAccessorDefinition other = null;
            if( (other = accessorDef.resolveCorrespondingAccessor(project)) != null)
            {
                ITypeDefinition otherType = other.resolveType(project);
                
                IDefinition anyType = project.getBuiltinType(BuiltinType.ANY_TYPE);

                if( otherType != thisType
                        // Don't complain if one of the types is '*'
                        && otherType != anyType && thisType != anyType )
                {
                    addProblem(new AccessorTypesMustMatchProblem(getAccessorTypeNode(iNode)));
                }
            }
            if( def instanceof IGetterDefinition )
            {
                if (formals.length > 0 )
                {
                    addProblem(new GetterCannotHaveParametersProblem(formals[0].getNode()));
                }
                
                if (SemanticUtils.isBuiltin(thisType, BuiltinType.VOID, project))
                {
                    addProblem( new GetterMustNotBeVoidProblem(iNode.getReturnTypeNode()));
                }
            }
       
            if( def instanceof ISetterDefinition )
            {
                if( formals.length != 1 )
                {
                    addProblem(new SetterMustHaveOneParameterProblem(iNode.getNameExpressionNode()));
                }
            }
        }

        checkNamespaceOfDefinition(iNode, def, project);
    }

    /**
     * Helper to get the node to report a problem with the "type" of a getter/setter.  Will return the
     * return type node for a setter, or the first parameter node for a getter, or the name node of the
     * accessor if the return type or parameter does not exist
     */
    private IASNode getAccessorTypeNode(IFunctionNode iNode)
    {
        IASNode result = iNode.getNameExpressionNode();
        if( iNode.isSetter() )
        {
            IExpressionNode returnType = iNode.getReturnTypeNode();
            if( returnType != null )
                result = returnType;
        }
        else if( iNode.isGetter() )
        {
            IParameterNode[] params = iNode.getParameterNodes();
            if( params != null && params.length > 0)
                result = params[0];
        }
        return result;
    }

    /**
     *  Check a simple name reference.
     */
    public void checkSimpleName(IASNode iNode, Binding binding)
    {
        if ( SemanticUtils.isThisKeyword(iNode) )
        {
           LanguageIdentifierNode.Context context = ((LanguageIdentifierNode)iNode).getContext();

           if ( context == LanguageIdentifierNode.Context.STATIC_CONTEXT || context == LanguageIdentifierNode.Context.PACKAGE_CONTEXT)
           {
               addProblem(new ThisUsedInStaticFunctionProblem(iNode));
           }
        }
        else if ( SemanticUtils.isArgumentsReference(binding) )
        {
            FunctionDefinition functionDef = SemanticUtils.getFunctionDefinition(iNode);
            if (functionDef != null)
            {
                ParameterDefinition[] parameters = functionDef.getParameters();
                for (ParameterDefinition param : parameters)
                {
                    if (param.isRest())
                    {
                        addProblem(new RestParamAndArgumentsUsedTogetherProblem(iNode));
                        break;
                    }
                }
            }
        }

        if( binding.getDefinition() == null && isPackageReference(binding) )
        {
            // A simple name only counts as a package reference if it did not resolve to anything
            addProblem(new PackageCannotBeUsedAsValueProblem(iNode, binding.getName().getBaseName()));
        }
    }

    /**
     * Translate a {@link PooledValue} into a {@link BuiltinType}.
     * @param value The {@link PooledValue} to translate.
     * @return The {@link BuiltinType} for the specified {@link PooledValue}.
     */
    private static BuiltinType getBuiltinTypeOfPooledValue(PooledValue value)
    {
        switch ( value.getKind() )
        {
            case ABCConstants.CONSTANT_Int:
                return BuiltinType.INT;
            case ABCConstants.CONSTANT_UInt:
                return BuiltinType.UINT;
            case ABCConstants.CONSTANT_Double:
                return BuiltinType.NUMBER;
            case ABCConstants.CONSTANT_Utf8:
                return BuiltinType.STRING;
            case ABCConstants.CONSTANT_True:
            case ABCConstants.CONSTANT_False:
                return BuiltinType.BOOLEAN;
            case ABCConstants.CONSTANT_Undefined:
                return BuiltinType.VOID;
            case ABCConstants.CONSTANT_Null:
                return BuiltinType.NULL;
            case ABCConstants.CONSTANT_Namespace:
            case ABCConstants.CONSTANT_PrivateNs:
            case ABCConstants.CONSTANT_PackageNs:
            case ABCConstants.CONSTANT_PackageInternalNs:
            case ABCConstants.CONSTANT_ProtectedNs:
            case ABCConstants.CONSTANT_ExplicitNamespace:
            case ABCConstants.CONSTANT_StaticProtectedNs:
                return BuiltinType.NAMESPACE;
            default:
                assert false : "Unknown default value kind " + value.getKind();
        }
        return BuiltinType.ANY_TYPE;
    }
    
    /**
     *  Translate a {@link PooledValue} into an {@link IDefinition} type.
     *  @return the {@link IDefinition} for the value's type.
     */
    private IDefinition getTypeOfPooledValue(PooledValue value)
    {
        BuiltinType builtinType = getBuiltinTypeOfPooledValue(value);

        return utils.getBuiltinType(builtinType);
    }

    /**
     * Helper method called by
     * {@link #checkInitialValue(IVariableNode, Binding, PooledValue)}.
     * <p>
     * Conversion rules:
     * <table>
     * <tr>
     * <td></td>
     * <td>*</td>
     * <td>Object</td>
     * <td>void</td>
     * <td>Array</td>
     * <td>XML</td>
     * <td>Function</td>
     * <td>Class</td>
     * <td>String</td>
     * <td>Boolean</td>
     * <td>Number</td>
     * <td>uint</td>
     * <td>int</td>
     * </tr>
     * <tr>
     * <td>CONSTANT_Int</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/coerce to string</td> <!-- String -->
     * <td>Error/coerce to Boolean</td> <!-- Boolean -->
     * <td>No Error</td> <!-- Number -->
     * <td>If negative error and coerce otherwise no error</td> <!-- uint -->
     * <td>-</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_UInt</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/coerce to string</td> <!-- String -->
     * <td>Error/coerce to Boolean</td> <!-- Boolean -->
     * <td>No Error</td> <!-- Number -->
     * <td>-</td> <!-- uint -->
     * <td>Error/coerce if not an integer in int range</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_Double</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/coerce to string</td> <!-- String -->
     * <td>Error/coerce to Boolean</td> <!-- Boolean -->
     * <td>-</td> <!-- Number -->
     * <td>Error/coerce if not a positive error in uint range</td> <!-- uint -->
     * <td>Error/coerce if not an integer in int range</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_Utf8</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>-</td> <!-- String -->
     * <td>Error/coerce to Boolean</td> <!-- Boolean -->
     * <td>Error/coerce to Number</td> <!-- Number -->
     * <td>Error/coerce to uint</td> <!-- uint -->
     * <td>Error/coerce to int</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_True</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/coerce to string</td> <!-- String -->
     * <td>-</td> <!-- Boolean -->
     * <td>Error/coerce to Number</td> <!-- Number -->
     * <td>Error/coerce to uint</td> <!-- uint -->
     * <td>Error/coerce to int</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_False</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/coerce to string</td> <!-- String -->
     * <td>-</td> <!-- Boolean -->
     * <td>Error/coerce to Number</td> <!-- Number -->
     * <td>Error/coerce to uint</td> <!-- uint -->
     * <td>Error/coerce to int</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_Undefined</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>No error</td> <!-- Array -->
     * <td>No error</td> <!-- XML -->
     * <td>No error</td> <!-- Function -->
     * <td>No error</td> <!-- Class -->
     * <td>No error</td> <!-- String -->
     * <td>No error</td> <!-- Boolean -->
     * <td>No error</td> <!-- Number -->
     * <td>No error</td> <!-- uint -->
     * <td>No error</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_Null</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>No error</td> <!-- Array -->
     * <td>No error</td> <!-- XML -->
     * <td>No error</td> <!-- Function -->
     * <td>No error</td> <!-- Class -->
     * <td>No error</td> <!-- String -->
     * <td>Error/coerce to Boolean</td> <!-- Boolean -->
     * <td>Error/coerce to Number</td> <!-- Number -->
     * <td>Error/coerce to uint</td> <!-- uint -->
     * <td>Error/coerce to int</td> <!-- int -->
     * </tr>
     * <tr>
     * <td>CONSTANT_Namespace, CONSTANT_*Ns</td>
     * <td>No error</td> <!-- * -->
     * <td>No error</td> <!-- Object -->
     * <td>No error</td> <!-- void -->
     * <td>Error/transform to null</td> <!-- Array -->
     * <td>Error/transform to null</td> <!-- XML -->
     * <td>Error/transform to null</td> <!-- Function -->
     * <td>Error/transform to null</td> <!-- Class -->
     * <td>Error/transform to null</td> <!-- String -->
     * <td>Error/transform to true</td> <!-- Boolean -->
     * <td>Error/transform to 0</td> <!-- Number -->
     * <td>Error/transform to 0</td> <!-- uint -->
     * <td>Error/transform to 0</td> <!-- int -->
     * </tr>
     * <tr>
     * </table>
     * 
     * @param initial_value_location The {@link ISourceLocation} for the
     * variable's initializer expression.
     * @param desired_type {@link IDefinition} that the initial value's type
     * should be compatible with.
     * @param initial_value {@link PooledValue} containing the constant
     * initializer for the variable.
     * @return A {@link PooledValue} whose type is compatible with desired_type.
     */
    private PooledValue checkInitialValue(ISourceLocation initial_value_location, IDefinition desired_type, PooledValue initial_value)
    {
        IDefinition value_type = getTypeOfPooledValue(initial_value);
        if  (desired_type == null ||
             desired_type.equals(value_type) ||
             utils.isInstanceOf(value_type, desired_type))
        {
            return initial_value;
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.OBJECT) ||
                 utils.isBuiltin(desired_type, BuiltinType.ANY_TYPE))
        {
            return initial_value;
        }
        else if (utils.isBuiltin(value_type, BuiltinType.VOID))
        {
            return initial_value;
        }
        else if (
            utils.isBuiltin(desired_type, BuiltinType.ARRAY) ||
            utils.isBuiltin(desired_type, BuiltinType.XML) ||
            utils.isBuiltin(desired_type, BuiltinType.FUNCTION) ||
            utils.isBuiltin(desired_type, BuiltinType.CLASS)
            )
        {
            if (utils.isBuiltin(value_type, BuiltinType.NULL))
                return initial_value;
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), "null"));
            // transform initial_value to null.
            return new PooledValue(ABCConstants.NULL_VALUE);
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.STRING))
        {
            assert !(utils.isBuiltin(value_type, BuiltinType.STRING));
            if (utils.isBuiltin(value_type, BuiltinType.NULL))
                return initial_value;
            String initial_value_string = ECMASupport.toString(initial_value.getValue());
            String initial_value_quoted = "\"" + initial_value_string + "\"";
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), initial_value_quoted));
            // transform initial_value to a string constant.
            return new PooledValue(initial_value_string);
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.BOOLEAN))
        {
            assert !(utils.isBuiltin(value_type, BuiltinType.BOOLEAN));
            // transform initial_value to a boolean constant.
            boolean initial_value_boolean = ECMASupport.toBoolean(initial_value.getValue());
            // tell the programmer about the transformation we did.
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), String.valueOf(initial_value_boolean)));
            return new PooledValue(initial_value_boolean);
                
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.NUMBER))
        {
            if (utils.isBuiltin(value_type, BuiltinType.INT) ||
                utils.isBuiltin(value_type, BuiltinType.UINT) ||
                utils.isBuiltin(value_type, BuiltinType.NUMBER))
                return initial_value;
            Number initial_value_numeric = ECMASupport.toNumeric(initial_value.getValue());
            double initial_value_double = initial_value_numeric != null ? initial_value_numeric.doubleValue() : 0;
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), String.valueOf(initial_value_double)));
            return new PooledValue(initial_value_double);
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.UINT))
        {
            return checkInitialUIntValue(initial_value_location, desired_type, initial_value, value_type);
        }
        else if (utils.isBuiltin(desired_type, BuiltinType.INT))
        {
            return checkInitialIntValue(initial_value_location, desired_type, initial_value, value_type);
        }
        
        addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), "null"));
        return new PooledValue(ABCConstants.NULL_VALUE);
    }

    /**
     * Helper method called by
     * {@link #checkInitialValue(ISourceLocation, IDefinition, PooledValue)}.
     * 
     * @param initial_value_location The {@link ISourceLocation} for the
     * variable's initializer expression.
     * @param desired_type {@link IDefinition} that the initial value's type
     * should be compatible with. This should always by the {@link IDefinition}
     * for int. This is passed in as a convenience.
     * @param initial_value {@link PooledValue} containing the constant
     * initializer for the variable.
     * @param value_type {@link IDefinition} for the type of value contained by
     * the specified {@link PooledValue}.
     * @return A {@link PooledValue} whose type is compatible with desired_type.
     */
    private PooledValue checkInitialIntValue(ISourceLocation initial_value_location, IDefinition desired_type, PooledValue initial_value, IDefinition value_type)
    {
        assert !(utils.isBuiltin(value_type, BuiltinType.INT));
        if (utils.isBuiltin(value_type, BuiltinType.UINT))
        {
            long initial_value_long = initial_value.getLongValue();
            if (initial_value_long > Integer.MAX_VALUE)
                return addIntOutOfRangeProblem(initial_value_location, desired_type, initial_value_long);
            else
                return initial_value;
        }
        else if (utils.isBuiltin(value_type, BuiltinType.NUMBER))
        {
            double initial_value_double = initial_value.getDoubleValue();
            double initial_value_rounded = ECMASupport.toInteger(initial_value_double);
            int initial_value_int = ECMASupport.toInt32(initial_value_double);
            if (initial_value_rounded != initial_value_double)
            {
                addProblem(new InitializerValueNotAnIntegerProblem(
                        initial_value_location,
                        desired_type.getBaseName(),
                        String.valueOf(initial_value_double), String.valueOf(initial_value_int)));
                return new PooledValue(initial_value_int);
            }
            else if ((initial_value_rounded < Integer.MIN_VALUE) || (initial_value_rounded > Integer.MAX_VALUE))
            {
                return addIntOutOfRangeProblem(initial_value_location, desired_type, initial_value_rounded);
            }
            else
            {
                // transform the number that happens to be an integer into
                // an integer.
                return new PooledValue(initial_value_int);
            }
        }
        else
        {
            Number initial_value_numeric = ECMASupport.toNumeric(initial_value.getValue());
            double initial_value_double = initial_value_numeric != null ? initial_value_numeric.doubleValue() : 0;
            int initial_value_int = ECMASupport.toInt32(initial_value_double);
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), String.valueOf(initial_value_int)));
            return new PooledValue(initial_value_int);
        }
    }

    /**
     * Helper method called by
     * {@link #checkInitialValue(ISourceLocation, IDefinition, PooledValue)}.
     * 
     * @param initial_value_location The {@link ISourceLocation} for the
     * variable's initializer expression.
     * @param desired_type {@link IDefinition} that the initial value's type
     * should be compatible with. This should always by the {@link IDefinition}
     * for uint. This is passed in as a convenience.
     * @param initial_value {@link PooledValue} containing the constant
     * initializer for the variable.
     * @param value_type {@link IDefinition} for the type of value contained by
     * the specified {@link PooledValue}.
     * @return A {@link PooledValue} whose type is compatible with desired_type.
     */
    private PooledValue checkInitialUIntValue(ISourceLocation initial_value_location, IDefinition desired_type, PooledValue initial_value, IDefinition value_type)
    {
        assert !(utils.isBuiltin(value_type, BuiltinType.UINT));
        if (utils.isBuiltin(value_type, BuiltinType.INT))
        {
            int initial_value_int = initial_value.getIntegerValue();
            
            if (initial_value_int < 0)
                return addUIntOutOfRangeProblem(initial_value_location, desired_type, initial_value_int);
            else
                return initial_value;
        }
        else if (utils.isBuiltin(value_type, BuiltinType.NUMBER))
        {
            double initial_value_double = initial_value.getDoubleValue();
            double initial_value_int = ECMASupport.toInteger(initial_value_double);
            long initial_value_long = ECMASupport.toUInt32(initial_value_int);
            if (initial_value_double != initial_value_int)
            {
                addProblem(new InitializerValueNotAnIntegerProblem(
                        initial_value_location,
                        desired_type.getBaseName(),
                        String.valueOf(initial_value_double), String.valueOf(initial_value_long)));
                return new PooledValue(initial_value_long);
            }
            else if ((initial_value_int < 0) || (initial_value_int > 0xFFFFFFFFL))
            {
                return addUIntOutOfRangeProblem(initial_value_location, desired_type, initial_value_int);
            }
            else
            {
                // transform the number that happens to be an unsigned integer into
                // an unsigned integer.
                return new PooledValue(initial_value_long);
            }
        }
        else
        {
            Number initial_value_numeric = ECMASupport.toNumeric(initial_value.getValue());
            double initial_value_double = initial_value_numeric != null ? initial_value_numeric.doubleValue() : 0;
            long initial_value_long = ECMASupport.toUInt32(initial_value_double);
            addProblem(new IncompatibleInitializerTypeProblem(initial_value_location, value_type.getBaseName(), desired_type.getBaseName(), String.valueOf(initial_value_long)));
            return new PooledValue(initial_value_long);
        }
    }
    
    private PooledValue addUIntOutOfRangeProblem(ISourceLocation initial_value_location, IDefinition required_type, double initial_value_int)
    {
        long initial_value_long = ECMASupport.toUInt32(initial_value_int);
        addProblem(new InitializerValueOutOfRangeProblem(
                initial_value_location, 
                required_type.getBaseName(),
                String.valueOf((long)initial_value_int),
                "0",
                String.valueOf(0xFFFFFFFFL),
                String.valueOf(initial_value_long)));
        return new PooledValue(initial_value_long);
    }

    private PooledValue addIntOutOfRangeProblem(ISourceLocation initial_value_location, IDefinition required_type, double initial_value_double)
    {
        int initial_value_int = ECMASupport.toInt32(initial_value_double);
        addProblem(new InitializerValueOutOfRangeProblem(
                initial_value_location, 
                required_type.getBaseName(),
                String.valueOf((long)initial_value_double),
                String.valueOf(Integer.MIN_VALUE),
                String.valueOf(Integer.MAX_VALUE),
                String.valueOf(initial_value_int)));
        return new PooledValue(initial_value_int);
    }


    /**
     *  Check a getproperty operation.
     *  @param binding - the Binding which is being fetched.
     */
    public void checkGetProperty(Binding binding)
    {
        Name name = binding.getName();
        assert name != null;

        if ( utils.isWriteOnlyDefinition(binding.getDefinition()) )
        {
            addProblem(new PropertyIsWriteOnlyProblem(
                binding.getNode(),
                name.getBaseName()
            ));
        }
        
        switch ( name.getKind() )
        {
            case ABCConstants.CONSTANT_QnameA:
            case ABCConstants.CONSTANT_MultinameA:
            case ABCConstants.CONSTANT_MultinameLA:
            case ABCConstants.CONSTANT_RTQnameA:
            case ABCConstants.CONSTANT_RTQnameLA:
                {
                    //  TODO: Attribute checks
                    break;
                }
            case ABCConstants.CONSTANT_TypeName:
                {
                    //  TODO: Type name checks
                    break;
                }
            case ABCConstants.CONSTANT_RTQname:
            case ABCConstants.CONSTANT_RTQnameL:
            case ABCConstants.CONSTANT_MultinameL:
                {
                    //  Not much to be done with these.
                }
            default:
                {
                    if ( binding.getDefinition() == null && SemanticUtils.definitionCanBeAnalyzed(binding, this.project) )
                    {
                        addProblem(accessUndefinedProperty(binding, binding.getNode()));
                    }
                    checkReference(binding);
                }
        }
    }

    /**
     * Check for possible problems with a reference for an r-value.
     * This will find 2 kinds of problems:
     *  1. Ambiguous references
     *  2. References to deprecated symbols
     *
     * @param b the binding to check
     */
    public void checkReference(Binding b)
    {
        checkReference(b, false);
    }

    /**
     * Check for possible problems with a reference.
     * This will find 2 kinds of problems:
     *  1. Ambiguous references
     *  2. References to deprecated symbols
     *
     * @param b the binding to check
     * @param forLValue Whether the binding is for an l-value.
     */
    public void checkReference(Binding b, boolean forLValue)
    {
        if (b != null)
        {
            IDefinition definition = b.getDefinition();
            
            if (definition != null)
            {
                // Since the BURM doesn't currently understand whether a Binding
                // is for an l-value or an r-value, a Binding for an l-value
                // may contain a getter and a Binding for an r-value may contain
                // a setter. If that's the case, we need to find the corresponding
                // accessor.
                if (forLValue && definition instanceof IGetterDefinition ||
                    !forLValue && definition instanceof ISetterDefinition)
                {
                     definition = ((IAccessorDefinition)definition).resolveCorrespondingAccessor(project);
                }
                
                IASNode node = b.getNode();

                checkAmbiguousReference(b);
                checkDeprecated(node, definition);
            }
        }
    }

    /**
     * Log a problem if the binding is an ambiguous reference
     * @param b the binding to check
     */
    private void checkAmbiguousReference(Binding b)
    {
        if( SemanticUtils.isAmbiguousReference(b) )
        {
            addProblem(new AmbiguousReferenceProblem(b.getNode(), b.getName().getBaseName()));
        }
    }

    /**
     * Log a problem if the definition passed in has been marked deprecated
     * and the node passed in is not within a deprecated API.
     * 
     * @param site  the Node to use to obtain location info for any problems
     * @param def   the definition to check
     */
    private void checkDeprecated(IASNode site, IDefinition def)
    {
        if (def != null && def.isDeprecated())
        {
            if (!SemanticUtils.hasDeprecatedAncestor(site))
            {
                ICompilerProblem problem = SemanticUtils.createDeprecationProblem(def, site);
                addProblem(problem);
            }
        }
    }

    /**
     * Check the initial value of an {@link IVariableNode}. The specified
     * {@link IVariableNode} could be:
     * <ul>
     * <li>an {@link IParameterNode} for a function parameter.</li>
     * <li>an {@link IVariableNode} for a var or const in any scope.</li>
     * </ul>
     * This method will create {@link ICompilerProblem}s if the specified
     * initial value is not the correct type and will return an initializer
     * value that is the correct type that was created by apply the AS3 coercion
     * rules.
     * 
     * @param iNode The {@link IVariableNode} whose initializer value should be
     * checked.
     * @param type A {@link Binding} for the specified {@link IVariableNode}'s
     * type annotation.
     * @param initial_value A {@link PooledValue} that contains the constant
     * initializer value computed by the constant propagation code.
     * @return A {@link PooledValue} with the correct type to initialize the
     * specified {@link IVariableNode}. This can be the same as the specified
     * {@link PooledValue} if it was already of the correct type.
     */
    public PooledValue checkInitialValue(IVariableNode iNode, Binding type, PooledValue initial_value)
    {
        assert initial_value != null : "Caller's should generate a compiler problem when a default_value is missing and *not* call this method!";
        ISourceLocation assignedValueExpressionLocation = iNode.getAssignedValueNode();
        IDefinition target_type = type.getDefinition();
        
        return checkInitialValue(assignedValueExpressionLocation, target_type, initial_value);
        
    }

    /**
     *  Analyze an undefined binding and create an appropriate problem.
     *  @return the problem that best fits this error condition.
     */
    private ICompilerProblem accessUndefinedProperty(Binding b, IASNode iNode)
    {
        ICompilerProblem problem;
        
        String unknown_name = null;

        if ( b.getName() != null )
            unknown_name = b.getName().getBaseName();
        else if (SemanticUtils.isThisKeyword(iNode))
            unknown_name = "this";
        else
            return null;

        if ( b.getNode() instanceof MemberAccessExpressionNode )
        {
            MemberAccessExpressionNode maex = (MemberAccessExpressionNode)b.getNode();

            if ( maex.stemIsPackage() && maex.getLeftOperandNode() instanceof IdentifierNode )
            {
                return new AccessUndefinedPropertyInPackageProblem(
                    iNode, 
                    unknown_name,
                    ((IdentifierNode)maex.getLeftOperandNode()).getName()
                );
            }
        }
        else if ((problem = isMissingMember(b.getNode())) != null)
        {
            return problem;
        }
        else if ( utils.isInInstanceFunction(iNode) && utils.isInaccessible((ASScope)utils.getEnclosingFunctionDefinition(iNode).getContainingScope(), b) )
        {
            return new InaccessiblePropertyReferenceProblem(
                    iNode, 
                    b.getName().getBaseName(), 
                    utils.getEnclosingClassName(iNode)
                );
        }

        while (iNode.getSourcePath().contains("compiler-jx") &&
        		iNode.getSourcePath().contains("config.as"))
		{
        	iNode = iNode.getParent();
		}
        	
        return new AccessUndefinedPropertyProblem(iNode, unknown_name);
    }
    
    public ICompilerProblem isMissingMember(IASNode iNode)
    {
        if (iNode instanceof IdentifierNode && iNode.getParent() instanceof MemberAccessExpressionNode)
        {
            MemberAccessExpressionNode mae = (MemberAccessExpressionNode)(iNode.getParent());
            if (iNode == mae.getRightOperandNode())
            {
                ITypeDefinition leftDef = mae.getLeftOperandNode().resolveType(project);
                if (!leftDef.isDynamic())
                    return new AccessUndefinedMemberProblem(iNode, ((IdentifierNode)iNode).getName(), leftDef.getQualifiedName());
            }
        }
        return null;
    }
    
    /**
     *  Ensure a super-qualified access is in an instance method.
     */
    public void checkSuperAccess(IASNode iNode)
    {
        IDefinition def = utils.getDefinition(iNode);
        
        //  If def isn't null, then we know this is a valid expression.
        //  if def is null, allow super.foo if the reference is in an
        //  instance function.
        if ( def == null && !utils.isInInstanceFunction(iNode) )
        {
            addProblem(new InvalidSuperExpressionProblem(iNode));
        }
        
        // For super.f(...), check whether f is deprecated.
        if (iNode instanceof IFunctionCallNode)
        {
            IExpressionNode nameNode = ((IFunctionCallNode)iNode).getNameNode();
            IExpressionNode site = ((IMemberAccessExpressionNode)nameNode).getRightOperandNode();
            def = ((IFunctionCallNode)iNode).resolveCalledExpression(project);
            checkDeprecated(site, def);
            if (def == null || def.isAbstract())
            {
            	String methodName = null;
            	if (nameNode.getNodeID() == ASTNodeID.MemberAccessExpressionID)
            	{
            		MemberAccessExpressionNode mae = (MemberAccessExpressionNode)nameNode;
            		IExpressionNode rightNode = mae.getRightOperandNode();
            		if (rightNode.getNodeID() == ASTNodeID.IdentifierID)
            			methodName = ((IdentifierNode)rightNode).getName();
            	}
                assert methodName != null;
                addProblem(new CallUndefinedMethodProblem( 
                        iNode, methodName
                    ));
            }
        }

        if ( this.superState == SuperState.Initial )
            this.superState = SuperState.Armed;
    }

    private boolean isPackageReference(Binding b)
    {
        IASNode n = b.getNode();
        return n instanceof ExpressionNodeBase && ((ExpressionNodeBase)n).isPackageReference();
    }

    /**
     *  Check foo++ and foo-- expressions.
     */
    public void checkIncDec(IASNode iNode, boolean is_incr)
    {
        IASNode operand = ((IUnaryOperatorNode)iNode).getOperandNode();

        checkImplicitConversion(operand, utils.numberType(), null);

        IDefinition def = utils.getDefinition(operand);
        
        if ( utils.isReadOnlyDefinition(def) )
        {
            if ( is_incr )
                addProblem(new InvalidIncrementOperandProblem(iNode));
            else
                addProblem(new InvalidDecrementOperandProblem(iNode));
        }
        else if ( def instanceof SetterDefinition || def instanceof GetterDefinition )
        {
            // No error, just avoid the else if ( def instanceof IFunctionDefinition ) below
        }
        else if ( def instanceof IFunctionDefinition ||  def instanceof ClassDefinition )
        {
            if ( is_incr )
                addProblem(new InvalidIncrementOperandProblem(iNode));
            else
                addProblem(new InvalidDecrementOperandProblem(iNode));
        }
        else if ( SemanticUtils.isConstDefinition(def) )
        {
            //  TODO: See CMP-1177; enhanced error message would be appropriate.
            if ( is_incr )
                addProblem(new InvalidIncrementOperandProblem(iNode));
            else
                addProblem(new InvalidDecrementOperandProblem(iNode));
        }
    }

    /**
     *  Check foo++ and foo-- expressions.
     *  @param iNode  the inc/dec Node
     *  @param is_incr whether this is an increment or decrement operation
     *  @param binding the binding for the name we are incrementing/decrementing
     */
    public void checkIncDec(IASNode iNode, boolean is_incr, Binding binding)
    {
        checkIncDec(iNode, is_incr);
        if ( binding.getName() != null )
        {
            checkGetProperty(binding);
        }
        else
        {
            addProblem(
                is_incr?
                    new IncrementMustBeReferenceProblem(iNode):
                    new DecrementMustBeReferenceProblem(iNode)
            );
        }
    }

    /**
     *  Perform semantic checks on an lvalue,
     *  i.e., the target of an assignment
     *  or other storage-mutating operation.
     */
    public void checkLValue(IASNode iNode, Binding binding)
    {
        IDefinition def = binding.getDefinition();

        if ( SemanticUtils.isThisKeyword(binding.getNode()) )
        {
            addProblem(new AssignToNonReferenceValueProblem(binding.getNode()));
        }
        else if ( def == null && !utils.hasDynamicBase(binding) && !SemanticUtils.isInWith(binding.getNode()))
        {
            addProblem(accessUndefinedProperty(binding, roundUpUsualSuspects(binding, iNode)));
        }
        else if ( def instanceof IConstantDefinition )
        {
            addProblem(new AssignToConstProblem(iNode));
        }
        else if ( utils.isReadOnlyDefinition(def) )
        {
            addProblem(new AssignToReadOnlyPropertyProblem(iNode, binding.getName().getBaseName()));
        }
        else if ( def instanceof SetterDefinition || def instanceof GetterDefinition)
        {
            // No error, just avoid the else if ( def instanceof IFunctionDefinition ) below
        }
        else if ( def instanceof IFunctionDefinition )
        {
            addProblem(new AssignToFunctionProblem(iNode, binding.getName().getBaseName()));
        }
        else if ( def instanceof ClassDefinition )
        {
            addProblem(new IllegalAssignmentToClassProblem(
                roundUpUsualSuspects(binding, iNode),
                binding.getName().getBaseName()
            ));
        }

        checkReference(binding, true);
    }

    /**
     *  Check a member access expression.
     */
    public void checkMemberAccess(IASNode iNode, Binding member, int opcode)
    {
        //  Don't check synthetic bindings.
        IASNode member_node = member.getNode();

        if ( member_node == null )
            return;

        IDefinition def = utils.getDefinition(member_node);

        if ( def == null && utils.definitionCanBeAnalyzed(member) )
        {
            // if it is foo.mx_internal::someProp, just say it passes
            if (member_node.getParent() instanceof NamespaceAccessExpressionNode)
                return;
            
            if ( utils.isInaccessible(iNode, member) )
            {
                addProblem(new InaccessiblePropertyReferenceProblem(
                    member_node, 
                    member.getName().getBaseName(), 
                    utils.getTypeOfStem(iNode))
                );
            }
            else
            {
                ICompilerProblem p = null;
                // Look for the special case of "something." (empty right hand side).
                // Return a less perplexing error for this case.
                if (iNode instanceof IMemberAccessExpressionNode)
                {
                    IMemberAccessExpressionNode maen = (IMemberAccessExpressionNode)iNode;
                    IExpressionNode right = maen.getRightOperandNode();
                    if (right instanceof IIdentifierNode)
                    {
                        if (((IIdentifierNode)right).getName().isEmpty())
                        {
                            p = new MissingPropertyNameProblem(right);
                        }
                    }
                }
                if (p== null)
                {
                    // If right side not blank, then use normal undefined member
                    p = new AccessUndefinedMemberProblem(
                            member_node, 
                            member.getName().getBaseName(), 
                            utils.getTypeOfStem(iNode));
                }
                addProblem(p);
            }
        }
        else if ( utils.isWriteOnlyDefinition(member.getDefinition()) )
        {
            addProblem(new PropertyIsWriteOnlyProblem(
                member_node,
                member.getName().getBaseName()
            ));
        }
        else
        {
            checkReference(member);
        }

    }
    
    /**
     * Check a "new expression".
     * 
     * @param call_node {@link FunctionCallNode} that has the "new" call.
     */
    @SuppressWarnings("incomplete-switch")
	public void checkNewExpr(IASNode call_node)
    {
        final ExpressionNodeBase name = ((FunctionCallNode)call_node).getNameNode();
        if (name instanceof MemberAccessExpressionNode)
        {
            final MemberAccessExpressionNode func_name = (MemberAccessExpressionNode)name;
            final IDefinition def = func_name.resolve(project);
            if ( def instanceof InterfaceDefinition )
            {
                addProblem(new InterfaceCannotBeInstantiatedProblem(call_node));
            }
            else if ( def instanceof ClassDefinition )
            {
                IClassDefinition classDef = (IClassDefinition) def;
                checkPrivateConstructorNewExpr(call_node, null, classDef, classDef.getConstructor());
            }
            else if ( def instanceof GetterDefinition )
            {
                // pass
            }
            else if (def instanceof FunctionDefinition)
            {
                final FunctionDefinition func_def = (FunctionDefinition)def;
                switch (func_def.getFunctionClassification())
                {
                    case CLASS_MEMBER:
                    case INTERFACE_MEMBER:
                        addProblem(new MethodCannotBeConstructorProblem(call_node));
                        break;
                }

                if (func_def.isConstructor())
                {
                    IDefinition class_def = func_def.getParent();
                    checkPrivateConstructorNewExpr(call_node, null, class_def, func_def);
                }
            }
            else if (def == null)
            {
            	addProblem(new UnresolvedClassReferenceProblem(call_node, func_name.getDisplayString()));
            }
        }
    }

    /**
     *  Check a new expression.
     */
    public void checkNewExpr(IASNode iNode, Binding class_binding, Vector<? extends Object> args)
    {
        IDefinition def = class_binding.getDefinition();

        if ( def == null && utils.definitionCanBeAnalyzed(class_binding) && !(class_binding.getName().isTypeName()) )
        {
            // Note: don't have to check accessability because
            // AS3 mandates constructors be public.

            addProblem(new CallUndefinedMethodProblem(
                roundUpUsualSuspects(class_binding, iNode),
                class_binding.getName().getBaseName()
            ));
        }
        else if ( def instanceof InterfaceDefinition )
        {
            addProblem(new InterfaceCannotBeInstantiatedProblem(
                roundUpUsualSuspects(class_binding, iNode)
            ));
        }
        else if ( def instanceof ClassDefinition )
        {
            ClassDefinition class_def = (ClassDefinition)def;

            if ( project.getAllowAbstractClasses() && class_def.isAbstract() )
            {
                addProblem(new AbstractClassCannotBeInstantiatedProblem(
                    roundUpUsualSuspects(class_binding, iNode)
                ));
            }

            IFunctionDefinition ctor = class_def.getConstructor();

            if ( ctor instanceof FunctionDefinition )
            {
                FunctionDefinition func_def = (FunctionDefinition)ctor;
                checkFormalsVsActuals(iNode, func_def, args);
                
                checkPrivateConstructorNewExpr(iNode, class_binding, class_def, func_def);
            }
        }
        else if ( def instanceof GetterDefinition )
        {
        }
        else if ( def instanceof FunctionDefinition )
        {
            FunctionDefinition func_def = (FunctionDefinition) def;

            IFunctionDefinition.FunctionClassification func_type = func_def.getFunctionClassification();

            if (func_def.isConstructor())
            {
                IDefinition class_def = func_def.getParent();
                checkPrivateConstructorNewExpr(iNode, class_binding, class_def, func_def);
            }
            else if ( func_type.equals(IFunctionDefinition.FunctionClassification.CLASS_MEMBER) || func_type.equals(IFunctionDefinition.FunctionClassification.INTERFACE_MEMBER) )
            {
                addProblem(new MethodCannotBeConstructorProblem(
                    roundUpUsualSuspects(class_binding, iNode)
                ));
            }
        }
        else if ( def instanceof IVariableDefinition)
        {
            if (class_binding.isLocal())
            {
                // Note: previously, local variable bindings were not checked at
                // all, but actually, variables of most types cannot be used with a
                // "new" expression -JT

                ITypeDefinition typeDef = def.resolveType(project);
                if (typeDef != null
                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.CLASS, project)
                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.FUNCTION, project)
                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.OBJECT, project)
                        && !SemanticUtils.isBuiltin(typeDef, BuiltinType.ANY_TYPE, project))
                {
                    addProblem(new CallUndefinedMethodProblem(
                        roundUpUsualSuspects(class_binding, iNode),
                        class_binding.getName().getBaseName()
                    ));
                }
            }
        }

        checkReference(class_binding);
    }

    private void checkPrivateConstructorNewExpr(IASNode iNode, Binding class_binding, IDefinition classDef, IFunctionDefinition funcDef)
    {
        if (!project.getAllowPrivateConstructors() || !funcDef.isPrivate())
        {
            return;
        }

        IScopedNode enclosingScope = iNode.getContainingScope();
        
        if (enclosingScope != null)
        {
            boolean needsProblem = true;
            IASScope currentScope = enclosingScope.getScope();
            while (currentScope != null)
            {
                IDefinition currentDef = currentScope.getDefinition();
                if (currentDef instanceof IClassDefinition)
                {
                    needsProblem = !classDef.equals(currentScope.getDefinition());
                    break;
                }
                currentScope = currentScope.getContainingScope();
            }
            if(needsProblem)
            {
                if(class_binding != null)
                {
                    addProblem(new InaccessibleConstructorReferenceProblem(
                        roundUpUsualSuspects(class_binding, iNode), classDef.getQualifiedName()
                    ));
                }
                else
                {
                    addProblem(new InaccessibleConstructorReferenceProblem(
                        iNode, classDef.getQualifiedName()
                    ));
                }
            }
        }
    }

    /**
     *  Check a return expression that returns a value.
     *  @param iNode - the return statement.  
     *    Known to have a child 0 expression.
     */
    public void checkReturnValue(IASNode iNode)
    {
        FunctionDefinition func_def = SemanticUtils.getFunctionDefinition(iNode);
        
        if ( func_def != null )
        {
            try
            {
                IExpressionNode returnExpression = ((IReturnNode)iNode).getReturnValueNode();
                IDefinition return_type = func_def.resolveReturnType(project);

                //  void has its own special type logic.
                if ( ClassDefinition.getVoidClassDefinition().equals(return_type) )
                {
                    IDefinition value_type = ((ExpressionNodeBase)returnExpression).resolveType(project);
                    if ( value_type != null && ! value_type.equals(ClassDefinition.getVoidClassDefinition()) )
                        addProblem(new ReturnValueMustBeUndefinedProblem(returnExpression));
                }
                else if ( func_def.isConstructor() )
                {
                    addProblem(new ReturnValueInConstructorProblem(returnExpression));
                }
                else
                {
                    checkImplicitConversion(returnExpression, return_type, null);
                }
            }
            catch ( Exception namerezo_problem )
            {
                //  Ignore until CMP-869 is fixed.
            }
        }
        else if ( isInPackageDefinition(iNode) )
        {
            addProblem(new ReturnCannotBeUsedInPackageProblem(iNode));
        }
        else if ( isInClassDefinition(iNode) )
        {
            addProblem(new ReturnCannotBeUsedInStaticProblem(iNode));
        }
        else if ( iNode.getAncestorOfType(MXMLDocumentNode.class) != null )
        {
            //  TODO: Remove this once CMP-874 is resolved.
        }
        else
        {
            addProblem(new ReturnCannotBeUsedInGlobalProblem(iNode));
        }

        if ( this.superState == SuperState.Initial )
            this.superState = SuperState.Armed;
    }
  
    /**
     *  Check a return expression that returns void.
     *  @param iNode - the return statement.  
     */
    public void checkReturnVoid(IASNode iNode)
    {
        if ( SemanticUtils.isInFunction(iNode) )
        {
            if ( SemanticUtils.functionMustReturnValue(iNode, currentScope.getProject().getAllowAbstractClasses(), this.project) )
                addProblem(new ReturnMustReturnValueProblem(iNode));
        }
        else if ( isInClassDefinition(iNode) )
        {
            addProblem(new ReturnCannotBeUsedInStaticProblem(iNode));
        }
        else if ( isInPackageDefinition(iNode) )
        {
            addProblem(new ReturnCannotBeUsedInPackageProblem(iNode));
        }
        else if ( iNode.getAncestorOfType(MXMLDocumentNode.class) != null )
        {
            //  TODO: Remove this once CMP-874 is resolved.
        }
        else
        {
            addProblem(new ReturnCannotBeUsedInGlobalProblem(iNode));
        }

        if ( this.superState == SuperState.Initial )
            this.superState = SuperState.Armed;
    }

    /**
     *  Perform semantic checks that require flow-aware analysis.
     *  @param iNode - an AST within a function.
     *  @param mi - the function's MethodInfo.
     *  @param mbi - the function's MethodBodyInfo.
     */
    public void checkControlFlow(IASNode iNode, MethodInfo mi, MethodBodyInfo mbi)
    {
        InstructionList il = mbi.getInstructionList();

        //  Walk the control flow graph if there are any issues that
        //  require it.
        if  ( 
                il.size() > 0 &&
                il.lastElement() == ABCGeneratingReducer.synthesizedReturnVoid && 
                SemanticUtils.functionMustReturnValue(iNode,
                    currentScope.getProject().getAllowAbstractClasses(),
                    this.project)
            )
        {
            for ( IBasicBlock b: mbi.getCfg().blocksInControlFlowOrder() )
            {
                if ( b.size() > 0 )
                {
                    //  If at some point it's necessary to walk the CFG regardless,
                    //  then this check can be for any OP_returnvoid and the alternate
                    //  problem injection site in checkReturnVoid can be removed.
                    if ( b.get(b.size()-1) == ABCGeneratingReducer.synthesizedReturnVoid )
                    {
                        addProblem(new ReturnMustReturnValueProblem(iNode));
                        break;
                    }
                }
            }
        }
    }

    /**
     *  Check a throw statement.
     */
    public void checkThrow(IASNode iNode)
    {
        if ( this.superState == SuperState.Initial )
            this.superState = SuperState.Armed;
    }

    /**
     *  Check an import directive.
     *  @param importNode - the import node.
     */
    public void checkImportDirective(IImportNode importNode)
    {
        IASNode site = importNode.getImportNameNode();
        
        String importAlias = importNode.getImportAlias();
        if (importAlias != null && !project.getAllowImportAliases())
        {
            //import aliases need to be enabled
            addProblem(new SyntaxProblem(importNode, "="));
        }
        
        if (!SemanticUtils.isValidImport(importNode, project, currentScope.getInInvisibleCompilationUnit()))
        {
            String importName = importNode.getImportName();
            if (importNode.isWildcardImport())
                addProblem(new UnknownWildcardImportProblem(site, importName));
            else
                addProblem(new UnknownImportProblem(site, importName));
        }
        
        // Check if a deprecated definition is being imported.
        if (!importNode.isWildcardImport())
        {
            IDefinition importedDefinition = importNode.resolveImport(project);
            checkDeprecated(site, importedDefinition);
        }
    }

    /**
     *  Check a use namespace directive.
     *  @param iNode - the use namespace node.
     *  @param ns_name - the namespace's Binding.
     */
    public void checkUseNamespaceDirective(IASNode iNode, Binding ns_name)
    {
        if ( ns_name.getDefinition() == null && ns_name.getName() != null )
        {
            // For error reporting, let's get the fully qualified name of the namespace, if possible
            String fullNamespaceName=null;
            IASNode n = ns_name.getNode();
            if (n instanceof IIdentifierNode)
            {
                // In cases I've seen we go through this path
                fullNamespaceName = ((IIdentifierNode)n).getName();
            }
            else
            {
                // This is purely defensive programming - if for some reason we can't get the full name,
                // go back to this older code that gets the short name.
                fullNamespaceName = ns_name.getName().getBaseName();
            }
           
            addProblem(
                new UnknownNamespaceProblem (
                    roundUpUsualSuspects(ns_name, iNode),
                    fullNamespaceName
                )
            );
        }
        
        checkReference(ns_name);
    }

    /**
     *  Check a unary operator.
     *  @param iNode - the operator's i-node.
     *  @param opcode - the corresponding opcode.
     */
    public void checkUnaryOperator(IASNode iNode, int opcode)
    {
        switch(opcode)
        {
            case ABCConstants.OP_negate:
            case ABCConstants.OP_convert_d:
            case ABCConstants.OP_bitnot:
                checkImplicitConversion(((IUnaryOperatorNode)iNode).getOperandNode(), utils.numberType(), null);
                break;
        }
    }

    /**
     *  @return true if the i-node is in a class definition.
     */
    private boolean isInClassDefinition(IASNode iNode)
    {
        return iNode.getAncestorOfType(ClassNode.class) != null;
    }

    /**
     *  @return true if the i-node is in a package definition.
     */
    private boolean isInPackageDefinition(IASNode iNode)
    {
        return iNode.getAncestorOfType(PackageNode.class) != null;
    }

    /**
     * Ensure that a definition does not have the same modifier more than once
     */
    public void checkForDuplicateModifiers(BaseDefinitionNode bdn)
    {
        ModifiersContainerNode mcn = bdn.getModifiersContainer();
        ModifiersSet modifierSet = bdn.getModifiers();
        if( mcn != null && modifierSet != null )
        {
            int modifierNodeCount = mcn.getChildCount();
            if( modifierNodeCount > modifierSet.getAllModifiers().length )
            {
                ModifiersSet tempSet = new ModifiersSet();
                // More children than modifiers - must have dups
                for( int i = 0; i < modifierNodeCount; ++i )
                {
                    IASNode node = mcn.getChild(i);
                    if( node instanceof ModifierNode )
                    {
                        ModifierNode modNode = (ModifierNode)node;
                        if( tempSet.hasModifier(modNode.getModifier()) )
                        {
                            currentScope.addProblem(new DuplicateAttributeProblem(modNode, modNode.getModifierString()));
                        }
                        tempSet.addModifier(modNode);
                    }
                }
            }
        }
    }
    
    /**
     * Looks for namespace prefixes on definitions inside of functions. 
     * Example:
     *  <code><pre>
     *  function foo() : void {
     *      private var bar:int;// this will give "Access modifier not allowed..."
     *      ns var baz:int;     // this will give "Namespace override not allowed ..."
     *  }
     *  </pre></code>
     *  
     *  This function must only be called for nodes that are in fact withing a function.
     */
    private void checkForNamespaceInFunction(BaseDefinitionNode node, LexicalScope scope)
    {
        assert SemanticUtils.isInFunction(node);
        DefinitionBase def = node.getDefinition();
        INamespaceReference nsRef = def.getNamespaceReference();
        if (!(nsRef instanceof NamespaceDefinition.IInternalNamespaceDefinition) &&
                !(nsRef instanceof NamespaceDefinition.IFilePrivateNamespaceDefinition))
        {
            IASNode site = node.getNamespaceNode();
            if (site == null)
                site = node;
            boolean isAccessor = nsRef instanceof NamespaceDefinition.ILanguageNamespaceDefinition;
           
            currentScope.addProblem(new NamespaceOverrideInsideFunctionProblem(site, isAccessor));
        }
    }

    /**
     *  Check a variable declaration.
     */
    public void checkVariableDeclaration(IASNode iNode)
    {
        VariableNode var = (VariableNode)iNode;
        ModifiersSet modifiersSet = var.getModifiers();

        boolean isInFunction = SemanticUtils.isInFunction(iNode);
         
        if (isInFunction)
        {
            checkForNamespaceInFunction(var, currentScope);
        }
        
        //  Variable decls inside methods can't have attributes other than namespaces.
        if ( isInFunction && modifiersSet != null)
        {
            IASNode site = var.getNameExpressionNode();
            for ( ASModifier modifier : modifiersSet.getAllModifiers() )
            {
                if( modifier == ASModifier.NATIVE )
                {
                    currentScope.addProblem(new NativeVariableProblem(site));
                }
                else if (modifier == ASModifier.DYNAMIC )
                {
                    currentScope.addProblem(new DynamicNotOnClassProblem(site));
                }
                else if( modifier == ASModifier.FINAL )
                {
                    currentScope.addProblem(new FinalOutsideClassProblem(site));
                }
                else if( modifier == ASModifier.OVERRIDE )
                {
                    currentScope.addProblem(new InvalidOverrideProblem(site));
                }
                else if( modifier == ASModifier.VIRTUAL )
                {
                    currentScope.addProblem(new VirtualOutsideClassProblem(site));
                }
                else if( modifier == ASModifier.STATIC )
                {
                    currentScope.addProblem(new StaticOutsideClassProblem(site));
                }
                else if( modifier == ASModifier.ABSTRACT )
                {
                    if(currentScope.getProject().getAllowAbstractClasses())
                    {
                        currentScope.addProblem(new AbstractOutsideClassProblem(site));
                    }
                }
            }
        }

        //  Check for ambiguity.
        IDefinition def = utils.getDefinition(var);
        checkVariableForConflictingDefinitions(iNode, (VariableDefinition)def);

        checkNamespaceOfDefinition(var, def, project);
        
        /////////////////////////////////////
        // Check for a type on the variable declaration
        String type = var.getTypeName();
       
        if (type.isEmpty())     // empty string means no declaration at all (not *)
        {
            // don't check things that didn't come from source. They tend to give false negatives
            if (var.getStart() != var.getEnd())
            {
                // get a node that has the best display location for problem
                IASNode location = var;
                IExpressionNode nameExpression = var.getNameExpressionNode();
                if (nameExpression != null)
                    location = nameExpression;
                this.currentScope.addProblem( new VariableHasNoTypeDeclarationProblem(location, var.getShortName()));
            }
        }

        ExpressionNodeBase typeNode = var.getTypeNode();
        IExpressionNode currentTypeNode = typeNode;
        IDefinition vectorType = project.getBuiltinType(IASLanguageConstants.BuiltinType.VECTOR);
        while (currentTypeNode instanceof ITypedExpressionNode)
        {
            ITypedExpressionNode typedNode = (ITypedExpressionNode) currentTypeNode;
            IExpressionNode collectionNode = typedNode.getCollectionNode();
            IDefinition collectionType = collectionNode.resolve(project);
            if (!vectorType.equals(collectionType))
            {
                currentScope.addProblem(new TypeParametersWithNonParameterizedTypeProblem(collectionNode));
            }
            //keep checking while there are nested types
            currentTypeNode = typedNode.getTypeNode();
        }

        // check if thise is an assignment in this declaration.
        // If so, do checks on that
        final ExpressionNodeBase rightNode = var.getAssignedValueNode();
        if( var.isConst() && rightNode == null )
        {
            addProblem(new ConstNotInitializedProblem(var, var.getName()));
        }

        // if there is an initializer, check that the value is reasonable 
        if (rightNode != null)
        {
            checkAssignmentValue(def, rightNode);
        }

        if(SemanticUtils.isNestedClassProperty(iNode, (VariableDefinition)def))
        {
            // TODO: Issue a better, mor specific diagnostic
            // TODO: once we are allowed to add new error strings.
            addProblem(new BURMDiagnosticNotAllowedHereProblem(iNode));
        }
    }

    /**
     *  Verify that a named type exists.
     *  @param typename - the name of the type.
     */
    public void checkTypeName(Binding typename)
    {
        if ( typename.getNode() == null || typename.getName() == null )
        {
            //  Some kind of synthetic Binding, ignore.
        }
        else
        {
            IDefinition typeDef = utils.getDefinition(typename.getNode());
            if ( !SemanticUtils.isType(typeDef) )
            {
                Name name = typename.getName();
                while ( name != null && name.isTypeName() && name.getTypeNameParameter() != null )
                    name = name.getTypeNameParameter();

                if ( name != null )
                {
                    if ( !name.isTypeName() )
                    {
                        addTypeProblem(typename.getNode(), typeDef, name.getBaseName(), false);
                    }
                    else
                    {
                        //  Render as best able.
                        addTypeProblem(typename.getNode(), typeDef, name.toString(), false);
                    }
                }
            }
        }
        
        checkReference(typename);
    }

    /**
     *  Check a class field declaration.
     */
    public void checkClassField(VariableNode var)
    {
        checkVariableDeclaration(var);

        //  Check the variable's type.
        IASNode typeNode = var.getTypeNode();

        IDefinition typeDef = utils.getDefinition(typeNode);
        if ( !SemanticUtils.isType(typeDef))
        {
            IASNode problematicType = utils.getPotentiallyParameterizedType(typeNode);

            String typeDesc;

            if ( problematicType instanceof IdentifierNode )
            {
                typeDesc = ((IdentifierNode)problematicType).getName();
            }
            else
            {
                typeDesc = var.getTypeName();
            }

            addTypeProblem(problematicType, typeDef, typeDesc, true);
        }
    }

    /**
     * Add the appropriate Problem when a type annotation did not resolve to a Type
     * @param typeNode  the Node to use for location info for the problem
     * @param typeDef   The IDefinition the type annotation resolved to
     * @param typeDesc  A String to use as the description of the type annotation in the diagnostic
     * @param reportAmbiguousReference A flag indicating whether an AmbiguousReferenceProblem
     * should be reported, if the <code>typeDef</code> is ambiguous.
     */
    public void addTypeProblem (IASNode typeNode, IDefinition typeDef, String typeDesc, boolean reportAmbiguousReference)
    {
        if( AmbiguousDefinition.isAmbiguous(typeDef) )
        {
            if (reportAmbiguousReference)
                addProblem(new AmbiguousReferenceProblem(typeNode, typeDesc));
        }
        else
        {
            addProblem(new UnknownTypeProblem(typeNode, typeDesc));
        }
    }

    /**
     * Check the qualifier of a qualified name ('a' in 'a::foo')
     * @param iNode     the node representing the qualifier
     */
    public void checkQualifier(IASNode iNode)
    {
        IDefinition qualifier = utils.getDefinition(iNode);
        
        // If a qualifier is used in a context hwere it is not valid, then the qualifier will resolve
        // to the CM Implicit namespace.
        // This happens for code like:  private::foo
        // when the code is outside of a class (so there is no private).
        if( qualifier == NamespaceDefinition.getCodeModelImplicitDefinitionNamespace() )
        {
            INamespaceDecorationNode nsNode = (INamespaceDecorationNode)iNode;
            String nsString = nsNode.getName();
            if( nsString == IASKeywordConstants.PUBLIC )
            {
                addProblem(new InvalidPublicNamespaceProblem(nsNode) );
            }
            else if( nsString == IASKeywordConstants.PROTECTED )
            {
                addProblem(new InvalidProtectedNamespaceProblem(nsNode) );
            }
            else if( nsString == IASKeywordConstants.PRIVATE )
            {
                addProblem(new InvalidPrivateNamespaceProblem(nsNode));
            }
        }
        
        checkDeprecated(iNode, qualifier);
    }

    /**
     *  Check a namespace declaration.
     */
    public void checkNamespaceDeclaration(IASNode iNode, Binding ns_name)
    {
        NamespaceNode nsNode = (NamespaceNode)iNode;

        IDefinition def = utils.getDefinition(nsNode);

        checkNamespaceOfDefinition(nsNode, def, project);
        SemanticUtils.checkScopedToDefaultNamespaceProblem(currentScope, nsNode, def, null);
        
        if (SemanticUtils.isInFunction(iNode))
        {
            if (iNode instanceof BaseDefinitionNode)
                checkForNamespaceInFunction((BaseDefinitionNode)iNode, currentScope);
        }
        
        // Check whether the namespace is being initialized to a deprecated namespace.
        IExpressionNode namespaceInitialValueNode = nsNode.getNamespaceURINode();
        if (namespaceInitialValueNode != null)
        {
            IDefinition namespaceInitialvalueDefinition = namespaceInitialValueNode.resolve(project);
            checkDeprecated(namespaceInitialValueNode, namespaceInitialvalueDefinition);
        }
    }

    /**
     * Check that the namespace of the definition is valid
     */
    public void checkNamespaceOfDefinition(IASNode iNode, IDefinition def, ICompilerProject project)
    {
        INamespaceReference nsRef = def.getNamespaceReference();
        
        // If it's not a language namespace, then it is only valid if the def is declared in a class
        if( !nsRef.isLanguageNamespace() && !(def.getParent() instanceof IClassDefinition) )
        {
            // if in function, we will already generate the error that no overrides at all are allowed
            if (!SemanticUtils.isInFunction(iNode))
                addProblem(new InvalidNamespaceProblem(iNode instanceof BaseDefinitionNode ?
                                                    ((BaseDefinitionNode)iNode).getNamespaceNode() :
                                                    iNode));
        }

        if( nsRef == NamespaceDefinition.getCodeModelImplicitDefinitionNamespace()
                // constructors are left in the CMImplicit namespace so that FB continues to work right
                && !isConstructor(def) )
        {
            // This should only happen if an invalid access namespace was specified
            // e.g. private outside of a class
            BaseDefinitionNode bdn = iNode instanceof BaseDefinitionNode ? (BaseDefinitionNode)iNode : null;
            if( bdn != null )
            {
                INamespaceDecorationNode nsNode = bdn.getNamespaceNode();
                if( nsNode != null )
                {
                    String nsString = nsNode.getName();
                    if( nsString == IASKeywordConstants.PUBLIC )
                    {
                        addProblem(new InvalidPublicNamespaceAttrProblem(nsNode) );
                    }
                    else if( nsString == IASKeywordConstants.PROTECTED )
                    {
                        addProblem(new InvalidProtectedNamespaceAttrProblem(nsNode) );
                    }
                    else if( nsString == IASKeywordConstants.PRIVATE )
                    {
                        addProblem(new InvalidPrivateNamespaceAttrProblem(nsNode));
                    }
                }
            }
        }
        
        IASNode nsNode = iNode instanceof BaseDefinitionNode ?
                ((BaseDefinitionNode)iNode).getNamespaceNode() :
                iNode;

        INamespaceDefinition nsDef = nsRef.resolveNamespaceReference(project);
        
        if (nsRef.resolveNamespaceReference(project) == null)
            addProblem(new UnresolvedNamespaceProblem(nsNode));
        
        checkDeprecated(nsNode, nsDef);
    }

    private boolean isConstructor(IDefinition d)
    {
        if( d instanceof IFunctionDefinition && ((IFunctionDefinition)d).isConstructor() )
            return true;
        return false;
    }
    /**
     *  Check a Vector literal.
     */
    public void checkVectorLiteral(IASNode iNode, Binding type_param)
    {
        IDefinition type_def = type_param.getDefinition();
        IContainerNode contentsNode = ((VectorLiteralNode)iNode).getContentsNode();
        if ( type_def != null )
        {
            boolean isNumericTypeOrBoolean = SemanticUtils.isNumericTypeOrBoolean(type_def, project);
            String typeName = type_def.getBaseName();
            boolean isInt = SemanticUtils.isBuiltin(type_def, BuiltinType.INT, project);
            boolean isUint = SemanticUtils.isBuiltin(type_def, BuiltinType.UINT, project);

            for ( int i = 0; i < contentsNode.getChildCount(); i++ )
            {
                IASNode literal_element = contentsNode.getChild(i);

                if (isNumericTypeOrBoolean)
                {
                    // check for loss of precision
                    if ( literal_element instanceof NumericLiteralNode )
                    {
                        INumericLiteralNode.INumericValue numeric = ((NumericLiteralNode)literal_element).getNumericValue();
                        if ( (isInt && ( numeric.toNumber() != numeric.toInt32())) ||
                             (isUint && ( numeric.toNumber() != numeric.toUint32()))  )
                        {
                            addProblem(new LossyConversionProblem(literal_element, typeName));
                        }
                    }

                    // check for null values where they don't make sense
                    if (literal_element instanceof IExpressionNode)
                    {
                        IDefinition elementType = ((IExpressionNode)literal_element).resolveType(project);
                        boolean elementIsNull = SemanticUtils.isBuiltin(elementType, BuiltinType.NULL, project);
                        if (elementIsNull)
                        {
                            addProblem( new NullUsedWhereOtherExpectedProblem(literal_element, typeName));
                        }
                    }
                }
                checkImplicitConversion(literal_element, type_def, null);
            }
        }
        return;
    }

    /**
     *  Find at least some AS3 context for a diagnostic.
     *  @return the i-node from the problematic Binding, or the nearest
     *    known i-node if the Binding has no i-node (i.e., it's synthetic).
     */
    private IASNode roundUpUsualSuspects(Binding offender, IASNode bystander)
    {
        if (offender.getNode() != null)
            return offender.getNode();
        else
            return bystander;

    }

    /**
     *  Check a rest parameter declaration (...rest)
     *  @param iNode - the ParameterNode for the rest decl.
     *  @param param_type - the type of the rest param
     */
    public void checkRestParameter(IASNode iNode, Binding param_type)
    {
        IDefinition type = param_type.getDefinition();
        if( !utils.isBuiltin(type, BuiltinType.ARRAY) && !utils.isBuiltin(type, BuiltinType.ANY_TYPE) )
            addProblem(new InvalidRestParameterDeclarationProblem(((ParameterNode)iNode).getTypeNode()));
    }


    /**
     * Check for other definitions that might conflict with the function passed in.  This method will issue
     * a diagnostic if there are any definitions with the same name in the same declaring scope.  It will
     * not find conflicts in base classes - if a method conflicts in something in a base class some sort of
     * illegal override error will already have been issued.
     *
     * @param iNode     The Node that produced the function definition.  Used for location info for any diagnostics.
     * @param funcDef   The FunctionDefinition of the function to check
     */
    public boolean checkFunctionForConflictingDefinitions (IASNode iNode, FunctionDefinition funcDef)
    {
        boolean foundConflict = false;
        // Only have to check for dups in the current class if this is a class method
        // If a base class has a conflict some sort of illegal override error will have been generated already
        // if this is a global or nested function we don't have to check the base class as there won't be one
        switch( SemanticUtils.getMultiDefinitionType(funcDef, project))
        {
            case AMBIGUOUS:
                String namespaceName = getNamespaceStringFromDef(funcDef);
                addProblem(new ConflictingNameInNamespaceProblem(iNode, funcDef.getBaseName(), namespaceName));
                foundConflict = true;
                break;
            case NONE:
                break;
            case MULTIPLE:
                addProblem(new DuplicateFunctionDefinitionProblem(iNode, funcDef.getBaseName()));
                break;
            default:;
              assert false;     
        }
        
        // getter or setter with same name as a package gets a warning/
        // we don't return true, however, as it isn't "really" a multiple definition
        if (funcDef instanceof IAccessorDefinition)
        {
            ASScope cs = (ASScope)funcDef.getContainingScope();
            if (cs.isPackageName(funcDef.getBaseName()))
            {
                IFunctionNode funcNode = (IFunctionNode)iNode;
                IASNode funcNameNode = funcNode.getNameExpressionNode();
                addProblem(new DefinitionShadowedByPackageNameProblem(funcNameNode));
            }
        }
        return foundConflict;
    }

    /**
     * Check for other definitions that might conflict with the function passed in.  This method is for interface
     * functions, so it will check for dups in the current interface, and also look for any conflicts in base interfaces.
     *
     * @param iNode     The node that produced the function definition.  Used for location info for any diagnostics.
     * @param funcDef   The FunctionDefinition of the interface function to check
     */
    public void checkInterfaceFunctionForConflictingDefinitions (IASNode iNode, FunctionDefinition funcDef)
    {
        // Look for conflicts in this interface
        checkFunctionForConflictingDefinitions(iNode, funcDef);

        // Look for methods from base interfaces we may be overriding.
        List<IFunctionDefinition> conflicts = funcDef.resolveOverridenInterfaceFunctions(project);
        if( conflicts.size() > 0 )
        {
            for( IFunctionDefinition overriden : conflicts )
            {
            	if ((overriden instanceof SetterDefinition &&
            		funcDef instanceof GetterDefinition) ||
            		(overriden instanceof GetterDefinition &&
            		funcDef instanceof SetterDefinition))
            		continue;
                addProblem(new InterfaceMethodOverrideProblem(iNode, funcDef.getBaseName(), overriden.getParent().getBaseName()));
            }
        }

    }

    /**
     * Check for other definitions that might conflict with the variable passed in.  This method will check for conflicts
     * in the declaring scope of the variable, and if it is declared in a class it will check for conflicts in the base classes.
     *
     * @param iNode     The node that produced the variable definition.  Used for location info for any diagnostics.
     * @param varDef   The VariableDefinition of the variable to check
     */
    public void checkVariableForConflictingDefinitions( IASNode iNode, VariableDefinition varDef )
    {
        MultiDefinitionType ambiguity = SemanticUtils.getMultiDefinitionType(varDef, project);
        if (ambiguity != MultiDefinitionType.NONE)
        {
            final String varName = varDef.getBaseName();
            ICompilerProblem problem = null;
            if (ambiguity == MultiDefinitionType.AMBIGUOUS)
            {
                problem =  new ConflictingNameInNamespaceProblem(iNode, varName, getNamespaceStringFromDef(varDef));
            }
            else 
            {
                IVariableNode varNode = (IVariableNode)iNode;
                IASNode varNameNode = varNode.getNameExpressionNode();
                if (ambiguity == MultiDefinitionType.MULTIPLE)
                    problem = new DuplicateVariableDefinitionProblem(varNameNode, varName);
                else if (ambiguity == MultiDefinitionType.SHADOWS_PARAM)
                    problem = new VariableDefinitionDuplicatesParameterProblem(varNameNode, varName);
            }
            
            assert problem != null;
            if (problem != null)
                addProblem(problem);
        }

        if (!varDef.isStatic() && SemanticUtils.hasBaseClassDefinition(iNode, project))
        {
            addProblem(new ConflictingInheritedNameInNamespaceProblem(iNode, varDef.getBaseName(), getNamespaceStringFromDef(varDef) ));
        }
            
        // Now look to see if the variable name is also a package name
        ASScope cs = (ASScope)varDef.getContainingScope();
        if (cs.isPackageName(varDef.getBaseName()))
        {
            IVariableNode varNode = (IVariableNode)iNode;
            IASNode varNameNode = varNode.getNameExpressionNode();
            addProblem(new DefinitionShadowedByPackageNameProblem(varNameNode));
        }
    }

    private String getNamespaceStringFromDef (IDefinition funcDef)
    {
        String namespaceName = null;
        INamespaceDefinition n = funcDef.resolveNamespace(project);
        if (n != null)
        {
            namespaceName = n.getBaseName();
        }
        return namespaceName;
    }

    /**
     *  Signal the semantic checker that its caller is entering a constructor:
     *  initialize constructor-specific state variables.
     */
    public void enterConstructor()
    {
        assert this.superState == SuperState.Invalid: String.format("Unexpected super() tracking state %s", this.superState);
        this.superState = SuperState.Initial;
    }

    /**
     *  Signal the semantic checker that its caller is leaving a constructor:
     *  reset constructor-specific state variables.
     */
    public void leaveConstructor()
    {
        assert this.superState != SuperState.Invalid: String.format("Unexpected super() tracking state %s", this.superState);
        this.superState = SuperState.Invalid;
    }

    /**
     * Test whether the getter for the specified accessor can be inlined
     * 
     * @param accessor The accessor to test whether the getter can be inlined
     * @return true if the getter can be inlined
     */
    public boolean canGetterBeInlined(AccessorDefinition accessor)
    {
        if (accessor instanceof SetterDefinition)
            accessor = accessor.resolveCorrespondingAccessor(currentScope.getProject());

        if (accessor == null)
            return false;

        return canFunctionBeInlined(accessor);
    }

    /**
     * Test whether the setter for the specified accessor can be inlined
     * 
     * @param accessor The accessor to test whether the setter can be inlined
     * @return true if the setter can be inlined
     */
    public boolean canSetterBeInlined(AccessorDefinition accessor)
    {
        if (accessor instanceof GetterDefinition)
            accessor = accessor.resolveCorrespondingAccessor(currentScope.getProject());

        if (accessor == null)
            return false;

        return canFunctionBeInlined(accessor);
    }

    /**
     * Test whether the specified function can be inlined.  If the function
     * can't be inlined, a problem will be if the user explicity requested
     * the function be inlined, rather than the compiler trying to
     * inline it optimistically.
     * 
     * @param function The function to test whether it can be inlined
     * @return true if the function can be inlined
     */
    public boolean canFunctionBeInlined(FunctionDefinition function)
    {
        if (!currentScope.getProject().isInliningEnabled())
            return false;

        // only report a problem when a function can't be inlined if the
        // function has been explicitly marked as inline
        final boolean reportInlineProblems = function.isInline();

        // don't support inlining functions inside inlined functions
        if (currentScope.insideInlineFunction())
        {
            if (reportInlineProblems)
                currentScope.addProblem(new InlineNestedInliningNotSupportedProblem(function.getBaseName()));

            return false;
        }

        // can't inline the function if we don't have a node for it
        FunctionNode functionNode = (FunctionNode)function.getFunctionNode();
        if (functionNode == null)
        {
            if (reportInlineProblems)
                currentScope.addProblem(new InlineNoSourceProblem(function.getBaseName()));

            return false;
        }

        if (!function.inlineFunction())
        {
            if (reportInlineProblems)
                currentScope.addProblem(new InlineFunctionNotFinalStaticOrGlobalProblem(functionNode, function.getBaseName()));

            return false;
        }

        // Pass in a new collection for the compiler problems, as we don't care
        // about any problems parsing the body, as they will be reported when
        // parsing the non-inlined version of the function.
        functionNode.parseFunctionBody(new ArrayList<ICompilerProblem>());

        // If we meet all the requirements for an inlined method, parse and scan the
        // body to make sure there isn't any constructs we can't inline.
        final ScopedBlockNode functionBody = functionNode.getScopedNode();
        if (functionBodyHasNonInlineableNodes(functionBody, reportInlineProblems, function.getBaseName(), new AtomicInteger()))
        {
            functionNode.discardFunctionBody();
            return false;
        }

        return true;
    }

    /**
     * Check for any constructs we know we can't inline, or if the function is too large
     * 
     * @param n the node to test
     * @param reportInlineProblems whether or not to report inline problems
     * @param functionName the name of the function being inlined
     * @param exprCount a running count of the expressions in the body
     * @return true if the function contains un-inlineable nodes, false if
     * the function body can be inlined
     */
    public boolean functionBodyHasNonInlineableNodes(IASNode n, boolean reportInlineProblems, String functionName, AtomicInteger exprCount)
    {
        if (n == null)
            return false;

        if (n instanceof ExpressionNodeBase)
        {
            exprCount.getAndIncrement();

            if (exprCount.get() > InlineFunctionLexicalScope.MAX_EXPR_IN_BODY)
            {
                if (reportInlineProblems)
                    currentScope.addProblem(new InlineFunctionTooLargeProblem(functionName, exprCount.get(), InlineFunctionLexicalScope.MAX_EXPR_IN_BODY));

                return true;
            }
        }

        switch (n.getNodeID())
        {
            case AnonymousFunctionID:
            case CatchID:
            case FinallyID:
            case FunctionID:
            case FunctionObjectID:
            case TryID:
            case WithID:
            {
                if (reportInlineProblems)
                    currentScope.addProblem(new InlineUnsupportedNodeProblem(n, functionName));

                return true;
            }
            default:
            {
                for (int i = 0; i < n.getChildCount(); i++)
                {
                    if (functionBodyHasNonInlineableNodes(n.getChild(i), reportInlineProblems, functionName, exprCount))
                        return true;
                }
            }
        }

        return false;
    }

    /**
     * Iterate through the Instructions which are to be inlined and
     * ensure the can all be inlined.  Any Instruction which makes
     * use of the scope chain will cause the inline to fail.
     * 
     * @param insns inlined instructions
     * @param reportInlineProblems whether or not to report inline problems
     * @param functionName the name of the function being inlined
     * @return true if all instructions are OK to be inlined
     */
    public boolean functionBodyHasNonInlineableInstructions(InstructionList insns, boolean reportInlineProblems, String functionName)
    {
        // if there are no instructions in the function body, then something went wrong (bad AS)
        // doing codegen, so we can't inline this function
        if (insns.isEmpty())
            return true;

        for (Instruction insn : insns.getInstructions())
        {
            switch (insn.getOpcode())
            {
                case OP_pushwith:
                case OP_popscope:
                case OP_pushscope:
                case OP_newfunction:
                case OP_returnvoid:
                case OP_returnvalue:
                case OP_newactivation:
                case OP_newclass:
                case OP_newcatch:
                case OP_findpropstrict:
                case OP_findproperty:
                case OP_getlex:
                case OP_getscopeobject:
                case OP_getouterscope:
                {
                    if (reportInlineProblems)
                        currentScope.addProblem(new InlineUnsupportedInstructionProblem(functionName));

                    return true;
                }
            }
        }

        return false;
    }
}

