void TrackCurrentFrameAndExpression (Token token)
		{
			while (frame.bracketType == '<' && !Tokens.ValidInsideTypeName[token.Kind]) {
				frame.type = FrameType.Popped;
				frame = frame.parent;
			}
			switch (token.Kind) {
			case Tokens.OpenCurlyBrace:
				frame.lastExpressionStart = Location.Empty;
				frame = new Frame (frame, '{');
				frame.parent.ResetCurlyChildType ();
				break;
			case Tokens.CloseCurlyBrace:
				while (frame.parent != null) {
					if (frame.bracketType == '{') {
						frame.type = FrameType.Popped;
						frame = frame.parent;
						break;
					} else {
						frame.type = FrameType.Popped;
						frame = frame.parent;
					}
				}
				break;
			case Tokens.OpenParenthesis:
				if (frame.lastExpressionStart.IsEmpty)
					frame.lastExpressionStart = token.Location;
				frame = new Frame (frame, '(');
				frame.parent.ResetParenthesisChildType ();
				break;
			case Tokens.OpenSquareBracket:
				frame = new Frame (frame, '[');
				frame.parent.ResetSquareBracketChildType ();
				break;
			case Tokens.CloseParenthesis:
			case Tokens.CloseSquareBracket:
				if (frame.parent != null && (frame.bracketType == '(' || frame.bracketType == '[')) {
					frame.type = FrameType.Popped;
					frame = frame.parent;
				}
				break;
			case Tokens.From:
				frame.SetContext (new ExpressionContext.LinqContext (token.Location.Line, token.Location.Column));
				break;
			case Tokens.LessThan:
				if (Tokens.ValidInsideTypeName[lastToken]) {
					frame = new Frame (frame, '<');
					if (frame.parent.InExpressionMode) {
						frame.SetContext (ExpressionContext.Default);
					} else if ((frame.parent.state == FrameState.TypeDecl || frame.parent.state == FrameState.MethodDecl || frame.parent.state == FrameState.FieldDeclAfterIdentifier) && frame.parent.context == ExpressionContext.IdentifierExpected) {
						frame.type = FrameType.TypeParameterDecl;
						frame.SetContext (ExpressionContext.TypeName);
						frame.parent.SetContext (ExpressionContext.ConstraintsStart);
					} else {
						frame.SetContext (ExpressionContext.TypeName);
					}
				}
				break;
			case Tokens.GreaterThan:
				if (frame.parent != null && frame.bracketType == '<') {
					frame.type = FrameType.Popped;
					frame = frame.parent;
				} else {
					frame.lastExpressionStart = Location.Empty;
					frame.SetDefaultContext ();
				}
				break;
			case Tokens.Question:
				// do not reset context - TrackCurrentContext will take care of this
				frame.lastExpressionStart = Location.Empty;
				break;
			case Tokens.Dot:
			case Tokens.DoubleColon:
				// let the current expression continue
				break;
			default:
				if (Tokens.IdentifierTokens[token.Kind]) {
					if (lastToken != Tokens.Dot && lastToken != Tokens.DoubleColon) {
						if (Tokens.ValidInsideTypeName[lastToken]) {
							frame.SetDefaultContext ();
						}
						frame.lastExpressionStart = token.Location;
					}
				} else if (Tokens.SimpleTypeName[token.Kind] || Tokens.ExpressionStart[token.Kind] || token.Kind == Tokens.Literal) {
					frame.lastExpressionStart = token.Location;
				} else {
					frame.lastExpressionStart = Location.Empty;
					frame.SetDefaultContext ();
				}
				break;
			}
		}
		void TrackCurrentContext (Token token)
		{
			if (frame.state == FrameState.ObjectCreation) {
				if (token.Kind == Tokens.CloseSquareBracket) {
					// handle collection initalizers new string[] { "foo" }.
					lexer.StartPeek ();
					if (!(lastToken == Tokens.OpenSquareBracket && lexer.Peek ().Kind == Tokens.OpenCurlyBrace) && frame.context.IsObjectCreation) {
						frame.SetContext (ExpressionContext.Default);
						frame.lastExpressionStart = frame.lastNewTokenStart;
					}
					// keep frame.state
				} else if (token.Kind == Tokens.CloseParenthesis || token.Kind == Tokens.CloseCurlyBrace) {
					if (frame.context.IsObjectCreation) {
						frame.SetContext (ExpressionContext.Default);
						frame.lastExpressionStart = frame.lastNewTokenStart;
					}
					// keep frame.state
				} else if (token.Kind == Tokens.GreaterThan || token.Kind == Tokens.DoubleColon || token.Kind == Tokens.Dot || Tokens.SimpleTypeName[token.Kind]) {
					// keep frame.state == FrameState.ObjectCreationInType
				} else {
					frame.state = FrameState.Normal;
					frame.ResetCurlyChildType ();
				}
			}
			
			switch (token.Kind) {
			case Tokens.Using:
				if (frame.type == FrameType.Global) {
					frame.SetContext (ExpressionContext.NamespaceNameExcepted);
					break;
				} else {
					goto case Tokens.For;
				}
			case Tokens.For:
			case Tokens.Foreach:
			case Tokens.Fixed:
			case Tokens.Catch:
				if (frame.type == FrameType.Statements) {
					frame.parenthesisChildType = FrameType.Statements;
				}
				break;
			case Tokens.Throw:
				frame.SetExpectedType (DomReturnType.Exception);
				break;
			case Tokens.New:
				if (frame.InExpressionMode) {
					frame.SetContext (ExpressionContext.TypeDerivingFrom (frame.expectedType, frame.expectedType, true));
					frame.state = FrameState.ObjectCreation;
					frame.curlyChildType = FrameType.ObjectInitializer;
					frame.lastNewTokenStart = token.Location;
				}
				break;
			case Tokens.Namespace:
				frame.SetContext (ExpressionContext.NamespaceNameExcepted);
				break;
			case Tokens.Assign:
				if (frame.type == FrameType.Global) {
					frame.SetContext (ExpressionContext.FullyQualifiedType);
					break;
				} else if (frame.type == FrameType.Enum) {
					frame.SetContext (ExpressionContext.Default);
					break;
				} else if (frame.type == FrameType.TypeDecl) {
					frame.SetContext (ExpressionContext.Default);
					frame.state = FrameState.Initializer;
					frame.ResetParenthesisChildType ();
					frame.ResetSquareBracketChildType ();
					frame.ResetCurlyChildType ();
					break;
				} else if (frame.type == FrameType.ObjectInitializer) {
					frame.state = FrameState.ObjectInitializerValue;
					frame.SetDefaultContext ();
					break;
				} else {
					goto default;
				}
			case Tokens.Colon:
				if (frame.context == ExpressionContext.NamespaceNameExcepted)
					break;
				if (frame.state == FrameState.MethodDecl && lastToken == Tokens.CloseParenthesis) {
					frame.SetContext (ExpressionContext.BaseConstructorCall);
					frame.parenthesisChildType = FrameType.Expression;
				} else {
					if (frame.curlyChildType == FrameType.TypeDecl || frame.curlyChildType == FrameType.Interface || frame.curlyChildType == FrameType.Enum) {
						if (frame.state != FrameState.Constraints) {
							frame.state = FrameState.InheritanceList;
							frame.SetDefaultContext ();
						}
					}
				}
				break;
			case Tokens.Class:
			case Tokens.Struct:
				if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
					if (frame.state != FrameState.Constraints) {
						frame.state = FrameState.TypeDecl;
						frame.curlyChildType = FrameType.TypeDecl;
						frame.SetContext (ExpressionContext.IdentifierExpected);
					}
				}
				break;
			case Tokens.Interface:
				if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
					frame.state = FrameState.TypeDecl;
					frame.curlyChildType = FrameType.Interface;
					frame.SetContext (ExpressionContext.IdentifierExpected);
				}
				break;
			case Tokens.Enum:
				if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
					frame.state = FrameState.TypeDecl;
					frame.curlyChildType = FrameType.Enum;
					frame.SetContext (ExpressionContext.IdentifierExpected);
				}
				break;
			case Tokens.Delegate:
				if (frame.InExpressionMode) {
					frame.parenthesisChildType = FrameType.ParameterList;
					frame.curlyChildType = FrameType.Statements;
				} else if (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl) {
					frame.parenthesisChildType = FrameType.ParameterList;
					frame.state = FrameState.MethodDecl;
					frame.SetContext (ExpressionContext.TypeName);
				}
				break;
			case Tokens.LambdaArrow:
				frame.curlyChildType = FrameType.Statements;
				break;
			case Tokens.Event:
				frame.SetContext (ExpressionContext.DelegateType);
				frame.curlyChildType = FrameType.Event;
				frame.state = FrameState.EventDecl;
				break;
			case Tokens.Comma:
				if (frame.bracketType == '<') {
					frame.state = FrameState.Normal;
					frame.SetDefaultContext ();
				} else if (frame.state == FrameState.FieldDecl || frame.state == FrameState.FieldDeclAfterIdentifier || frame.state == FrameState.Initializer) {
					frame.state = FrameState.FieldDecl;
					frame.SetContext (ExpressionContext.IdentifierExpected);
				} else if (frame.state == FrameState.ObjectInitializerValue) {
					frame.state = FrameState.Normal;
					frame.SetDefaultContext ();
				} else if (frame.type == FrameType.Statements) {
					frame.SetContext (ExpressionContext.IdentifierExpected);
				}
				break;
			case Tokens.Where:
				if (!frame.InExpressionMode && (frame.type == FrameType.Global || frame.type == FrameType.TypeDecl)) {
					frame.state = FrameState.Constraints;
					frame.SetDefaultContext ();
				}
				break;
			case Tokens.CloseCurlyBrace:
			case Tokens.Semicolon:
				frame.state = FrameState.Normal;
				frame.SetDefaultContext ();
				break;
			case Tokens.OpenParenthesis:
				if (frame.parent != null && (frame.parent.state == FrameState.FieldDeclAfterIdentifier || frame.parent.state == FrameState.FieldDecl)) {
					frame.type = FrameType.ParameterList;
					frame.SetContext (ExpressionContext.FirstParameterType);
					frame.parent.state = FrameState.MethodDecl;
					frame.parent.curlyChildType = FrameType.Statements;
				}
				break;
			case Tokens.Question:
				// IdentifierExpected = this is after a type name = the ? was a nullable marker
				if (frame.context != ExpressionContext.IdentifierExpected) {
					frame.SetDefaultContext ();
				}
				break;
			case Tokens.This:
				if (frame.state == FrameState.FieldDecl) {
					// this is an indexer declaration
					frame.squareBracketChildType = FrameType.ParameterList;
					frame.state = FrameState.FieldDeclAfterIdentifier;
				}
				break;
			case Tokens.Goto:
				frame.SetContext (ExpressionContext.IdentifierExpected);
				break;
			case Tokens.As:
			case Tokens.Is:
				frame.SetContext (ExpressionContext.TypeName);
				break;
			case Tokens.Typeof:
				frame.parenthesisChildType = FrameType.TypeReference;
				break;
			case Tokens.Default:
				frame.parenthesisChildType = FrameType.TypeReference;
				break;
			default:
				if (frame.context == ExpressionContext.NamespaceNameExcepted)
					break;
				if (Tokens.SimpleTypeName[token.Kind]) {
					if (frame.type == FrameType.Interface || frame.type == FrameType.TypeDecl) {
						if (frame.state == FrameState.Normal) {
							frame.state = FrameState.FieldDecl;
							frame.curlyChildType = FrameType.Property;
						} else if (frame.state == FrameState.FieldDecl && Tokens.IdentifierTokens[token.Kind]) {
							frame.state = FrameState.FieldDeclAfterIdentifier;
						}
						if (frame.state != FrameState.ObjectCreation) {
							frame.SetContext (ExpressionContext.IdentifierExpected);
						}
					} else if (frame.type == FrameType.ParameterList || frame.type == FrameType.Statements || frame.type == FrameType.Global) {
						if (!frame.context.IsObjectCreation) {
							frame.SetContext (ExpressionContext.IdentifierExpected);
						}
					}
				}
				break;
			}
		}
		void ApplyToken (Token token)
		{
			TrackCurrentFrameAndExpression (token);
			TrackCurrentContext (token);
		}