/*
 *
 *  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.definitions.AmbiguousDefinition;
import org.apache.royale.compiler.internal.definitions.VariableDefinition;
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.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.as.codegen.ABCGeneratingReducer;
import org.apache.royale.compiler.internal.as.codegen.Binding;
import org.apache.royale.compiler.internal.as.codegen.InlineFunctionLexicalScope;
import org.apache.royale.compiler.internal.as.codegen.LexicalScope;
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));
            }
        }
    }


    /**
     *  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 && 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 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;
    }
}

