internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame frame)
		{
			// TODO: Fix remaining.
			uint address = 0;
			//string typeFQN;
			//string typeFullName;
			string addressSpace = "";
			string file = "";
			int line = 0;
			int column = 0;
			string method = "";
			string lang = "";
			string module = "";
			string type = "";
			bool hasDebugInfo = false;
			bool hidden = false;
			bool external = true;

			if (frame.FrameType == CorFrameType.ILFrame) {
				if (frame.Function != null) {
					module = frame.Function.Module.Name;
					CorMetadataImport importer = new CorMetadataImport (frame.Function.Module);
					MethodInfo mi = importer.GetMethodInfo (frame.Function.Token);
					method = mi.DeclaringType.FullName + "." + mi.Name;
					type = mi.DeclaringType.FullName;
					addressSpace = mi.Name;
					ISymbolReader reader = session.GetReaderForModule (frame.Function.Module.Name);
					if (reader != null) {
						ISymbolMethod met = reader.GetMethod (new SymbolToken (frame.Function.Token));
						if (met != null) {
							CorDebugMappingResult mappingResult;
							frame.GetIP (out address, out mappingResult);
							SequencePoint prevSp = null;
							foreach (SequencePoint sp in met.GetSequencePoints ()) {
								if (sp.Offset > address)
									break;
								prevSp = sp;
							}
							if (prevSp != null) {
								line = prevSp.Line;
								column = prevSp.Offset;
								file = prevSp.Document.URL;
								address = (uint)prevSp.Offset;
							}
						}
					}
					// FIXME: Still steps into.
					//hidden = mi.GetCustomAttributes (true).Any (v => v is System.Diagnostics.DebuggerHiddenAttribute);
				}
				lang = "Managed";
				hasDebugInfo = true;
			}
			else if (frame.FrameType == CorFrameType.NativeFrame) {
				frame.GetNativeIP (out address);
				method = "<Unknown>";
				lang = "Native";
			}
			else if (frame.FrameType == CorFrameType.InternalFrame) {
				switch (frame.InternalFrameType) {
					case CorDebugInternalFrameType.STUBFRAME_M2U: method = "[Managed to Native Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_U2M: method = "[Native to Managed Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: method = "[Lightweight Method Call]"; break;
					case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: method = "[Application Domain Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break;
				}
			}

			if (method == null)
				method = "<Unknown>";

			var loc = new SourceLocation (method, file, line, column);
			return new StackFrame ((long) address, addressSpace, loc, lang, external, hasDebugInfo, hidden, null, null);
		}
		internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame frame)
		{
			uint address = 0;
			string file = "";
			int line = 0;
			string method = "";
			string lang = "";
			string module = "";
			string type = "";

			if (frame.FrameType == CorFrameType.ILFrame) {
				if (frame.Function != null) {
					module = frame.Function.Module.Name;
					CorMetadataImport importer = new CorMetadataImport (frame.Function.Module);
					MethodInfo mi = importer.GetMethodInfo (frame.Function.Token);
					method = mi.DeclaringType.FullName + "." + mi.Name;
					type = mi.DeclaringType.FullName;
					ISymbolReader reader = session.GetReaderForModule (frame.Function.Module.Name);
					if (reader != null) {
						ISymbolMethod met = reader.GetMethod (new SymbolToken (frame.Function.Token));
						if (met != null) {
							uint offset;
							CorDebugMappingResult mappingResult;
							frame.GetIP (out offset, out mappingResult);
							SequencePoint prevSp = null;
							foreach (SequencePoint sp in met.GetSequencePoints ()) {
								if (sp.Offset > offset)
									break;
								prevSp = sp;
							}
							if (prevSp != null) {
								line = prevSp.Line;
								file = prevSp.Document.URL;
							}
						}
					}
				}
				lang = "Managed";
			}
			else if (frame.FrameType == CorFrameType.NativeFrame) {
				frame.GetNativeIP (out address);
				method = "<Unknown>";
				lang = "Native";
			}
			else if (frame.FrameType == CorFrameType.InternalFrame) {
				switch (frame.InternalFrameType) {
					case CorDebugInternalFrameType.STUBFRAME_M2U: method = "[Managed to Native Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_U2M: method = "[Native to Managed Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION: method = "[Lightweight Method Call]"; break;
					case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION: method = "[Application Domain Transition]"; break;
					case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL: method = "[Function Evaluation]"; break;
				}
			}
			if (method == null)
				method = "<Unknown>";
			var loc = new SourceLocation (method, file, line);
			return new StackFrame ((long) address, loc, lang);
		}
		internal static StackFrame CreateFrame (CorDebuggerSession session, CorFrame frame)
		{
			// TODO: Fix remaining.
			uint address = 0;
			//string typeFQN;
			//string typeFullName;
			string addressSpace = "";
			string file = "";
			int line = 0;
			int endLine = 0;
			int column = 0;
			int endColumn = 0;
			string method = "";
			string lang = "";
			string module = "";
			string type = "";
			bool hasDebugInfo = false;
			bool hidden = false;
			bool external = true;

			if (frame.FrameType == CorFrameType.ILFrame) {
				if (frame.Function != null) {
					module = frame.Function.Module.Name;
					CorMetadataImport importer = new CorMetadataImport (frame.Function.Module);
					MethodInfo mi = importer.GetMethodInfo (frame.Function.Token);
					method = mi.DeclaringType.FullName + "." + mi.Name;
					type = mi.DeclaringType.FullName;
					addressSpace = mi.Name;
					
					var sp = GetSequencePoint (session, frame);
					if (sp != null) {
						line = sp.StartLine;
						column = sp.StartColumn;
						endLine = sp.EndLine;
						endColumn = sp.EndColumn;
						file = sp.Document.URL;
						address = (uint)sp.Offset;
					}

					if (session.IsExternalCode (file)) {
						external = true;
					} else {
						if (session.Options.ProjectAssembliesOnly) {
							external = mi.GetCustomAttributes (true).Any (v => 
								v is System.Diagnostics.DebuggerHiddenAttribute ||
							v is System.Diagnostics.DebuggerNonUserCodeAttribute);
						} else {
							external = mi.GetCustomAttributes (true).Any (v => 
								v is System.Diagnostics.DebuggerHiddenAttribute);
						}
					}
					hidden = mi.GetCustomAttributes (true).Any (v => v is System.Diagnostics.DebuggerHiddenAttribute);
				}
				lang = "Managed";
				hasDebugInfo = true;
			} else if (frame.FrameType == CorFrameType.NativeFrame) {
				frame.GetNativeIP (out address);
				method = "<Unknown>";
				lang = "Native";
			} else if (frame.FrameType == CorFrameType.InternalFrame) {
				switch (frame.InternalFrameType) {
				case CorDebugInternalFrameType.STUBFRAME_M2U:
					method = "[Managed to Native Transition]";
					break;
				case CorDebugInternalFrameType.STUBFRAME_U2M:
					method = "[Native to Managed Transition]";
					break;
				case CorDebugInternalFrameType.STUBFRAME_LIGHTWEIGHT_FUNCTION:
					method = "[Lightweight Method Call]";
					break;
				case CorDebugInternalFrameType.STUBFRAME_APPDOMAIN_TRANSITION:
					method = "[Application Domain Transition]";
					break;
				case CorDebugInternalFrameType.STUBFRAME_FUNC_EVAL:
					method = "[Function Evaluation]";
					break;
				}
			}

			if (method == null)
				method = "<Unknown>";

			var loc = new SourceLocation (method, file, line, column, endLine, endColumn);
			return new StackFrame ((long)address, addressSpace, loc, lang, external, hasDebugInfo, hidden, null, null);
		}