diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugFieldInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugFieldInfo.cs
index 7c305045ca..10477f7db9 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugFieldInfo.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugFieldInfo.cs
@@ -127,5 +127,9 @@ namespace Debugger.MetaData
 		{
 			return this.FieldType + " " + this.Name;
 		}
+		
+		DebugType IDebugMemberInfo.MemberType {
+			get { return (DebugType)this.FieldType; }
+		}
 	}
 }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugMethodInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugMethodInfo.cs
index 25a56c0b6d..43670c5be5 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugMethodInfo.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugMethodInfo.cs
@@ -179,7 +179,7 @@ namespace Debugger.MetaData
 		public override ParameterInfo ReturnParameter {
 			get {
 				if (this.MethodDefSig.RetType.Void) return null;
-				return new DebugParameterInfo(this, string.Empty, this.ReturnType, -1);
+				return new DebugParameterInfo(this, string.Empty, this.ReturnType, -1, delegate { throw new NotSupportedException(); });
 			}
 		}
 		
@@ -207,6 +207,15 @@ namespace Debugger.MetaData
 		
 		ParameterInfo[] parameters;
 		
+		public DebugParameterInfo GetParameter(string name)
+		{
+			foreach(DebugParameterInfo par in GetParameters()) {
+				if (par.Name == name)
+					return par;
+			}
+			return null;
+		}
+		
 		/// <inheritdoc/>
 		public override ParameterInfo[] GetParameters()
 		{
@@ -220,12 +229,14 @@ namespace Debugger.MetaData
 					} catch {
 						name = String.Empty;
 					}
+					int iCopy = i;
 					parameters[i] =
 						new DebugParameterInfo(
 							this,
 							name,
 							DebugType.CreateFromSignature(this.DebugModule, this.MethodDefSig.Parameters[i].Type, declaringType),
-							i
+							i,
+							delegate (StackFrame context) { return context.GetArgumentValue(iCopy); }
 						);
 				}
 			}
@@ -467,6 +478,15 @@ namespace Debugger.MetaData
 			}
 		}
 		
+		public DebugLocalVariableInfo GetLocalVariable(string name)
+		{
+			foreach(DebugLocalVariableInfo loc in GetLocalVariables()) {
+				if (loc.Name == name)
+					return loc;
+			}
+			return null;
+		}
+		
 		List<DebugLocalVariableInfo> localVariables;
 		
 		public List<DebugLocalVariableInfo> GetLocalVariables()
@@ -629,5 +649,9 @@ namespace Debugger.MetaData
 		{
 			return methodProps.SigBlob.Adress;
 		}
+		
+		DebugType IDebugMemberInfo.MemberType {
+			get { return (DebugType)this.ReturnType; }
+		}
 	}
 }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugParameterInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugParameterInfo.cs
index 9b527f2706..e82d6ded2d 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugParameterInfo.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugParameterInfo.cs
@@ -12,6 +12,7 @@ namespace Debugger.MetaData
 {
 	public class DebugParameterInfo : System.Reflection.ParameterInfo
 	{
+		ValueGetter getter;
 		MemberInfo member;
 		string name;
 		Type parameterType;
@@ -37,12 +38,18 @@ namespace Debugger.MetaData
 			get { return position; }
 		}
 		
-		public DebugParameterInfo(MemberInfo member, string name, Type parameterType, int position)
+		public DebugParameterInfo(MemberInfo member, string name, Type parameterType, int position, ValueGetter getter)
 		{
 			this.member = member;
 			this.name = name;
 			this.parameterType = parameterType;
 			this.position = position;
+			this.getter = getter;
+		}
+		
+		public Value GetValue(StackFrame context)
+		{
+			return getter(context);
 		}
 			
 		//		public virtual ParameterAttributes Attributes { get; }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugPropertyInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugPropertyInfo.cs
index efd4e1679c..18b823f35e 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugPropertyInfo.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugPropertyInfo.cs
@@ -193,6 +193,20 @@ namespace Debugger.MetaData
 			get { return (getMethod ?? setMethod).IsStatic; }
 		}
 		
+		DebugType IDebugMemberInfo.MemberType {
+			get { return (DebugType)this.PropertyType; }
+		}
+		
+		ParameterInfo[] IOverloadable.GetParameters()
+		{
+			return GetIndexParameters();
+		}
+		
+		IntPtr IOverloadable.GetSignarture()
+		{
+			return ((IOverloadable)(getMethod ?? setMethod)).GetSignarture();
+		}
+		
 		/// <inheritdoc/>
 		public override string ToString()
 		{
@@ -215,15 +229,5 @@ namespace Debugger.MetaData
 			}
 			return sb.ToString();
 		}
-		
-		ParameterInfo[] IOverloadable.GetParameters()
-		{
-			return GetIndexParameters();
-		}
-		
-		IntPtr IOverloadable.GetSignarture()
-		{
-			return ((IOverloadable)(getMethod ?? setMethod)).GetSignarture();
-		}
 	}
 }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugType.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugType.cs
index ce22eb17c9..669fdf9fc4 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugType.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/DebugType.cs
@@ -31,6 +31,7 @@ namespace Debugger.MetaData
 	{
 		public const BindingFlags BindingFlagsAll = BindingFlags.FlattenHierarchy | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
 		public const BindingFlags BindingFlagsAllDeclared = BindingFlags.DeclaredOnly | BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
+		public const BindingFlags BindingFlagsAllInScope = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
 		
 		Module module;
 		ICorDebugType corType;
@@ -286,9 +287,11 @@ namespace Debugger.MetaData
 			// Filter by name
 			IEnumerable<List<MemberInfo>> searchScope;
 			if (name != null) {
-				if (!membersByName.ContainsKey(name))
-					return new T[] {};
-				searchScope = new List<MemberInfo>[] { membersByName[name] };
+				if (membersByName.ContainsKey(name)) {
+					searchScope = new List<MemberInfo>[] { membersByName[name] };
+				} else {
+					searchScope = new List<MemberInfo>[] { };
+				}
 			} else {
 				searchScope = membersByName.Values;
 			}
@@ -326,8 +329,11 @@ namespace Debugger.MetaData
 					// Do not include static types
 					bindingFlags = bindingFlags & ~BindingFlags.Static;
 				}
-				T[] superResults = ((DebugType)this.BaseType).GetMembers<T>(name, bindingFlags, filter);
-				results.AddRange(superResults);
+				// Any flags left?
+				if ((bindingFlags & (BindingFlags.Instance | BindingFlags.Static)) != 0) {
+					T[] superResults = ((DebugType)this.BaseType).GetMembers<T>(name, bindingFlags, filter);
+					results.AddRange(superResults);
+				}
 			}
 			
 			return results.ToArray();
@@ -590,15 +596,18 @@ namespace Debugger.MetaData
 		
 		public MemberInfo[] GetFieldsAndNonIndexedProperties(BindingFlags bindingAttr)
 		{
-			return GetMembers<MemberInfo>(null, bindingAttr, delegate (MemberInfo info) {
-			                              	if (info is FieldInfo)
-			                              		return true;
-			                              	if (info is PropertyInfo) {
-			                              		return ((PropertyInfo)info).GetGetMethod(true) != null &&
-			                              		       ((PropertyInfo)info).GetGetMethod(true).GetParameters().Length == 0;
-			                              	}
-			                              	return false;
-			                              });
+			return GetMembers<MemberInfo>(null, bindingAttr, IsFieldOrNonIndexedProperty);
+		}
+		
+		public static bool IsFieldOrNonIndexedProperty(MemberInfo info)
+		{
+			if (info is FieldInfo)
+				return true;
+			if (info is PropertyInfo) {
+				return ((PropertyInfo)info).GetGetMethod(true) != null &&
+				       ((PropertyInfo)info).GetGetMethod(true).GetParameters().Length == 0;
+			}
+			return false;
 		}
 		
 		public PropertyInfo[] GetProperties(string name, BindingFlags bindingAttr)
@@ -1241,10 +1250,43 @@ namespace Debugger.MetaData
 			membersByToken[member.MetadataToken] = member;
 		}
 		
+		public override bool Equals(object o)
+		{
+			DebugType other = o as DebugType;
+			if (other == null)
+				return false;
+			return this.MetadataToken == other.MetadataToken && // Performance optimization
+			       this.DebugModule == other.DebugModule &&
+			       this.FullName == other.FullName;
+		}
+		
+		public override int GetHashCode()
+		{
+			return this.FullName.GetHashCode();
+		}
+		
+		public static bool operator == (DebugType a, DebugType b)
+		{
+			if ((object)a == (object)b)
+				return true;
+			if (((object)a == null) || ((object)b == null))
+				return false;
+			return a.Equals(b);
+		}
+		
+		public static bool operator != (DebugType a, DebugType b)
+		{
+			return !(a == b);
+		}
+		
 		/// <inheritdoc/>
 		public override string ToString()
 		{
 			return this.FullName;
 		}
+		
+		DebugType IDebugMemberInfo.MemberType {
+			get { return null; }
+		}
 	}
 }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/IDebugMemberInfo.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/IDebugMemberInfo.cs
index a715e4893a..72d19f46ab 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/IDebugMemberInfo.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/MetaData/IDebugMemberInfo.cs
@@ -19,5 +19,6 @@ namespace Debugger.MetaData
 		bool IsAssembly { get; }
 		bool IsFamily { get; }
 		bool IsPrivate { get; }
+		DebugType MemberType { get; }
 	}
 }
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/NRefactory/Visitors/ExpressionEvaluator.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/NRefactory/Visitors/ExpressionEvaluator.cs
index 4b8acb6c47..2ae9f96dd9 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/NRefactory/Visitors/ExpressionEvaluator.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/NRefactory/Visitors/ExpressionEvaluator.cs
@@ -22,6 +22,30 @@ namespace ICSharpCode.NRefactory.Visitors
 		public EvaluateException(INode code, string msgFmt, params object[] msgArgs):base(code, string.Format(msgFmt, msgArgs)) {}
 	}
 	
+	class TypedValue
+	{
+		Value value;
+		DebugType type;
+		
+		public Value Value {
+			get { return value; }
+		}
+		
+		public DebugType Type {
+			get { return type; }
+		}
+		
+		public object PrimitiveValue {
+			get { return value.PrimitiveValue; }
+		}
+		
+		public TypedValue(Value value, DebugType type)
+		{
+			this.value = value;
+			this.type = type;
+		}
+	}
+	
 	public class ExpressionEvaluator: NotImplementedAstVisitor
 	{
 		const BindingFlags BindingFlagsAll = BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static | BindingFlags.Instance;
@@ -64,7 +88,7 @@ namespace ICSharpCode.NRefactory.Visitors
 			if (context == null) throw new ArgumentNullException("context");
 			if (context.IsInvalid) throw new DebuggerException("The context is no longer valid");
 			
-			return new ExpressionEvaluator(context).Evaluate(code, false);
+			return new ExpressionEvaluator(context).Evaluate(code, false).Value;
 		}
 		
 		/// <summary>
@@ -127,28 +151,27 @@ namespace ICSharpCode.NRefactory.Visitors
 			}
 		}
 		
-		Value Evaluate(INode expression)
+		TypedValue Evaluate(INode expression)
 		{
 			return Evaluate(expression, true);
 		}
 		
-		Value Evaluate(INode expression, bool permRef)
+		TypedValue Evaluate(INode expression, bool permRef)
 		{
 			// Try to get the value from cache
 			// (the cache is cleared when the process is resumed)
-			Value val;
+			TypedValue val;
 			if (context.Process.CachedExpressions.TryGetValue(expression, out val)) {
-				if (val == null || !val.IsInvalid) {
+				if (val == null || !val.Value.IsInvalid)
 					return val;
-				}
 			}
 			
 			System.Diagnostics.Stopwatch watch = new System.Diagnostics.Stopwatch();
 			watch.Start();
 			try {
-				val = (Value)expression.AcceptVisitor(this, null);
+				val = (TypedValue)expression.AcceptVisitor(this, null);
 				if (val != null && permRef)
-					val = val.GetPermanentReference();
+					val = new TypedValue(val.Value.GetPermanentReference(), val.Type);
 			} catch (GetValueException e) {
 				e.Expression = expression;
 				throw;
@@ -159,7 +182,7 @@ namespace ICSharpCode.NRefactory.Visitors
 				context.Process.TraceMessage("Evaluated: {0} in {1} ms total", expression.PrettyPrint(), watch.ElapsedMilliseconds);
 			}
 			
-			if (val != null && val.IsInvalid)
+			if (val != null && val.Value.IsInvalid)
 				throw new DebuggerException("Expression \"" + expression.PrettyPrint() + "\" is invalid right after evaluation");
 			
 			// Add the result to cache
@@ -179,7 +202,25 @@ namespace ICSharpCode.NRefactory.Visitors
 			this.context = context;
 		}
 		
-		public DebugType GetDebugType(INode expr)
+		Value[] GetValues(List<TypedValue> typedVals)
+		{
+			List<Value> vals = new List<Value>(typedVals.Count);
+			foreach(TypedValue typedVal in typedVals) {
+				vals.Add(typedVal.Value);
+			}
+			return vals.ToArray();
+		}
+		
+		DebugType[] GetTypes(List<TypedValue> typedVals)
+		{
+			List<DebugType> types = new List<DebugType>(typedVals.Count);
+			foreach(TypedValue typedVal in typedVals) {
+				types.Add(typedVal.Type);
+			}
+			return types.ToArray();
+		}
+		
+		DebugType GetDebugType(INode expr)
 		{
 			if (expr is ParenthesizedExpression) {
 				return GetDebugType(((ParenthesizedExpression)expr).Expression);
@@ -190,6 +231,12 @@ namespace ICSharpCode.NRefactory.Visitors
 			}
 		}
 		
+		TypedValue CreateValue(object primitiveValue)
+		{
+			Value val = Eval.CreateValue(context.AppDomain, primitiveValue);
+			return new TypedValue(val, val.Type);
+		}
+		
 		public override object VisitAssignmentExpression(AssignmentExpression assignmentExpression, object data)
 		{
 			BinaryOperatorType op;
@@ -211,7 +258,7 @@ namespace ICSharpCode.NRefactory.Visitors
 				default: throw new GetValueException("Unknown operator " + assignmentExpression.Op);
 			}
 			
-			Value right;
+			TypedValue right;
 			if (op == BinaryOperatorType.None) {
 				right = Evaluate(assignmentExpression.Right);
 			} else {
@@ -223,16 +270,16 @@ namespace ICSharpCode.NRefactory.Visitors
 			}
 			
 			// We can not have perfRef because we need to be able to set the value
-			Value left = (Value)assignmentExpression.Left.AcceptVisitor(this, null);
+			TypedValue left = (TypedValue)assignmentExpression.Left.AcceptVisitor(this, null);
 			
 			if (left == null) {
 				// Can this happen?
 				throw new GetValueException(string.Format("\"{0}\" can not be set", assignmentExpression.Left.PrettyPrint()));
 			}
-			if (!left.IsReference && left.Type.FullName != right.Type.FullName) {
+			if (!left.Value.IsReference && left.Type.FullName != right.Type.FullName) {
 				throw new GetValueException(string.Format("Type {0} expected, {1} seen", left.Type.FullName, right.Type.FullName));
 			}
-			left.SetValue(right);
+			left.Value.SetValue(right.Value);
 			return right;
 		}
 		
@@ -257,7 +304,12 @@ namespace ICSharpCode.NRefactory.Visitors
 		
 		public override object VisitCastExpression(CastExpression castExpression, object data)
 		{
-			return Evaluate(castExpression.Expression);
+			TypedValue val = Evaluate(castExpression.Expression);
+			DebugType castTo = castExpression.CastTo.ResolveType(context.AppDomain);
+			if (!castTo.IsAssignableFrom(val.Value.Type))
+				throw new GetValueException("Can not cast {0} to {1}", val.Value.Type.FullName, castTo.FullName);
+			// TODO: Primitive values
+			return new TypedValue(val.Value, castTo);
 		}
 		
 		public override object VisitIdentifierExpression(IdentifierExpression identifierExpression, object data)
@@ -266,91 +318,93 @@ namespace ICSharpCode.NRefactory.Visitors
 			
 			if (identifier == "__exception") {
 				if (context.Thread.CurrentException != null) {
-					return context.Thread.CurrentException.Value;
+					return new TypedValue(
+						context.Thread.CurrentException.Value,
+						DebugType.CreateFromType(context.AppDomain.Mscorlib, typeof(System.Exception))
+					);
 				} else {
 					throw new GetValueException("No current exception");
 				}
 			}
 			
-			Value arg = context.GetArgumentValue(identifier);
-			if (arg != null) return arg;
+			DebugParameterInfo par = context.MethodInfo.GetParameter(identifier);
+			if (par != null)
+				return new TypedValue(par.GetValue(context), (DebugType)par.ParameterType);
 			
-			Value local = context.GetLocalVariableValue(identifier);
-			if (local != null) return local;
+			DebugLocalVariableInfo loc = context.MethodInfo.GetLocalVariable(identifier);
+			if (loc != null)
+				return new TypedValue(loc.GetValue(context), (DebugType)loc.LocalType);
 			
 			// Instance class members
-			Value thisValue = GetThisValue();
+			// Note that the method might be generated instance method that represents anonymous method
+			TypedValue thisValue = GetThisValue();
 			if (thisValue != null) {
-				Value member = thisValue.GetMemberValue(identifier);
-				if (member != null) return member;
+				IDebugMemberInfo instMember = (IDebugMemberInfo)thisValue.Type.GetMember<MemberInfo>(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, DebugType.IsFieldOrNonIndexedProperty);
+				if (instMember != null)
+					return new TypedValue(Value.GetMemberValue(thisValue.Value, (MemberInfo)instMember), instMember.MemberType);
 			}
 			
 			// Static class members
-			IDebugMemberInfo memberInfo = 
-				(IDebugMemberInfo)context.MethodInfo.DeclaringType.GetField(identifier) ??
-				(IDebugMemberInfo)context.MethodInfo.DeclaringType.GetProperty(identifier);
-			if (memberInfo != null && memberInfo.IsStatic) {
-				return Value.GetMemberValue(null, (MemberInfo)memberInfo, null);
-			}
+			// TODO: Static members in outter class
+			IDebugMemberInfo statMember = (IDebugMemberInfo)((DebugType)context.MethodInfo.DeclaringType).GetMember<MemberInfo>(identifier, BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Static, DebugType.IsFieldOrNonIndexedProperty);
+			if (statMember != null)
+				return new TypedValue(Value.GetMemberValue(null, (MemberInfo)statMember), statMember.MemberType);
 			
 			throw new GetValueException("Identifier \"" + identifier + "\" not found in this context");
 		}
 		
 		public override object VisitIndexerExpression(IndexerExpression indexerExpression, object data)
 		{
-			List<Value> indexes = new List<Value>();
+			TypedValue target = Evaluate(indexerExpression.TargetObject);
+			
+			List<TypedValue> indexes = new List<TypedValue>();
 			foreach(Expression indexExpr in indexerExpression.Indexes) {
-				Value indexValue = Evaluate(indexExpr);
-				indexes.Add(indexValue);
+				indexes.Add(Evaluate(indexExpr));
 			}
 			
-			Value target = Evaluate(indexerExpression.TargetObject);
-			
 			if (target.Type.IsArray) {
 				List<int> intIndexes = new List<int>();
-				foreach(Value index in indexes) {
-					if (!index.Type.IsInteger) throw new GetValueException("Integer expected for indexer");
+				foreach(TypedValue index in indexes) {
+					if (!index.Type.IsInteger)
+						throw new GetValueException("Integer expected for indexer");
 					intIndexes.Add((int)index.PrimitiveValue);
 				}
-				return target.GetArrayElement(intIndexes.ToArray());
+				return new TypedValue(
+					target.Value.GetArrayElement(intIndexes.ToArray()),
+					(DebugType)target.Type.GetElementType()
+				);
 			}
 			
-			if (target.Type.IsPrimitive && target.PrimitiveValue is string) {
+			if (target.Type.FullName == typeof(string).FullName) {
 				if (indexes.Count == 1 && indexes[0].Type.IsInteger) {
 					int index = (int)indexes[0].PrimitiveValue;
-					return Eval.CreateValue(context.AppDomain, ((string)target.PrimitiveValue)[index]);
+					return CreateValue(((string)target.PrimitiveValue)[index]);
 				} else {
 					throw new GetValueException("Expected single integer index");
 				}
 			}
 			
-			Type[] indexerTypes = GetTypes(indexerExpression.Indexes);
-			DebugPropertyInfo pi = (DebugPropertyInfo)target.Type.GetProperty("Item", indexerTypes);
-			if (pi == null) throw new GetValueException("The object does not have an indexer property");
-			return target.GetPropertyValue(pi, indexes.ToArray());
-		}
-		
-		Type[] GetTypes(List<Expression> args)
-		{
-			List<DebugType> argTypes = new List<DebugType>();
-			foreach(Expression arg in args) {
-				DebugType argType = GetDebugType(arg) ?? Evaluate(arg).Type;
-				argTypes.Add(argType);
-			}
-			return argTypes.ToArray();
+			DebugPropertyInfo pi = (DebugPropertyInfo)target.Type.GetProperty("Item", GetTypes(indexes));
+			if (pi == null)
+				throw new GetValueException("The object does not have an indexer property");
+			return new TypedValue(
+				target.Value.GetPropertyValue(pi, GetValues(indexes)),
+				(DebugType)pi.PropertyType
+			);
 		}
 		
 		public override object VisitInvocationExpression(InvocationExpression invocationExpression, object data)
 		{
-			Value target;
+			TypedValue target;
 			DebugType targetType;
 			string methodName;
 			MemberReferenceExpression memberRef = invocationExpression.TargetObject as MemberReferenceExpression;
 			if (memberRef != null) {
+				// TODO: Optimize
 				try {
 					// Instance
 					target = Evaluate(memberRef.TargetObject);
-					targetType = GetDebugType(memberRef.TargetObject) ?? target.Type;
+					targetType = target.Type;
 				} catch (GetValueException) {
 					// Static
 					target = null;
@@ -369,43 +423,42 @@ namespace ICSharpCode.NRefactory.Visitors
 					throw new GetValueException("Member reference expected for method invocation");
 				}
 			}
-			Type[] argTypes = GetTypes(invocationExpression.Arguments);
-			MethodInfo method = targetType.GetMethod(methodName, BindingFlagsAll, null, argTypes, null);
-			if (method == null)
-				throw new GetValueException("Method " + methodName + " not found");
-			List<Value> args = new List<Value>();
+			List<TypedValue> args = new List<TypedValue>();
 			foreach(Expression expr in invocationExpression.Arguments) {
 				args.Add(Evaluate(expr));
 			}
-			return Value.InvokeMethod(target, method, args.ToArray());
+			MethodInfo method = targetType.GetMethod(methodName, DebugType.BindingFlagsAllInScope, null, GetTypes(args), null);
+			if (method == null)
+				throw new GetValueException("Method " + methodName + " not found");
+			Value retVal = Value.InvokeMethod(target != null ? target.Value : null, method, GetValues(args));
+			if (retVal == null)
+				return null;
+			return new TypedValue(retVal, (DebugType)method.ReturnType);
 		}
 		
 		public override object VisitObjectCreateExpression(ObjectCreateExpression objectCreateExpression, object data)
 		{
-			List<Expression> constructorParameters = objectCreateExpression.Parameters;
-			DebugType[] constructorParameterTypes = new DebugType[constructorParameters.Count];
-			for (int i = 0; i < constructorParameters.Count; i++) {
-				constructorParameterTypes[i] = GetDebugType(constructorParameters[i]);
-			}
-			Value[] constructorParameterValues = new Value[constructorParameters.Count];
-			for (int i = 0; i < constructorParameters.Count; i++) {
-				constructorParameterValues[i] = Evaluate(constructorParameters[i]);
-			}
-			return Eval.NewObject(
-				objectCreateExpression.CreateType.ResolveType(context.AppDomain),
-				constructorParameterValues,
-				constructorParameterTypes
+			List<TypedValue> ctorArgs = new List<TypedValue>(objectCreateExpression.Parameters.Count);
+			foreach(Expression argExpr in objectCreateExpression.Parameters) {
+				ctorArgs.Add(Evaluate(argExpr));
+			}
+			// TODO: Use reflection
+			// TODO: Arrays
+			DebugType type = objectCreateExpression.CreateType.ResolveType(context.AppDomain);
+			return new TypedValue(
+				Eval.NewObject((DebugType)type, GetValues(ctorArgs), GetTypes(ctorArgs)),
+				type
 			);
 		}
 		
 		public override object VisitMemberReferenceExpression(MemberReferenceExpression memberReferenceExpression, object data)
 		{
-			Value target;
+			TypedValue target;
 			DebugType targetType;
 			try {
 				// Instance
 				target = Evaluate(memberReferenceExpression.TargetObject);
-				targetType = GetDebugType(memberReferenceExpression.TargetObject) ?? target.Type;
+				targetType = target.Type;
 			} catch (GetValueException) {
 				// Static
 				target = null;
@@ -413,13 +466,13 @@ namespace ICSharpCode.NRefactory.Visitors
 				if (targetType == null)
 					throw;
 			}
-			MemberInfo[] memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAllDeclared);
-			if (memberInfos.Length == 0)
-				memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, BindingFlagsAll);
+			MemberInfo[] memberInfos = targetType.GetMember(memberReferenceExpression.MemberName, DebugType.BindingFlagsAllInScope);
 			if (memberInfos.Length == 0)
 				throw new GetValueException("Member \"" + memberReferenceExpression.MemberName + "\" not found");
-			Value member = Value.GetMemberValue(target, memberInfos[0]);
-			return member;
+			return new TypedValue(
+				Value.GetMemberValue(target != null ? target.Value : null, memberInfos[0]),
+				((IDebugMemberInfo)memberInfos[0]).MemberType
+			);
 		}
 		
 		public override object VisitParenthesizedExpression(ParenthesizedExpression parenthesizedExpression, object data)
@@ -429,38 +482,41 @@ namespace ICSharpCode.NRefactory.Visitors
 		
 		public override object VisitPrimitiveExpression(PrimitiveExpression primitiveExpression, object data)
 		{
-			return Eval.CreateValue(context.AppDomain, primitiveExpression.Value);
+			return CreateValue(primitiveExpression.Value);
 		}
 		
-		Value GetThisValue()
+		TypedValue GetThisValue()
 		{
 			// This is needed so that captured 'this' is supported
 			foreach(DebugLocalVariableInfo locVar in context.MethodInfo.GetLocalVariables()) {
 				if (locVar.IsThis)
-					return locVar.GetValue(context);
+					return new TypedValue(locVar.GetValue(context), (DebugType)locVar.LocalType);
 			}
 			return null;
 		}
 		
 		public override object VisitThisReferenceExpression(ThisReferenceExpression thisReferenceExpression, object data)
 		{
-			Value thisValue = GetThisValue();
+			TypedValue thisValue = GetThisValue();
 			if (thisValue == null)
-				throw new GetValueException(context.MethodInfo.FullName + " does not have \"this\"");
+				throw new GetValueException(context.MethodInfo.FullName + " is static method and does not have \"this\"");
 			return thisValue;
 		}
 		
 		public override object VisitUnaryOperatorExpression(UnaryOperatorExpression unaryOperatorExpression, object data)
 		{
-			Value value = Evaluate(unaryOperatorExpression.Expression);
+			TypedValue value = Evaluate(unaryOperatorExpression.Expression);
 			UnaryOperatorType op = unaryOperatorExpression.Op;
 			
 			if (op == UnaryOperatorType.Dereference) {
-				if (!value.Type.IsPointer) throw new GetValueException("Target object is not a pointer");
-				return value.Dereference(); // TODO: Test
+				if (!value.Type.IsPointer)
+					throw new GetValueException("Target object is not a pointer");
+				// TODO: Test
+				return new TypedValue(value.Value.Dereference(), (DebugType)value.Type.GetElementType());
 			}
 			
-			if (!value.Type.IsPrimitive) throw new GetValueException("Primitive value expected");
+			if (!value.Type.IsPrimitive)
+				throw new GetValueException("Primitive value expected");
 			
 			object val = value.PrimitiveValue;
 			
@@ -507,34 +563,36 @@ namespace ICSharpCode.NRefactory.Visitors
 				}
 			}
 			
-			if (result == null) throw new GetValueException("Unsuppored unary expression " + op);
+			if (result == null)
+				throw new GetValueException("Unsuppored unary expression " + op);
 			
-			return Eval.CreateValue(context.AppDomain, result);
+			return CreateValue(result);
 		}
 		
 		public override object VisitBinaryOperatorExpression(BinaryOperatorExpression binaryOperatorExpression, object data)
 		{
-			Value left = Evaluate(binaryOperatorExpression.Left);
-			Value right = Evaluate(binaryOperatorExpression.Right);
+			TypedValue left = Evaluate(binaryOperatorExpression.Left);
+			TypedValue right = Evaluate(binaryOperatorExpression.Right);
 			
 			object result = VisitBinaryOperatorExpressionInternal(left, right, binaryOperatorExpression.Op);
 			// Conver long to int if possible
-			if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue) result = (int)(long)result;
-			return Eval.CreateValue(context.AppDomain, result);
+			if (result is long && int.MinValue <= (long)result && (long)result <= int.MaxValue)
+				result = (int)(long)result;
+			return CreateValue(result);
 		}
 		
-		public object VisitBinaryOperatorExpressionInternal(Value leftValue, Value rightValue, BinaryOperatorType op)
+		object VisitBinaryOperatorExpressionInternal(TypedValue leftValue, TypedValue rightValue, BinaryOperatorType op)
 		{
 			object left = leftValue.Type.IsPrimitive ? leftValue.PrimitiveValue : null;
 			object right = rightValue.Type.IsPrimitive ? rightValue.PrimitiveValue : null;
 			
 			// Both are classes - do reference comparison
 			if (left == null && right == null) {
-				if (leftValue.IsNull || rightValue.IsNull) {
-					return leftValue.IsNull && rightValue.IsNull;
+				if (leftValue.Value.IsNull || rightValue.Value.IsNull) {
+					return leftValue.Value.IsNull && rightValue.Value.IsNull;
 				} else {
 					// TODO: Make sure this works for byrefs and arrays
-					return leftValue.Address == rightValue.Address;
+					return leftValue.Value.Address == rightValue.Value.Address;
 				}
 			}
 			
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Process.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Process.cs
index a6e984c208..b4ba197847 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Process.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Process.cs
@@ -5,9 +5,10 @@
 //     <version>$Revision$</version>
 // </file>
 
-using Debugger.Internal;
+using ICSharpCode.NRefactory.Visitors;
 using System;
 using System.Collections.Generic;
+using Debugger.Internal;
 using Debugger.Interop.CorDebug;
 using ICSharpCode.NRefactory.Ast;
 
@@ -214,7 +215,7 @@ namespace Debugger
 		
 		internal bool TerminateCommandIssued = false;
 		internal Queue<Breakpoint> BreakpointHitEventQueue = new Queue<Breakpoint>();
-		internal Dictionary<INode, Value> CachedExpressions = new Dictionary<INode, Value>();
+		internal Dictionary<INode, TypedValue> CachedExpressions = new Dictionary<INode, TypedValue>();
 		
 		#region Events
 		
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/StackFrame.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/StackFrame.cs
index 9d0e8641df..f26cca5def 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/StackFrame.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/StackFrame.cs
@@ -314,12 +314,10 @@ namespace Debugger
 		/// <returns> Null if not found </returns>
 		public Value GetArgumentValue(string name)
 		{
-			for(int i = 0; i < this.ArgumentCount; i++) {
-				if (this.MethodInfo.GetParameters()[i].Name == name) {
-					return GetArgumentValue(i);
-				}
-			}
-			return null;
+			DebugParameterInfo par = this.MethodInfo.GetParameter(name);
+			if (par == null)
+				return null;
+			return GetArgumentValue(par.Position);
 		}
 		
 		/// <summary> Gets argument with a given index </summary>
@@ -360,12 +358,10 @@ namespace Debugger
 		/// <returns> Null if not found </returns>
 		public Value GetLocalVariableValue(string name)
 		{
-			foreach(DebugLocalVariableInfo locVar in this.MethodInfo.GetLocalVariables()) {
-				if (locVar.Name == name) {
-					return locVar.GetValue(this);
-				}
-			}
-			return null;
+			DebugLocalVariableInfo loc = this.MethodInfo.GetLocalVariable(name);
+			if (loc == null)
+				return null;
+			return loc.GetValue(this);
 		}
 		
 		public override bool Equals(object obj)
diff --git a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Value.cs b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Value.cs
index 674d866fb2..8b3f5fdf37 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Value.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Core/Project/Src/Value.cs
@@ -381,6 +381,16 @@ namespace Debugger
 		
 		#region Convenience overload methods
 		
+		/// <summary> Get a field or property of an object with a given name. </summary>
+		/// <returns> Null if not found </returns>
+		public Value GetMemberValue(string name)
+		{
+			MemberInfo memberInfo = this.Type.GetMember<MemberInfo>(name, DebugType.BindingFlagsAllInScope, DebugType.IsFieldOrNonIndexedProperty);
+			if (memberInfo == null)
+				return null;
+			return GetMemberValue(memberInfo);
+		}
+		
 		/// <summary> Get the value of given member. </summary>
 		public Value GetMemberValue(MemberInfo memberInfo, params Value[] arguments)
 		{
@@ -600,26 +610,6 @@ namespace Debugger
 			);
 		}
 		
-		/// <summary> Get a field or property of an object with a given name. </summary>
-		/// <returns> Null if not found </returns>
-		public Value GetMemberValue(string name)
-		{
-			DebugType currentType = this.Type;
-			while (currentType != null) {
-				MemberInfo memberInfo = currentType.GetMember<MemberInfo>(name, DebugType.BindingFlagsAll, null);
-				if (memberInfo != null) {
-					if (memberInfo is DebugFieldInfo) {
-						return this.GetFieldValue((DebugFieldInfo)memberInfo);
-					}
-					if (memberInfo is DebugPropertyInfo) {
-						return this.GetPropertyValue((DebugPropertyInfo)memberInfo);
-					}
-				}
-				currentType = (DebugType)currentType.BaseType;
-			}
-			return null;
-		}
-		
 		#endregion
 		
 		public override string ToString()
diff --git a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/Tests/ExpressionEvaluator_Tests.cs b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/Tests/ExpressionEvaluator_Tests.cs
index e828940e03..96d2717bcf 100644
--- a/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/Tests/ExpressionEvaluator_Tests.cs
+++ b/src/AddIns/Misc/Debugger/Debugger.Tests/Project/Src/Tests/ExpressionEvaluator_Tests.cs
@@ -262,6 +262,14 @@ namespace Debugger.Tests {
 				}
 			}
 			
+			// Type equality
+			
+			DebugLocalVariableInfo loc = process.SelectedStackFrame.MethodInfo.GetLocalVariable("list");
+			Type locType = loc.LocalType;
+			Type valType = loc.GetValue(process.SelectedStackFrame).Type;
+			ObjectDump("TypesIdentitcal", object.ReferenceEquals(locType, valType));
+			ObjectDump("TypesEqual", locType == valType);
+			
 			EndTest();
 		}
 		
@@ -379,6 +387,8 @@ namespace Debugger.Tests {
     <Eval> </Eval>
     <TypeResulution> typeof(System.Int32*[][,]) = System.Int32*[,][] (ok)</TypeResulution>
     <TypeResulution> typeof(Debugger.Tests.ExpressionEvaluator_Tests.A&lt;System.Int32&gt;.B.C&lt;System.Char&gt;[][,]) = Debugger.Tests.ExpressionEvaluator_Tests+A`1+B+C`1[System.Int32,System.Char][,][] (ok)</TypeResulution>
+    <TypesIdentitcal>False</TypesIdentitcal>
+    <TypesEqual>True</TypesEqual>
     <ProcessExited />
   </Test>
 </DebuggerTests>