/*******************************************************************************
 * Copyright (c) 2005, 2008 IBM Corporation and others.
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     IBM Corporation - initial API and implementation
 *******************************************************************************/
package org.eclipse.wst.jsdt.core.infer;


import org.eclipse.wst.jsdt.core.ast.ASTVisitor;
import org.eclipse.wst.jsdt.core.ast.IAllocationExpression;
import org.eclipse.wst.jsdt.core.ast.IArgument;
import org.eclipse.wst.jsdt.core.ast.IAssignment;
import org.eclipse.wst.jsdt.core.ast.IExpression;
import org.eclipse.wst.jsdt.core.ast.IFunctionCall;
import org.eclipse.wst.jsdt.core.ast.IFunctionDeclaration;
import org.eclipse.wst.jsdt.core.ast.ILocalDeclaration;
import org.eclipse.wst.jsdt.core.ast.IObjectLiteral;
import org.eclipse.wst.jsdt.core.ast.IObjectLiteralField;
import org.eclipse.wst.jsdt.core.ast.IReturnStatement;
import org.eclipse.wst.jsdt.core.ast.IScriptFileDeclaration;
import org.eclipse.wst.jsdt.core.compiler.CharOperation;
import org.eclipse.wst.jsdt.internal.compiler.ast.ASTNode;
import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractMethodDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.AbstractVariableDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.AllocationExpression;
import org.eclipse.wst.jsdt.internal.compiler.ast.Argument;
import org.eclipse.wst.jsdt.internal.compiler.ast.ArrayInitializer;
import org.eclipse.wst.jsdt.internal.compiler.ast.Assignment;
import org.eclipse.wst.jsdt.internal.compiler.ast.CharLiteral;
import org.eclipse.wst.jsdt.internal.compiler.ast.CompilationUnitDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.Expression;
import org.eclipse.wst.jsdt.internal.compiler.ast.FalseLiteral;
import org.eclipse.wst.jsdt.internal.compiler.ast.FieldReference;
import org.eclipse.wst.jsdt.internal.compiler.ast.FunctionExpression;
import org.eclipse.wst.jsdt.internal.compiler.ast.Javadoc;
import org.eclipse.wst.jsdt.internal.compiler.ast.JavadocSingleNameReference;
import org.eclipse.wst.jsdt.internal.compiler.ast.LocalDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.MethodDeclaration;
import org.eclipse.wst.jsdt.internal.compiler.ast.NumberLiteral;
import org.eclipse.wst.jsdt.internal.compiler.ast.ObjectLiteral;
import org.eclipse.wst.jsdt.internal.compiler.ast.ObjectLiteralField;
import org.eclipse.wst.jsdt.internal.compiler.ast.ProgramElement;
import org.eclipse.wst.jsdt.internal.compiler.ast.SingleNameReference;
import org.eclipse.wst.jsdt.internal.compiler.ast.StringLiteral;
import org.eclipse.wst.jsdt.internal.compiler.ast.ThisReference;
import org.eclipse.wst.jsdt.internal.compiler.ast.TrueLiteral;
import org.eclipse.wst.jsdt.internal.compiler.util.HashtableOfObject;
import org.eclipse.wst.jsdt.internal.compiler.util.Util;

/**
 * 
 * The default inference engine.  This class can also be subclassed by Inferrence providors.
 * 
 * Provisional API: This class/interface is part of an interim API that is still under development and expected to 
 * change significantly before reaching stability. It is being made available at this early stage to solicit feedback 
 * from pioneering adopters on the understanding that any code that uses this API will almost certainly be broken 
 * (repeatedly) as the API evolves.
 */
public class InferEngine extends ASTVisitor {

	InferOptions inferOptions;
	CompilationUnitDeclaration compUnit;
    Context [] contexts=new Context[100];
    int contextPtr=-1;
    Context currentContext=new Context();
    protected int passNumber=1;

    boolean isTopLevelAnonymousFunction;
    int anonymousCount=0;
    
    public int appliesTo;
    
    public InferrenceProvider inferenceProvider;

	public  InferredType StringType=new InferredType(new char[]{'S','t','r','i','n','g'});
	public  InferredType NumberType=new InferredType(new char[]{'N','u','m','b','e','r'});
	public  InferredType BooleanType=new InferredType(new char[]{'B','o','o','l','e','a','n'});
	public  InferredType FunctionType=new InferredType(new char[]{'F','u','n','c','t','i','o','n'});
	public  InferredType ArrayType=new InferredType(InferredType.ARRAY_NAME);
	public  InferredType VoidType=new InferredType(new char[]{'v','o','i','d'});
	public  InferredType ObjectType=new InferredType(InferredType.OBJECT_NAME);
	public  InferredType GlobalType=new InferredType(InferredType.GLOBAL_NAME);

	
	public static HashtableOfObject WellKnownTypes=new HashtableOfObject();
	{
		WellKnownTypes.put(InferredType.OBJECT_NAME,null);
		WellKnownTypes.put(InferredType.ARRAY_NAME,null);
		WellKnownTypes.put(new char[]{'S','t','r','i','n','g'},null);
		WellKnownTypes.put(new char[]{'N','u','m','b','e','r'},null);
		WellKnownTypes.put(new char[]{'B','o','o','l','e','a','n'},null);
		WellKnownTypes.put(new char[]{'F','u','n','c','t','i','o','n'},null);
		WellKnownTypes.put(new char[]{'D','a','t','e'},null);
		WellKnownTypes.put(new char[]{'M','a','t','h'},null);
		WellKnownTypes.put(new char[]{'R','e','g','E','x','p'},null);
		WellKnownTypes.put(new char[]{'E','r','r','o','r'},null);
	}
	
	
	
	protected InferredType inferredGlobal=null;

	static final char[] CONSTRUCTOR_ID={'c','o','n','s','t','r','u','c','t','o','r'};

	public final static char[] ANONYMOUS_PREFIX = {'_','_','_'};
	public static final char[] ANONYMOUS_CLASS_ID= {'a','n','o','n','y','m','o','u','s'};

	static class Context
	{
		InferredType currentType;
		MethodDeclaration currentMethod;
		boolean isJsDocClass;
		
		private HashtableOfObject definedMembers;

		/*
		 * Parent context to provide chaining when searching
		 * for members in scope.
		 */
		private Context parent = null;

		/*
		 * Root context
		 */
		Context(){}

		/*
		 * Nested context
		 */
		Context( Context parent )
		{
			this.parent = parent;

			currentType = parent.currentType;
			currentMethod = parent.currentMethod;
			this.isJsDocClass=parent.isJsDocClass;
		}

		public Object getMember( char [] key ){

			Object value = null;
			if( definedMembers != null ){
				value = definedMembers.get( key );
			}

			//chain lookup
			if( value == null && parent != null ){
				value = parent.getMember( key );
			}

			return value;
		}

		public void addMember( char [] key, Object member ){

			if( definedMembers == null ){
				definedMembers = new HashtableOfObject();
			}

			definedMembers.put( key, member );
		}
		
		public void setCurrentType(InferredType type)
		{
			this.currentType=type;
			Context parentContext=this.parent;
			
			while (parentContext!=null && parentContext.currentMethod==this.currentMethod)
			{
				parentContext.currentType=type;
				parentContext=parentContext.parent;
			}
		}


	}

	public InferEngine(InferOptions inferOptions)
	{
		this.inferOptions=inferOptions;
	}

	public InferEngine()
	{
		this.inferOptions=new InferOptions();
	}


	public void initialize()
	{
	    this.contextPtr=-1;
	    this.currentContext=new Context();
	    this.passNumber=1;
	    this.isTopLevelAnonymousFunction=false;
	    this.anonymousCount=0;
	    this.inferredGlobal=null;

	}

	public void setCompilationUnit(CompilationUnitDeclaration compilationUnit) {
		this.compUnit = compilationUnit;
		buildDefinedMembers(compilationUnit.statements,null);
	}


	public boolean visit(IFunctionCall functionCall) {
		boolean visitChildren=handleFunctionCall(functionCall);
		if (visitChildren)
		{
			if (this.contextPtr==-1 && functionCall.getReceiver() instanceof FunctionExpression)
				this.isTopLevelAnonymousFunction=true;
		}
		return visitChildren;
	}

	public boolean visit(ILocalDeclaration localDeclaration) {

		//add as a member of the current context
		currentContext.addMember( localDeclaration.getName(), localDeclaration );

		if (localDeclaration.getJsDoc()!=null)
		{
			Javadoc javadoc = (Javadoc)localDeclaration.getJsDoc();
			createTypeIfNecessary(javadoc);
			InferredAttribute attribute = null;
			if (javadoc.memberOf!=null)
			{
				InferredType type = this.addType(javadoc.memberOf.getSimpleTypeName(),true);
				 attribute = type.addAttribute(localDeclaration.getName(), localDeclaration);
				 if (localDeclaration.getInitialization()!=null)
					 attribute.initializationStart=localDeclaration.getInitialization().sourceStart();
				attribute.type=type;
			} 

			if (javadoc.returnType!=null)
			{
			   InferredType type = this.addType(javadoc.returnType.getSimpleTypeName());
			   localDeclaration.setInferredType(type);
			   if (attribute!=null)
				   attribute.type=type;
			}
		}

		if (localDeclaration.getInferredType()==null && localDeclaration.getInitialization()!=null)
		{
			localDeclaration.setInferredType(getTypeOf(localDeclaration.getInitialization()));
		}
		return true;
	}

	private void createTypeIfNecessary(Javadoc javadoc) {
		if (javadoc.memberOf!=null)
		{
			char [][]namespace={};
			char[][] typeName = javadoc.memberOf.getTypeName();
			if (javadoc.namespace!=null)
			{
				namespace=javadoc.namespace.getTypeName();
			}
			char [] name=CharOperation.concat(
					CharOperation.concatWith(namespace, '.'),
					CharOperation.concatWith(typeName, '.'),
					'.');
			this.currentContext.currentType=addType(name);
			if (javadoc.extendsType!=null)
			{
				char[] superName = CharOperation.concatWith(javadoc.extendsType.getTypeName(),'.');
				this.currentContext.currentType.superClass=addType(superName);
			}
			this.currentContext.isJsDocClass=true;
			
		}
		
	}

	public boolean visit(IAssignment assignment) {
		pushContext();
		Expression assignmentExpression=(Expression)assignment.getExpression();
		if (handlePrototype((Assignment)assignment))
		{

		}
		else if (assignmentExpression instanceof FunctionExpression)
		{
			boolean keepVisiting= handleFunctionExpressionAssignment((Assignment) assignment);
			if (!keepVisiting)
				return false;
		}
		else if (assignmentExpression instanceof SingleNameReference  && this.currentContext.currentType !=null &&
				isThis(assignment.getLeftHandSide()))
		{
			SingleNameReference snr=(SingleNameReference)assignmentExpression;
			Object object = this.currentContext.getMember( snr.token );


			FieldReference fieldReference=(FieldReference)assignment.getLeftHandSide();
			char [] memberName = fieldReference.token;
			InferredMember member = null;

			/*
			 * this.foo = bar //bar is a function
			 */
			if( object instanceof MethodDeclaration ){

				MethodDeclaration method=(MethodDeclaration)object;
				member = this.currentContext.currentType.addMethod( memberName, method,false );

			}
			/*
			 * this.foo = bar //assume that bar is not a function and create a new attribute in teh current type
			 */
			else{

				member = this.currentContext.currentType.addAttribute( memberName, assignment );
				((InferredAttribute)member).type = getTypeOf( assignmentExpression );

			}

			//setting location
			if( member != null ){
				member.isStatic = false; //this is a not static member because it is being set on the this
				member.nameStart = fieldReference.sourceEnd - memberName.length+1;
			}
		}

		/*
		 *	foo = {};
		 */
		else if ( assignmentExpression instanceof ObjectLiteral && assignment.getLeftHandSide() instanceof SingleNameReference ){

			AbstractVariableDeclaration varDecl = getVariable( assignment.getLeftHandSide() );

			if( varDecl != null ){
				InferredType type = varDecl.inferredType;

				if( type == null ){
					//create an annonymous type based on the ObjectLiteral
					type = getTypeOf( assignmentExpression );

					varDecl.inferredType = type;

					return true;
				}
				else
					return false; //

			}

		}
		/*
		 * foo.bar = {};
		 *
		 */
		else if ( assignmentExpression instanceof ObjectLiteral && assignment.getLeftHandSide() instanceof FieldReference ){
			FieldReference fRef = (FieldReference)assignment.getLeftHandSide();

			boolean isKnownName=fRef.receiver.isThis() && isKnownType(fRef.token) && 
					(this.inferredGlobal!=null && this.inferredGlobal==this.currentContext.currentType); 
				
			 if (isKnownName || (this.inferOptions.useAssignments && passNumber == 2 ))
			{


				InferredType receiverType = getInferredType( fRef.receiver );

				if (receiverType==null && this.passNumber==2)
				  receiverType=getInferredType2(fRef.receiver );

				if( receiverType != null ){
					//check if there is an attribute already created

					InferredAttribute attr = receiverType.findAttribute( fRef.token );

					//ignore if the attribute exists and has a type
					if( !(attr != null && attr.type != null) ){

						attr = receiverType.addAttribute( fRef.token, assignment );
						attr.type = getTypeOf( assignmentExpression );

						if (isKnownName && attr.type.isAnonymous)
						{
							InferredType existingType = compUnit.findInferredType( fRef.token ) ;
							if (existingType!=null)
								attr.type=existingType;
							else
							{
								compUnit.inferredTypesHash.removeKey(attr.type.name);
								attr.type.name=fRef.token;
								compUnit.inferredTypesHash.put(fRef.token, attr.type);
							}
						}
						
						
						/*
						 * determine if static
						 *
						 * check if the receiver is a type
						 */
						char [] possibleTypeName = constructTypeName( fRef.receiver );

						if( receiverType.allStatic ||
								(possibleTypeName != null && compUnit.findInferredType( possibleTypeName ) != null ))
							attr.isStatic = true;
						else
							attr.isStatic = false;

						attr.nameStart = (int)(fRef.nameSourcePosition>>>32);

						return false; //done with this
					}

				}
			}
		}
		else if ( assignmentExpression instanceof AllocationExpression && 
				((AllocationExpression)assignmentExpression).member instanceof FunctionExpression){
				handleFunctionExpressionAssignment((Assignment)assignment);
			}
		else if ( assignmentExpression instanceof Assignment && 
				((Assignment)assignmentExpression).expression instanceof FunctionExpression){
				handleFunctionExpressionAssignment((Assignment)assignment);
			}
		else
		{
			/*
			 * foo.bar = ?  //? is not {} and not a function
			 */
			if (this.inferOptions.useAssignments)
			{
				if( assignment.getLeftHandSide() instanceof FieldReference ){
					FieldReference fRef = (FieldReference)assignment.getLeftHandSide();
					int nameStart=(int)(fRef.nameSourcePosition>>>32);

					InferredType receiverType = getInferredType( fRef.receiver );
					if (receiverType==null)
					{
					  IFunctionDeclaration function = getDefinedFunction(fRef.receiver);
					  if (function!=null)
					  {
						  char [] typeName = constructTypeName(fRef.receiver);
						  if (typeName!=null)
							  receiverType=addType(typeName);
					  }
					}
					if (receiverType==null && this.passNumber==2)
						  receiverType=getInferredType2(fRef.receiver );

					if( receiverType != null ){
						//check if there is an attribute already created

						InferredMethod method=null;
						InferredAttribute attr = receiverType.findAttribute( fRef.token );
						if (attr==null)
							 method = receiverType.findMethod(fRef.token, null);

						//ignore if the attribute exists and has a type
						if(  (method==null && attr==null) ||  (method==null && attr != null && attr.type == null) ){


//							attr.type =
							IFunctionDeclaration definedFunction=null;
							InferredType exprType = getTypeOf( assignmentExpression );
							if (exprType==null)
								 definedFunction = getDefinedFunction(assignmentExpression );

							if (definedFunction!=null)
							{
								method = receiverType.addMethod(fRef.token, definedFunction,false);
								method.nameStart=nameStart;
								method.isStatic=receiverType.allStatic;
							}
							else
							{
							  attr = receiverType.addAttribute( fRef.token, assignment );
							  attr.type=exprType;
							/*
							 * determine if static
							 *
							 * check if the receiver is a type
							 */
							  char [] possibleTypeName = constructTypeName( fRef.receiver );

							  if( receiverType.allStatic||
									  (possibleTypeName != null && compUnit.findInferredType( possibleTypeName ) != null ))
								attr.isStatic = true;
							  else
								attr.isStatic = false;

							  attr.nameStart = (int)(fRef.nameSourcePosition>>>32);
							}
							return false; //done with this
						}


					}
				}
			}
		}
		return true; // do nothing by default, keep traversing
	}

	protected InferredType getInferredType2(Expression fieldReceiver)
	{
		InferredType receiverType=null;
		AbstractVariableDeclaration var=getVariable(fieldReceiver);
		if (var!=null)
		{
			receiverType=createAnonymousType(var);
		}
		else
		{
			if (this.inferredGlobal!=null && fieldReceiver instanceof SingleNameReference)
			{
				char []name=((SingleNameReference)fieldReceiver).token;
				InferredAttribute attr=(InferredAttribute)this.inferredGlobal.attributesHash.get(name);
				if (attr!=null)
					receiverType=attr.type;
			}

		}
		return receiverType;
	}

	private InferredType createAnonymousType(AbstractVariableDeclaration var) {

		InferredType currentType = var.inferredType;

		if (currentType==null || !currentType.isAnonymous)
		{
			InferredType type=createAnonymousType(var.name, currentType);
			var.inferredType=type;
		}
		return var.inferredType;
	}

	private InferredType createAnonymousType(char[] possibleTypeName, InferredType currentType) {
		char []name;
		if (this.isKnownType(possibleTypeName))
		{
			name=possibleTypeName;
		}
		else
		{
			char[] cs = String.valueOf(this.anonymousCount++).toCharArray();
			name = CharOperation.concat(ANONYMOUS_PREFIX,possibleTypeName,cs);
		}
		InferredType type = addType(name,true);
		type.isAnonymous=true;
		if (currentType!=null)
			type.superClass=currentType;
		return type;
	}
	/*
	 * Creates an anonymous type based in the location in the document. This information is used
	 * to avoid creating duplicates because of the 2-pass nature of this engine.
	 */
	private InferredType createAnonymousType( ObjectLiteral objLit, boolean asStatic ) {

		if (objLit.inferredType!=null)
			return objLit.inferredType;
		//char[] cs = String.valueOf(this.anonymousCount2++).toCharArray();
		char [] loc = (String.valueOf( objLit.sourceStart ) + '_' + String.valueOf( objLit.sourceEnd )).toCharArray();
		char []name = CharOperation.concat( ANONYMOUS_PREFIX, ANONYMOUS_CLASS_ID, loc );

		InferredType anonType = addType(name,true);
		anonType.isAnonymous=true;
		anonType.isObjectLiteral=true;
		anonType.superClass = ObjectType;

		anonType.sourceStart = objLit.sourceStart;
		anonType.sourceEnd = objLit.sourceEnd;
		anonType.allStatic=asStatic;

		populateType( anonType, objLit ,asStatic);

		return anonType;
	}

	
	/**
	 * handle the inferrencing for an assigment whose right hand side is a function expression
	 * @param the assignment AST node
	 * @return true if handled
	 */
	protected boolean handleFunctionExpressionAssignment(Assignment assignment)
	{
		FunctionExpression functionExpression=null;
		if (assignment.expression instanceof FunctionExpression)
			functionExpression=(FunctionExpression)assignment.expression;
		else if (assignment.expression instanceof AllocationExpression)
			functionExpression=(FunctionExpression)((AllocationExpression)assignment.expression).member;
		else if (assignment.expression instanceof Assignment)
			functionExpression=(FunctionExpression)((Assignment)assignment.expression).expression;
		MethodDeclaration methodDeclaration = functionExpression.methodDeclaration;

		char [] possibleTypeName = constructTypeName( assignment.lhs );

		InferredType type = null;
		if( possibleTypeName != null )
		{
			type = compUnit.findInferredType( possibleTypeName );
			if (type==null && isPossibleClassName(possibleTypeName))
			{
				type=addType(possibleTypeName,true);
			}
			if (type==null && methodDeclaration.getJsDoc()!=null && ((Javadoc)methodDeclaration.getJsDoc()).isConstructor)
			{
				type=addType(possibleTypeName,true);
				handleJSDocConstructor(type, methodDeclaration, assignment.sourceStart);
			}
		}

		if (type!=null)	// isConstructor
		{
			if (this.inferOptions.useInitMethod)
			{
				this.currentContext.currentType=type;
				this.currentContext.currentType=type;
				type.isDefinition=true;
				InferredMethod method = type.addMethod(type.name, methodDeclaration,true);
				type.updatePositions(assignment.lhs.sourceStart, assignment.expression.sourceEnd);
				method.nameStart=assignment.lhs.sourceStart;
			}

		}
		else	// could be method
		{
			if (assignment.lhs instanceof FieldReference)
			{
				FieldReference fieldReference=(FieldReference)assignment.lhs;
				int nameStart=(int)(fieldReference.nameSourcePosition>>>32);

				InferredType receiverType = getInferredType( fieldReference.receiver );

				if( receiverType != null ){

					//check if there is a member method already created
					InferredMethod method = receiverType.findMethod( fieldReference.token, methodDeclaration );

					if( method == null ){
						//create member method if it does not exist

						method = receiverType.addMethod( fieldReference.token, methodDeclaration ,false);
						receiverType.updatePositions(assignment.sourceStart, assignment.sourceEnd); // @GINO: not sure if necessary
						method.nameStart = nameStart;
						receiverType.isDefinition=true;

						/*
						 * determine if static
						 *
						 * check if the receiver is a type
						 */
						char [] possibleInTypeName = constructTypeName( fieldReference.receiver );

						if( receiverType.allStatic ||  
								(possibleInTypeName != null && compUnit.findInferredType( possibleInTypeName ) != null) )
							method.isStatic = true;
						else
							method.isStatic = false;

						return true; //keep visiting to get return type
					}
					else
						return false; //no need to visit again

				}
				else if (this.passNumber==2)	// create anonymous class
				{
					receiverType = getInferredType2(fieldReference.receiver);
					if (receiverType!=null)
					{
						InferredMethod method = receiverType.addMethod(fieldReference.token,methodDeclaration,false);
						method.isStatic=receiverType.isAnonymous;
						method.nameStart=nameStart;
						receiverType.updatePositions(assignment.sourceStart, assignment.sourceEnd);
					}
				}
			}
			else if (assignment.lhs instanceof SingleNameReference)
			{
			}
		}
		return true;
	}
	
	
	protected boolean handlePrototype(Assignment assignment) {

		Expression lhs = assignment.lhs;
		if (lhs instanceof FieldReference) {
			FieldReference fieldReference = (FieldReference) lhs;

			/*
			 * foo.prototype = ?
			 */
			if (fieldReference.isPrototype())
			{
				/*
				 * When encountering a prototype, we are going to assume that the
				 * receiver is a type.
				 *
				 * If the type had not been inferred, it will be added at this point
				 */
				InferredType newType = null;
				char [] possibleTypeName = constructTypeName( fieldReference.receiver );
				if( possibleTypeName != null )
					newType = compUnit.findInferredType( possibleTypeName );
				else
					return true; //no type created


				//create the new type if not found
				if( newType == null ){
					newType = addType( possibleTypeName ,true);
				}

//				char[] typeName = getTypeName(fieldReference.receiver);
//				Object object = currentContext.definedMembers.get(typeName);
//
//				if (object instanceof Argument)
//					return false;
//
//				InferredType newType = addType(typeName);
//				newType.isDefinition=true;

				newType.updatePositions(assignment.sourceStart, assignment.sourceEnd);

				/*
				 * foo.prototype = new ...
				 */
				if (assignment.expression instanceof AllocationExpression)
				{
					//setting the super type
					AllocationExpression allocationExpression =(AllocationExpression)assignment.expression;

					InferredType superType = null;
					char [] possibleSuperTypeName = constructTypeName( allocationExpression.member );
					if( possibleSuperTypeName != null ){
						superType = compUnit.findInferredType( possibleSuperTypeName );

						if( superType == null )
							superType = addType( possibleSuperTypeName );

						//check if it is set already because it might be set by jsdocs
						if( newType.superClass == null )
							newType.superClass = superType;
					}

					return true;
				}
				/*
				 * foo.prototype = {...}
				 */
				else if( assignment.expression instanceof ObjectLiteral ){
					//rather than creating an anonymous type, is better just to set the members directly
					//on newType
					populateType( newType, (ObjectLiteral)assignment.expression,false );

					//check if it is set already because it might be set by jsdocs
					if( newType.superClass == null )
						newType.superClass = ObjectType;

					return true;
				}
			}
			/*
			 * foo.prototype.bar = ?
			 */
			else if ( fieldReference.receiver.isPrototype() )
			{

				FieldReference prototype = (FieldReference) fieldReference.receiver;

				InferredType newType = null;
				char[] possibleTypeName = constructTypeName( prototype.receiver );
				if( possibleTypeName != null )
					newType = compUnit.findInferredType( possibleTypeName );
				else
					return true; //no type created

				//create the new type if not found
				if( newType == null ){
					newType = addType( possibleTypeName );
					newType.isDefinition = true;
				}

//				char[] typeName = getTypeName(prototype.receiver);
//				Object receiverDef = currentContext.definedMembers.get(typeName);
//				if (receiverDef instanceof Argument)
//					return false;
//				InferredType newType = addType(typeName);
//				newType.isDefinition=true;

				newType.updatePositions(assignment.sourceStart, assignment.sourceEnd);

				//prevent Object literal based anonymous types from being created more than once
				if( passNumber == 1 && assignment.expression instanceof ObjectLiteral ){
					return false;
				}

				char[] memberName = fieldReference.token;
				int nameStart= (int)(fieldReference.nameSourcePosition >>> 32);

				InferredType typeOf = getTypeOf(assignment.expression);
				IFunctionDeclaration methodDecl=null;

				if (typeOf==null || typeOf==FunctionType)
					methodDecl=getDefinedFunction(assignment.expression);

				if (methodDecl!=null)
				{
					InferredMember method = newType.addMethod(memberName, methodDecl,false);
					method.nameStart=nameStart;
				}
				else if (!CharOperation.equals(CONSTRUCTOR_ID, memberName))
				{
					InferredAttribute attribute = newType.addAttribute(memberName, assignment);
					attribute.initializationStart=assignment.expression.sourceStart;
					attribute.nameStart=nameStart;
					if (attribute.type==null)
						attribute.type=typeOf;
				}
				return true;
			}
		}
		return false;
	}

	/**
	 * Get the function referenced by the expression
	 * 
	 * @param expression AST node
	 * @return the function or null
	 */
	protected IFunctionDeclaration getDefinedFunction(IExpression expression)
	{
		if (expression instanceof SingleNameReference)
		{
			Object object = this.currentContext.getMember( ((SingleNameReference)expression).token );
			if (object instanceof AbstractMethodDeclaration)
				return (MethodDeclaration)object;
		} else if (expression instanceof FunctionExpression)
			return ((FunctionExpression)expression).methodDeclaration;
		 else if (expression instanceof FieldReference)
		 {
			 FieldReference fieldReference=(FieldReference)expression;
			InferredType receiverType = getInferredType( fieldReference.receiver );
			if (receiverType==null && passNumber==2)
				receiverType=getInferredType2( fieldReference.receiver );
			if (receiverType!=null)
			{
				InferredMethod method = receiverType.findMethod(fieldReference.token, null);
				if (method!=null)
					return method.getFunctionDeclaration();
			}

		 }

		return null;

	}

	protected InferredType getTypeOf(IExpression expression) {
		if (expression instanceof StringLiteral || expression instanceof CharLiteral) {
			return StringType;
		}
		else if (expression instanceof NumberLiteral) {
			return NumberType;
		}
		else if (expression instanceof AllocationExpression)
		{
			AllocationExpression allocationExpression=(AllocationExpression)expression;

			InferredType type = null;
			char [] possibleTypeName = constructTypeName( allocationExpression.member );
			if( possibleTypeName != null ){
				type = compUnit.findInferredType( possibleTypeName );

				if( type == null )
					type = addType( possibleTypeName );

				return type;
			}
		}
		else if (expression instanceof SingleNameReference)
		{
			AbstractVariableDeclaration varDecl = getVariable( (SingleNameReference)expression );
			if( varDecl != null )
				return varDecl.inferredType;
			if (this.inferredGlobal!=null)
			{
				InferredAttribute attribute = this.inferredGlobal.findAttribute(((SingleNameReference)expression).token );
				if (attribute!=null)
					return attribute.type;
			}

		}
		else if (expression instanceof FieldReference)
		{
			FieldReference fieldReference=(FieldReference)expression;
			if (fieldReference.receiver.isThis() && currentContext.currentType!=null)
			{
				InferredAttribute attribute = currentContext.currentType.findAttribute(fieldReference.token);
				if (attribute!=null)
					return attribute.type;
			}
		}
		else if (expression instanceof ArrayInitializer)
		{
			ArrayInitializer arrayInitializer = (ArrayInitializer)expression;
			boolean typeSet=false;
			InferredType memberType=null;
			if (arrayInitializer.expressions!=null)
				for (int i = 0; i < arrayInitializer.expressions.length; i++) {
					InferredType thisType = getTypeOf(arrayInitializer.expressions[i]);
					if (thisType!=null)
					{
					  if (!thisType.equals(memberType))
						  if (!typeSet)
							  memberType=thisType;
						  else
							  memberType=null;
					  typeSet=true;

					}
				}
			if (memberType!=null)
			{
				InferredType type = new InferredType(InferredType.ARRAY_NAME);
				type.referenceClass=memberType;
				return type;
			}
			else
			return ArrayType;
		}	else if (expression instanceof TrueLiteral || expression instanceof FalseLiteral) {
			return BooleanType;
		}
		else if ( expression instanceof ObjectLiteral ){

			//create an annonymous type based on the ObjectLiteral
			InferredType type = createAnonymousType( (ObjectLiteral)expression,true );

			//set the start and end
			type.sourceStart = expression.sourceStart();
			type.sourceEnd = expression.sourceEnd();

			return type;


		} 	else if ( expression instanceof ThisReference ){
			return this.currentContext.currentType;
		}
		else if (expression instanceof Assignment)
			return getTypeOf(((Assignment)expression).getExpression());
		else if (expression instanceof FunctionExpression)
			return FunctionType;

		return null;
	}

	private void populateType(InferredType type, ObjectLiteral objLit, boolean isStatic) {
		if (objLit.inferredType==null) {
			objLit.inferredType=type;
			if (objLit.fields != null) {
				for (int i = 0; i < objLit.fields.length; i++) {
					ObjectLiteralField field = objLit.fields[i];

					char[] name = null;
					int nameStart = -1;

					if (field.fieldName instanceof SingleNameReference) {
						SingleNameReference singleNameReference = (SingleNameReference) field.fieldName;
						name = singleNameReference.token;
						nameStart = singleNameReference.sourceStart;
					} else
						continue; //not supporting this case right now

					Javadoc javaDoc = (Javadoc)field.getJsDoc();
					InferredType returnType=null;
					if (javaDoc!=null)
					{
						if (javaDoc.memberOf!=null)
						{
							char[] typeName = javaDoc.memberOf.getSimpleTypeName();
							convertAnonymousTypeToNamed(type,typeName);
							type.isDefinition=true;
						}
						else if (this.currentContext.isJsDocClass && javaDoc.property!=null)
						{
							if (type.isAnonymous )
							{
								InferredType previousType = this.currentContext.currentType;
								if (previousType!=null)
								{
									copyAnonymousTypeToNamed(type,previousType);
									objLit.inferredType=type=this.currentContext.currentType=previousType;
								}
									
							}
						}
						if (javaDoc.returnType!=null)
						{
							returnType=this.addType(javaDoc.returnType.getSimpleTypeName());
						}
					}
					
					//need to build the members of the annonymous inferred type
					if (field.initializer instanceof FunctionExpression) {
						FunctionExpression functionExpression = (FunctionExpression) field.initializer;
						InferredMember method = type.addMethod(name,
								functionExpression.methodDeclaration, false);
						method.nameStart = nameStart;
						method.isStatic=isStatic;
						if (javaDoc!=null)
						{
						    functionExpression.methodDeclaration.modifiers=javaDoc.modifiers;
						  handleFunctionDeclarationArguments(functionExpression.methodDeclaration,javaDoc);
						}
					    if (returnType!=null)
					    {
					    	functionExpression.methodDeclaration.inferredType=returnType;
					    }


					} else //attribute
					{
						InferredAttribute attribute = type.addAttribute(name,
								field.fieldName);
						attribute.nameStart = nameStart;
						attribute.isStatic=isStatic;
						//@GINO: recursion might not be the best idea
						if (returnType!=null)
							attribute.type=returnType;
						else
						  attribute.type = getTypeOf(field.initializer);
					}
				}
			}
		}		
	}

	public void endVisit(IAssignment assignment) {
		popContext();
	}

	protected boolean handleFunctionCall(IFunctionCall messageSend) {
		return true;
	}

	public void endVisit(IReturnStatement returnStatement) {

//			if (currentContext.currentMethod!=null)
//			{
//				if (returnStatement.getExpression()!=null)
//				{
//
//					InferredType type = getTypeOf(returnStatement.getExpression());
//
//					if (currentContext.currentMethod.inferredType==VoidType)
//						currentContext.currentMethod.inferredType=type;
//					else if (type==null || !type.equals(currentContext.currentMethod.inferredType))
//						currentContext.currentMethod.inferredType=null;
//				}
//			}

	}
	

	public boolean visit(IReturnStatement returnStatement) {

			if (currentContext.currentMethod!=null)
			{
				if (returnStatement.getExpression()!=null)
				{

					InferredType type = null;
					IExpression expression = returnStatement.getExpression();
					if (expression instanceof IObjectLiteral)
					{
						type = createAnonymousType( (ObjectLiteral)expression,false );

						//set the start and end
						type.sourceStart = expression.sourceStart();
						type.sourceEnd = expression.sourceEnd();
					}
					else 
						type=getTypeOf(expression);

					if (currentContext.currentMethod.inferredType==VoidType)
						currentContext.currentMethod.inferredType=type;
					else if (type==null || !type.equals(currentContext.currentMethod.inferredType))
						currentContext.currentMethod.inferredType=null;
				}
			}
			return false;
	}


	public void endVisit(IFunctionDeclaration methodDeclaration) {
		popContext();
	}

	public boolean visit(IFunctionDeclaration methodDeclaration) {
		pushContext();
		if (this.isTopLevelAnonymousFunction && this.currentContext.currentType==null)
		{
			this.currentContext.currentType=addType(InferredType.GLOBAL_NAME,true);
			this.inferredGlobal=this.currentContext.currentType;
		}

		this.isTopLevelAnonymousFunction=false; 
		char[] methodName = methodDeclaration.getName();
		if (passNumber==1)
		{
			buildDefinedMembers((ProgramElement[])methodDeclaration.getStatements(),(Argument[])methodDeclaration.getArguments());
			if (methodDeclaration.getJsDoc()!=null)
			{
				InferredMethod method=null;
				Javadoc javadoc = (Javadoc)methodDeclaration.getJsDoc();
				createTypeIfNecessary(javadoc);
				if (javadoc.isConstructor)
				{
					InferredType type;
					if (!this.currentContext.isJsDocClass && methodName!=null)
					  type = this.addType(methodName);
					else
						type=this.currentContext.currentType;
					if (type!=null)
						handleJSDocConstructor(type, methodDeclaration, methodDeclaration.sourceStart());
				}
				else if (javadoc.memberOf!=null)
				{
					InferredType type = this.addType(javadoc.memberOf.getSimpleTypeName(),true);
					char [] name=methodName;
					if (name!=null)
						method=type.addMethod(methodName, methodDeclaration,false);
				}
				else if (javadoc.methodDef!=null && this.currentContext.isJsDocClass)
				{
					InferredType type=this.currentContext.currentType;
					char[][] methName = javadoc.methodDef.getTypeName();
					if (methName.length==1)
						method=type.addMethod(methName[0], methodDeclaration,false);
					else
					{
						method=type.addMethod(methName[methName.length-1], methodDeclaration,false);
						method.isStatic=true;
					}
					method.nameStart=((MethodDeclaration)methodDeclaration).sourceStart;
						
				}

				if (javadoc.returnType!=null)
				{
				   InferredType type = this.addType(javadoc.returnType.getSimpleTypeName());
				   methodDeclaration.setInferredType(type);
				   ((MethodDeclaration)methodDeclaration).bits |= ASTNode.IsInferredJsDocType;
				}

			}
			if (methodDeclaration.getArguments()!=null)
				handleFunctionDeclarationArguments((MethodDeclaration)methodDeclaration,(Javadoc)methodDeclaration.getJsDoc());
		}
		// check if this is a constructor
		if (passNumber==2)
		{

			if (methodName!=null) {
				InferredType type = compUnit
						.findInferredType(methodName);
				if (type != null) {
					this.currentContext.currentType = type;
					type.isDefinition = true;
					InferredMethod method = type.addMethod(
							methodName, methodDeclaration,true);
					method.nameStart=methodDeclaration.sourceStart();
					method.isConstructor = true;
					methodDeclaration.setInferredType(type);
				}
			}
		}
		this.currentContext.currentMethod=(MethodDeclaration)methodDeclaration;
		if (methodDeclaration.getInferredMethod()!=null && methodDeclaration.getInferredMethod().inType!=null)
			this.currentContext.currentType=methodDeclaration.getInferredMethod().inType;
		if (methodDeclaration.getInferredType()==null)
			methodDeclaration.setInferredType(VoidType);
		return true;
	}
	
	protected void handleJSDocConstructor(InferredType type,IFunctionDeclaration methodDeclaration, int nameStart) {
		Javadoc javadoc = (Javadoc)methodDeclaration.getJsDoc();
		type.isDefinition=true;
		InferredMethod method = type.addMethod(type.name, methodDeclaration,true);
		method.nameStart=nameStart;
		method.isConstructor=true;

		if (javadoc.extendsType!=null)
		{
			InferredType superType=this.addType(javadoc.extendsType.getSimpleTypeName());
			type.superClass=superType;
		}
		
	}

	protected void handleFunctionDeclarationArguments(IFunctionDeclaration methodDeclaration, Javadoc javadoc) {
		if (javadoc==null)
			return;
		IArgument[] arguments = methodDeclaration.getArguments();
		if (arguments!=null)
		for (int i = 0; i < arguments.length; i++) {
			JavadocSingleNameReference param = javadoc.findParam(arguments[i].getName());
			if (param!=null)
			{
				if (param.types!=null)
				{
					
					char []name={};
					for (int j = 0; j < param.types.length; j++) {
						char []typeName=param.types[j].getSimpleTypeName();
						if (j==0)
							name=typeName;
						else
						{
							name=CharOperation.append(name, '|');
							name=CharOperation.concat(name, typeName);
						}
					}
					InferredType paramType=this.addType(name);
					arguments[i].setInferredType(paramType);
				}
			}
		}
	}



	public boolean visit(
    		IAllocationExpression allocationExpression) {

		InferredType type = null;
		char [] possibleTypeName = constructTypeName( allocationExpression.getMember() );
		if( possibleTypeName != null ){
			type = compUnit.findInferredType( possibleTypeName );

			if( type == null  )
				type = addType( possibleTypeName ); //creating type
		}
		return true;
	}


	public void endVisit(IObjectLiteralField field) {
//		if (field.getJsDoc()!=null)
//		{
//			Javadoc javaDoc = (Javadoc)field.getJsDoc();
//			InferredType inClass=this.currentContext.currentType;
//			char [] name=null;
//			int nameStart=-1;
//			InferredType returnType=null;
////			boolean isFunction=field.initializer instanceof FunctionExpression;
// 			if (field.getFieldName() instanceof SingleNameReference)
// 			{
// 				SingleNameReference singleNameReference=(SingleNameReference)field.getFieldName();
// 				name=singleNameReference.token;
// 				nameStart=singleNameReference.sourceStart;
// 			}
//			if (javaDoc.memberOf!=null)
//			{
//				char[] typeName = javaDoc.memberOf.getSimpleTypeName();
//				convertAnonymousTypeToNamed(inClass,typeName);
//				inClass.isDefinition=true;
//			}
//			else if (this.currentContext.isJsDocClass && javaDoc.property!=null)
//			{
//				if (this.currentContext.currentType.isAnonymous && this.currentContext.parent!=null)
//				{
//					InferredType previousType = this.currentContext.parent.currentType;
//					if (previousType!=null)
//					{
//						copyAnonymousTypeToNamed(inClass,previousType);
//						this.currentContext.currentType=previousType;
//					}
//						
//				}
//			}
//			if (javaDoc.returnType!=null)
//			{
//				returnType=this.addType(javaDoc.returnType.getSimpleTypeName());
//			}
//
//			if (inClass!=null && name!=null)
//			{
//				if (field.getInitializer() instanceof FunctionExpression) {
//					FunctionExpression functionExpression = (FunctionExpression) field.getInitializer();
//				    InferredMember method = inClass.addMethod(name, functionExpression.methodDeclaration,false);
//				    method.nameStart=nameStart;
//				    functionExpression.methodDeclaration.modifiers=javaDoc.modifiers;
//				    if (returnType!=null)
//				    {
//				    	functionExpression.methodDeclaration.inferredType=returnType;
//				    }
////				    else
////				    	method.inferredType=functionExpression.methodDeclaration.inferredType;
//				}
//				else	//attribute
//				{
//					InferredAttribute attribute = inClass.addAttribute(name, field.getFieldName());
//					attribute.nameStart=field.getFieldName().sourceStart();
//					if (returnType!=null)
//						attribute.type=returnType;
//				}
//			}
//
//		}
//		//no jsdoc
//		else{
//
//			if( field.getInitializer() instanceof ObjectLiteral ){
//
//			}
//
//
//		}
	}

	private void copyAnonymousTypeToNamed(InferredType inClass,
			InferredType toType) {
		compUnit.inferredTypesHash.removeKey(inClass.name);
		if (inClass.methods!=null)
		{
			if (toType!=null)
				toType.methods.addAll(inClass.methods);
			else 
				toType.methods=inClass.methods;
			
		}
		if (inClass.attributes!=null)
		{
			for (int i = 0; i < inClass.numberAttributes; i++) {
				toType.addAttribute(inClass.attributes[i]);
			}
		}
		
		
	}

	private void convertAnonymousTypeToNamed(InferredType inClass, char[] typeName) {
		if (inClass.isAnonymous)
		{
			inClass.isAnonymous=false;
			compUnit.inferredTypesHash.removeKey(inClass.name);
			inClass.name=typeName;
			compUnit.inferredTypesHash.put(typeName,inClass);

		}
	
	}

	protected boolean isMatch(IExpression expr,char[] [] names, int index)
	{
		char [] matchName=names[index];
		if (expr instanceof SingleNameReference) {
			SingleNameReference snr = (SingleNameReference) expr;
			return CharOperation.equals(snr.token, matchName);
		}
		else if (expr instanceof FieldReference && names.length>1) {
			FieldReference fieldReference = (FieldReference) expr;
			if (CharOperation.equals(fieldReference.token, matchName))
				return isMatch(fieldReference.receiver, names, index-1);

		}
		return false;
	}

	protected boolean isFunction(IFunctionCall messageSend,String string) {
		String []names=string.split("\\."); //$NON-NLS-1$
		char [] functionName=names[names.length-1].toCharArray();
		if (!CharOperation.equals(functionName, messageSend.getSelector()))
			return false;

		char [][]namesChars=new char[names.length][];
		for (int i = 0; i < namesChars.length; i++) {
			namesChars[i]=names[i].toCharArray();
		}
		if (names.length>1)
			return isMatch(messageSend.getReciever(), namesChars, namesChars.length-2);
		return true;
	}

	protected boolean isFunction(IFunctionCall messageSend,char [][]names) {
		char [] functionName=names[names.length-1];
		if (!CharOperation.equals(functionName, messageSend.getSelector()))
			return false;

		if (names.length>1)
			return isMatch(messageSend.getReciever(), names, names.length-2);
		return true;
	}


	public void doInfer()
	{
		try {
			compUnit.traverse(this );
			passNumber=2;
			compUnit.traverse(this );
			for (int i = 0; i < compUnit.numberInferredTypes; i++) {
				if (compUnit.inferredTypes[i].sourceStart<0)
					compUnit.inferredTypes[i].sourceStart=0;
			}
			this.compUnit=null;
		} catch (RuntimeException e) {
			org.eclipse.wst.jsdt.internal.core.util.Util.log(e, "error during type inferencing");
		}
}

	protected InferredType addType(char[] className) {
		return addType(className,false);
	}

	/**
	 * Create a new inferred type with the given name
	 * 
	 * @param className the name of the inferred type
	 * @param isDefinition true if this unit defines the type
	 * @return new Inferred type
	 */
	protected InferredType addType(char[] className, boolean isDefinition) {

		InferredType type = compUnit.findInferredType(className);


		if (type==null)
		{
			if (compUnit.numberInferredTypes == compUnit.inferredTypes.length)

				System.arraycopy(
						compUnit.inferredTypes,
						0,
						(compUnit.inferredTypes = new InferredType[compUnit.numberInferredTypes  * 2]),
						0,
						compUnit.numberInferredTypes );
			type=compUnit.inferredTypes[compUnit.numberInferredTypes ++] = new InferredType(className);
			type.inferenceProviderID=this.inferenceProvider.getID();
			compUnit.inferredTypesHash.put(className,type);

		}
		if (isDefinition)
			type.isDefinition=isDefinition;
		return type;
	}

	protected final void pushContext()
	{
		Context newContext = new Context( currentContext  );
		contexts[++contextPtr] = currentContext;
		currentContext = newContext;

	}

	protected final void popContext()
	{
		currentContext = contexts[contextPtr];
		contexts[contextPtr--] = null;
	}

	protected final boolean isInNamedMethod()
	{
		return this.currentContext.currentMethod!=null && this.currentContext.currentMethod.selector!=null;
	}


	/**
	 * Finds a Var Declaration on the context from the name represented with the expression
	 *
	 * Currently, only SNR are supported
	 */
	protected AbstractVariableDeclaration getVariable(IExpression expression)
	{
		char [] name=null;

		if (expression instanceof SingleNameReference)
			name=((SingleNameReference)expression).token;
		if (name!=null)
		{
			Object var = this.currentContext.getMember( name );
			if (var instanceof AbstractVariableDeclaration)
				return (AbstractVariableDeclaration)var;

		}
		return null;

	}

	private void buildDefinedMembers(ProgramElement[] statements, IArgument[] arguments) {

		if (arguments!=null)
		{
			for (int i = 0; i < arguments.length; i++) {
				this.currentContext.addMember( arguments[i].getName(), arguments[i] );
			}
		}
		if (statements!=null)
		{
			for (int i = 0; i < statements.length; i++) {
				if (statements[i] instanceof LocalDeclaration) {
					LocalDeclaration local = (LocalDeclaration) statements[i];
					this.currentContext.addMember( local.name, local );
				}
				else if (statements[i] instanceof AbstractMethodDeclaration) {
					AbstractMethodDeclaration method = (AbstractMethodDeclaration) statements[i];
					if (method.selector!=null)
						this.currentContext.addMember( method.selector, method );
				}
			}
		}
	}

	private static boolean isThis(IExpression expression)
	{
		if (expression instanceof FieldReference && ((FieldReference)expression).receiver.isThis())
			return true;
		return false;
	}

	/*
	 * This method is used to determined the inferred type of a LHS Expression.
	 *
	 * It could return null.
	 *
	 * a.b.c
	 */
	private InferredType getInferredType( Expression expression ){

		InferredType type = null;

		/*
		 * this
		 */
		if( expression instanceof ThisReference ){
			if (this.passNumber==2 && this.currentContext.currentType==null)
			{
				char [] possibleTypeName={'g','l','o','b','a','l'};
				if (this.currentContext.currentMethod!=null)
					possibleTypeName=this.currentContext.currentMethod.selector;
				this.currentContext.setCurrentType(createAnonymousType(possibleTypeName, null));
			}
			
			type = this.currentContext.currentType;
		}
		/*
		 * foo (could be a Type name or a reference to a variable)
		 */
		else if( expression instanceof SingleNameReference ){
			char [] possibleTypeName = constructTypeName( expression );

			if( possibleTypeName != null ){
				//search the defined types in the context
				type = compUnit.findInferredType( possibleTypeName );

				if (type==null)
				{
					if (WellKnownTypes.containsKey(possibleTypeName)) 
					{
						type = addType(possibleTypeName,true);
					}
					else if (/*this.passNumber==2 && */this.isKnownType(possibleTypeName))
					{
						type = addType(possibleTypeName,true);
//						if (type!=null)
//						{
//							AbstractVariableDeclaration varDecl = getVariable( (expression) );
//
//							if( varDecl != null ){
//								varDecl.inferredType=type;
//							}
//							
//						}
					}
					 
				}
				
				
				/*
				 * There is no match for a type with the name, check if the name refers to
				 * var decl and return its type
				 */
				if( type == null ){

					AbstractVariableDeclaration varDecl = getVariable( (expression) );

					if( varDecl != null ){
						type = varDecl.inferredType; //could be null
						if (type!=null && !type.isAnonymous)
							type=createAnonymousType(varDecl);
					}

				}
			}
		}
		/*
		 * foo.bar.xxx...
		 */
		else if( expression instanceof FieldReference ){
			char[] possibleTypeName = constructTypeName(expression);

			if (possibleTypeName != null)
				// search the defined types in the context
				type = compUnit.findInferredType(possibleTypeName);
			
			if (type==null && isPossibleClassName(possibleTypeName))
			{
				type = addType(possibleTypeName,true);
			}

			/*
			 * Continue the search by trying to resolve further down the name
			 * because this token of the field reference could be a member of a
			 * type or instance of a type
			 */
			if (type == null) {
				FieldReference fRef = (FieldReference) expression;

				// this
				InferredType parentType = getInferredType(fRef.receiver);

				if (parentType != null) {
					// check the members and return type
					InferredAttribute typeAttribute = parentType
							.findAttribute(fRef.token);

					if (typeAttribute != null) {
						type = typeAttribute.type;
						if (type != null && !type.isAnonymous) {
							if (possibleTypeName==null)
								possibleTypeName=typeAttribute.name;
							type = createAnonymousType(possibleTypeName, type);
							typeAttribute.type = type;
						}
					}
				}
			}
		 
		}

		return type;
	}



	protected boolean isKnownType(char[] possibleTypeName) {
		return false;
	}

	/*
	 * For SNR it returns the name
	 * For FR it construct a Qualified name separated by '.'
	 *
	 * If at any point it hits a portion of the Field reference that is
	 * not supported (such as a function call, a prototype, or this )
	 */
	protected final char [] constructTypeName( IExpression expression ){

		return Util.getTypeName( expression );
	}

	public boolean visit(IObjectLiteral literal) {
		if (this.passNumber==1 && literal.getInferredType()==null)
			createAnonymousType((ObjectLiteral)literal,true);
		pushContext();
		this.currentContext.currentType=literal.getInferredType();
		return true;
	}

	public void endVisit(IObjectLiteral literal) {
		popContext();
	}
	

	/**
	 * Overriden by client who wish to update the infer options
	 * 
	 * @param options
	 */
	public void initializeOptions(InferOptions options) {
	}
	
	protected boolean isPossibleClassName(char[]name)
	{
		return false;
	}
	
	/**
	 * Get the Script file this inferrence is being done on
	 * 
	 * @return
	 */
	public IScriptFileDeclaration getScriptFileDeclaration()
	{
		return this.compUnit;
	}
}
