public StackFrame(int id, string name, Source source, int line, int column = 0, int? endLine = null, int? endColumn = null)
		{
			this.id = id;
			this.name = name;
			this.source = source;
			this.line = line;
			this.column = column;
			this.endLine = endLine;
			this.endColumn = endColumn;
		}
		public override void StackTrace(Response response, Table args)
		{
			int maxLevels = getInt(args, "levels", 10);
			//int threadReference = getInt(args, "threadId", 0);

			var stackFrames = new List<StackFrame>();

			var stack = m_Debug.GetWatches(WatchType.CallStack);

			var coroutine = m_Debug.GetWatches(WatchType.Threads).LastOrDefault();

			int level = 0;
			int max = Math.Min(maxLevels - 3, stack.Count);

			while (level < max)
			{
				WatchItem frame = stack[level];

				string name = frame.Name;
				SourceRef sourceRef = frame.Location ?? DefaultSourceRef;
				int sourceIdx = sourceRef.SourceIdx;
				string path = sourceRef.IsClrLocation ? "(native)" : (m_Debug.GetSourceFile(sourceIdx) ?? "???");
				string sourceName = Path.GetFileName(path);

				var source = new Source(sourceName, path); // ConvertDebuggerPathToClient(path));

				stackFrames.Add(new StackFrame(level, name, source,
					ConvertDebuggerLineToClient(sourceRef.FromLine), sourceRef.FromChar,
					ConvertDebuggerLineToClient(sourceRef.ToLine), sourceRef.ToChar));

				level++;
			}

			if (stack.Count > maxLevels - 3)
				stackFrames.Add(new StackFrame(level++, "(...)", null, 0));

			if (coroutine != null)
				stackFrames.Add(new StackFrame(level++, "(" + coroutine.Name + ")", null, 0));
			else
				stackFrames.Add(new StackFrame(level++, "(main coroutine)", null, 0));

			stackFrames.Add(new StackFrame(level++, "(native)", null, 0));

			SendResponse(response, new StackTraceResponseBody(stackFrames));
		}