/*
 *
 *  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.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.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;

            IDefinition def = func.getDefinition();

            if ( !( def.hasModifier(ASModifier.NATIVE ) || def.hasModifier(ASModifier.DYNAMIC) || func.isConstructor() ) )
            {
                if ( !func.hasBody() )
                {
                    addProblem(new FunctionWithoutBodyProblem(SemanticUtils.getFunctionProblemNode(func)));
                }
            }
        }
    }

    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)
            {
            	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 )
            {
                // pass
            }
            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;
                }
            }
        }
    }

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

        if ( class_binding.isLocal() )
        {
            //  No checking required.
        }
        else 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;

            IFunctionDefinition ctor = class_def.getConstructor();

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

            IFunctionDefinition.FunctionClassification func_type = func_def.getFunctionClassification();

            if ( func_type.equals(IFunctionDefinition.FunctionClassification.CLASS_MEMBER) || func_type.equals(IFunctionDefinition.FunctionClassification.INTERFACE_MEMBER) )
            {
                addProblem(new MethodCannotBeConstructorProblem(
                    roundUpUsualSuspects(class_binding, iNode)
                ));
            }
        }

        checkReference(class_binding);
    }

    /**
     *  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, 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, 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();
        
        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));
                }
            }
        }

        //  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()));
            }
        }

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

