Add a GetTypes() method to VirtualMachine to search for types with a given name in...
[mono.git] / mcs / class / Mono.Debugger.Soft / Mono.Debugger.Soft / Connection.cs
1 using System;
2 using System.IO;
3 using System.Net;
4 using System.Net.Sockets;
5 using System.Threading;
6 using System.Collections.Generic;
7 using System.Text;
8 using System.Diagnostics;
9 using Mono.Cecil.Metadata;
10
11 namespace Mono.Debugger.Soft
12 {
13         public class VersionInfo {
14                 public string VMVersion {
15                         get; set;
16                 }
17
18                 public int MajorVersion {
19                         get; set;
20                 }
21
22                 public int MinorVersion {
23                         get; set;
24                 }
25
26                 /*
27                  * Check that this version is at least major:minor
28                  */
29                 public bool AtLeast (int major, int minor) {
30                         if ((MajorVersion > major) || ((MajorVersion == major && MinorVersion >= minor)))
31                                 return true;
32                         else
33                                 return false;
34                 }
35         }
36
37         class DebugInfo {
38                 public int max_il_offset;
39                 public string filename;
40                 public int[] il_offsets;
41                 public int[] line_numbers;
42         }
43
44         struct FrameInfo {
45                 public long id;
46                 public long method;
47                 public int il_offset;
48                 public StackFrameFlags flags;
49         }
50
51         class TypeInfo {
52                 public string ns, name, full_name;
53                 public long assembly, module, base_type, element_type;
54                 public int token, rank, attributes;
55                 public bool is_byref, is_pointer, is_primitive, is_valuetype, is_enum;
56                 public long[] nested;
57         }
58
59         class MethodInfo {
60                 public int attributes, iattributes, token;
61         }
62
63         class MethodBodyInfo {
64                 public byte[] il;
65         }
66
67         struct ParamInfo {
68                 public int call_conv;
69                 public int param_count;
70                 public int generic_param_count;
71                 public long ret_type;
72                 public long[] param_types;
73                 public string[] param_names;
74         }
75
76         struct LocalsInfo {
77                 public long[] types;
78                 public string[] names;
79                 public int[] live_range_start;
80                 public int[] live_range_end;
81         }
82
83         struct PropInfo {
84                 public long id;
85                 public string name;
86                 public long get_method, set_method;
87                 public int attrs;
88         }
89
90         class CattrNamedArgInfo {
91                 public bool is_property;
92                 public long id;
93                 public ValueImpl value;
94         }
95
96         class CattrInfo {
97                 public long ctor_id;
98                 public ValueImpl[] ctor_args;
99                 public CattrNamedArgInfo[] named_args;
100         }
101
102         class ThreadInfo {
103                 public bool is_thread_pool;
104         }
105
106         struct ObjectRefInfo {
107                 public long type_id;
108                 public long domain_id;
109         }
110
111         enum ValueTypeId {
112                 VALUE_TYPE_ID_NULL = 0xf0,
113                 VALUE_TYPE_ID_TYPE = 0xf1
114         }
115
116         enum InvokeFlags {
117                 NONE = 0x0,
118                 DISABLE_BREAKPOINTS = 0x1,
119                 SINGLE_THREADED = 0x2
120         }
121
122         enum ElementType {
123                 End              = 0x00,
124                 Void            = 0x01,
125                 Boolean  = 0x02,
126                 Char            = 0x03,
127                 I1                = 0x04,
128                 U1                = 0x05,
129                 I2                = 0x06,
130                 U2                = 0x07,
131                 I4                = 0x08,
132                 U4                = 0x09,
133                 I8                = 0x0a,
134                 U8                = 0x0b,
135                 R4                = 0x0c,
136                 R8                = 0x0d,
137                 String    = 0x0e,
138                 Ptr              = 0x0f,
139                 ByRef      = 0x10,
140                 ValueType   = 0x11,
141                 Class      = 0x12,
142                 Var        = 0x13,
143                 Array      = 0x14,
144                 GenericInst = 0x15,
145                 TypedByRef  = 0x16,
146                 I                  = 0x18,
147                 U                  = 0x19,
148                 FnPtr      = 0x1b,
149                 Object    = 0x1c,
150                 SzArray  = 0x1d,
151                 MVar       = 0x1e,
152                 CModReqD        = 0x1f,
153                 CModOpt  = 0x20,
154                 Internal        = 0x21,
155                 Modifier        = 0x40,
156                 Sentinel        = 0x41,
157                 Pinned    = 0x45,
158
159                 Type            = 0x50,
160                 Boxed      = 0x51,
161                 Enum            = 0x55
162         }
163
164         class ValueImpl {
165                 public ElementType Type; /* or one of the VALUE_TYPE_ID constants */
166                 public long Objid;
167                 public object Value;
168                 public long Klass; // For ElementType.ValueType
169                 public ValueImpl[] Fields; // for ElementType.ValueType
170                 public bool IsEnum; // For ElementType.ValueType
171                 public long Id; /* For VALUE_TYPE_ID_TYPE */
172         }
173
174         class ModuleInfo {
175                 public string Name, ScopeName, FQName, Guid;
176                 public long Assembly;
177         }               
178
179         enum TokenType {
180                 STRING = 0,
181                 TYPE = 1,
182                 FIELD = 2,
183                 METHOD = 3,
184                 UNKNOWN = 4
185         }
186
187         enum StackFrameFlags {
188                 DEBUGGER_INVOKE = 1
189         }
190
191         class ResolvedToken {
192                 public TokenType Type;
193                 public string Str;
194                 public long Id;
195         }
196
197         class Modifier {
198         }
199
200         class CountModifier : Modifier {
201                 public int Count {
202                         get; set;
203                 }
204         }
205
206         class LocationModifier : Modifier {
207                 public long Method {
208                         get; set;
209                 }
210
211                 public long Location {
212                         get; set;
213                 }
214         }
215
216         class StepModifier : Modifier {
217                 public long Thread {
218                         get; set;
219                 }
220
221                 public int Depth {
222                         get; set;
223                 }
224
225                 public int Size {
226                         get; set;
227                 }
228         }
229
230         class ThreadModifier : Modifier {
231                 public long Thread {
232                         get; set;
233                 }
234         }
235
236         class ExceptionModifier : Modifier {
237                 public long Type {
238                         get; set;
239                 }
240                 public bool Caught {
241                         get; set;
242                 }
243                 public bool Uncaught {
244                         get; set;
245                 }
246         }
247
248         class AssemblyModifier : Modifier {
249                 public long[] Assemblies {
250                         get; set;
251                 }
252         }
253
254         class SourceFileModifier : Modifier {
255                 public string[] SourceFiles {
256                         get; set;
257                 }
258         }
259
260         class EventInfo {
261                 public EventType EventType {
262                         get; set;
263                 }
264
265                 public int ReqId {
266                         get; set;
267                 }
268
269                 public SuspendPolicy SuspendPolicy {
270                         get; set;
271                 }
272
273                 public long ThreadId {
274                         get; set;
275                 }
276
277                 public long Id {
278                         get; set;
279                 }
280
281                 public long Location {
282                         get; set;
283                 }
284
285                 public int Level {
286                         get; set;
287                 }
288
289                 public string Category {
290                         get; set;
291                 }
292
293                 public string Message {
294                         get; set;
295                 }
296
297                 public EventInfo (EventType type, int req_id) {
298                         EventType = type;
299                         ReqId = req_id;
300                 }
301         }
302
303         public enum ErrorCode {
304                 NONE = 0,
305                 INVALID_OBJECT = 20,
306                 INVALID_FIELDID = 25,
307                 INVALID_FRAMEID = 30,
308                 NOT_IMPLEMENTED = 100,
309                 NOT_SUSPENDED = 101,
310                 INVALID_ARGUMENT = 102,
311                 ERR_UNLOADED = 103,
312                 ERR_NO_INVOCATION = 104,
313                 ABSENT_INFORMATION = 105,
314                 NO_SEQ_POINT_AT_IL_OFFSET = 106
315         }
316
317         public class ErrorHandlerEventArgs : EventArgs {
318
319                 public ErrorCode ErrorCode {
320                         get; set;
321                 }
322         }
323
324         /*
325          * Represents the connection to the debuggee
326          */
327         public abstract class Connection
328         {
329                 /*
330                  * The protocol and the packet format is based on JDWP, the differences 
331                  * are in the set of supported events, and the commands.
332                  */
333                 internal const string HANDSHAKE_STRING = "DWP-Handshake";
334
335                 internal const int HEADER_LENGTH = 11;
336
337                 static readonly bool EnableConnectionLogging = !String.IsNullOrEmpty (Environment.GetEnvironmentVariable ("MONO_SDB_LOG"));
338                 static int ConnectionId;
339                 readonly StreamWriter LoggingStream = EnableConnectionLogging ? 
340                         new StreamWriter (string.Format ("/tmp/sdb_conn_log_{0}", ConnectionId++), false) : null;
341
342                 /*
343                  * Th version of the wire-protocol implemented by the library. The library
344                  * and the debuggee can communicate if they implement the same major version.
345                  * If they implement a different minor version, they can communicate, but some
346                  * features might not be available. This allows older clients to communicate
347                  * with newer runtimes, and vice versa.
348                  */
349                 internal const int MAJOR_VERSION = 2;
350                 internal const int MINOR_VERSION = 9;
351
352                 enum WPSuspendPolicy {
353                         NONE = 0,
354                         EVENT_THREAD = 1,
355                         ALL = 2
356                 }
357
358                 enum CommandSet {
359                         VM = 1,
360                         OBJECT_REF = 9,
361                         STRING_REF = 10,
362                         THREAD = 11,
363                         ARRAY_REF = 13,
364                         EVENT_REQUEST = 15,
365                         STACK_FRAME = 16,
366                         APPDOMAIN = 20,
367                         ASSEMBLY = 21,
368                         METHOD = 22,
369                         TYPE = 23,
370                         MODULE = 24,
371                         EVENT = 64
372                 }
373
374                 enum EventKind {
375                         VM_START = 0,
376                         VM_DEATH = 1,
377                         THREAD_START = 2,
378                         THREAD_DEATH = 3,
379                         APPDOMAIN_CREATE = 4, // Not in JDI
380                         APPDOMAIN_UNLOAD = 5, // Not in JDI
381                         METHOD_ENTRY = 6,
382                         METHOD_EXIT = 7,
383                         ASSEMBLY_LOAD = 8,
384                         ASSEMBLY_UNLOAD = 9,
385                         BREAKPOINT = 10,
386                         STEP = 11,
387                         TYPE_LOAD = 12,
388                         EXCEPTION = 13,
389                         KEEPALIVE = 14,
390                         USER_BREAK = 15,
391                         USER_LOG = 16
392                 }
393
394                 enum ModifierKind {
395                         COUNT = 1,
396                         THREAD_ONLY = 3,
397                         LOCATION_ONLY = 7,
398                         EXCEPTION_ONLY = 8,
399                         STEP = 10,
400                         ASSEMBLY_ONLY = 11,
401                         SOURCE_FILE_ONLY = 12
402                 }
403
404                 enum CmdVM {
405                         VERSION = 1,
406                         ALL_THREADS = 2,
407                         SUSPEND = 3,
408                         RESUME = 4,
409                         EXIT = 5,
410                         DISPOSE = 6,
411                         INVOKE_METHOD = 7,
412                         SET_PROTOCOL_VERSION = 8,
413                         ABORT_INVOKE = 9,
414                         SET_KEEPALIVE = 10,
415                         GET_TYPES_FOR_SOURCE_FILE = 11,
416                         GET_TYPES = 12
417                 }
418
419                 enum CmdEvent {
420                         COMPOSITE = 100
421                 }
422
423                 enum CmdThread {
424                         GET_FRAME_INFO = 1,
425                         GET_NAME = 2,
426                         GET_STATE = 3,
427                         GET_INFO = 4,
428                         /* FIXME: Merge into GET_INFO when the major protocol version is increased */
429                         GET_ID = 5,
430                         /* Ditto */
431                         GET_TID = 6
432                 }
433
434                 enum CmdEventRequest {
435                         SET = 1,
436                         CLEAR = 2,
437                         CLEAR_ALL_BREAKPOINTS = 3
438                 }
439
440                 enum CmdAppDomain {
441                         GET_ROOT_DOMAIN = 1,
442                         GET_FRIENDLY_NAME = 2,
443                         GET_ASSEMBLIES = 3,
444                         GET_ENTRY_ASSEMBLY = 4,
445                         CREATE_STRING = 5,
446                         GET_CORLIB = 6,
447                         CREATE_BOXED_VALUE = 7
448                 }
449
450                 enum CmdAssembly {
451                         GET_LOCATION = 1,
452                         GET_ENTRY_POINT = 2,
453                         GET_MANIFEST_MODULE = 3,
454                         GET_OBJECT = 4,
455                         GET_TYPE = 5,
456                         GET_NAME = 6
457                 }
458
459                 enum CmdModule {
460                         GET_INFO = 1,
461                 }
462
463                 enum CmdMethod {
464                         GET_NAME = 1,
465                         GET_DECLARING_TYPE = 2,
466                         GET_DEBUG_INFO = 3,
467                         GET_PARAM_INFO = 4,
468                         GET_LOCALS_INFO = 5,
469                         GET_INFO = 6,
470                         GET_BODY = 7,
471                         RESOLVE_TOKEN = 8
472                 }
473
474                 enum CmdType {
475                         GET_INFO = 1,
476                         GET_METHODS = 2,
477                         GET_FIELDS = 3,
478                         GET_VALUES = 4,
479                         GET_OBJECT = 5,
480                         GET_SOURCE_FILES = 6,
481                         SET_VALUES = 7,
482                         IS_ASSIGNABLE_FROM = 8,
483                         GET_PROPERTIES = 9,
484                         GET_CATTRS = 10,
485                         GET_FIELD_CATTRS = 11,
486                         GET_PROPERTY_CATTRS = 12,
487                         /* FIXME: Merge into GET_SOURCE_FILES when the major protocol version is increased */
488                         GET_SOURCE_FILES_2 = 13,
489                         /* FIXME: Merge into GET_VALUES when the major protocol version is increased */
490                         GET_VALUES_2 = 14,
491                         CMD_TYPE_GET_METHODS_BY_NAME_FLAGS = 15,
492                 }
493
494                 enum BindingFlagsExtensions {
495                         BINDING_FLAGS_IGNORE_CASE = 0x70000000,
496                 }
497
498                 enum CmdStackFrame {
499                         GET_VALUES = 1,
500                         GET_THIS = 2,
501                         SET_VALUES = 3
502                 }
503
504                 enum CmdArrayRef {
505                         GET_LENGTH = 1,
506                         GET_VALUES = 2,
507                         SET_VALUES = 3
508                 }
509
510                 enum CmdStringRef {
511                         GET_VALUE = 1
512                 }
513
514                 enum CmdObjectRef {
515                         GET_TYPE = 1,
516                         GET_VALUES = 2,
517                         IS_COLLECTED = 3,
518                         GET_ADDRESS = 4,
519                         GET_DOMAIN = 5,
520                         SET_VALUES = 6,
521                         GET_INFO = 7,
522                 }
523
524                 class Header {
525                         public int id;
526                         public int command_set;
527                         public int command;
528                         public int flags;
529                 }                       
530
531                 internal static int GetPacketLength (byte[] header) {
532                         int offset = 0;
533                         return decode_int (header, ref offset);
534                 }
535
536                 internal static bool IsReplyPacket (byte[] packet) {
537                         int offset = 8;
538                         return decode_byte (packet, ref offset) == 0x80;
539                 }
540
541                 internal static int GetPacketId (byte[] packet) {
542                         int offset = 4;
543                         return decode_int (packet, ref offset);
544                 }
545
546                 static int decode_byte (byte[] packet, ref int offset) {
547                         return packet [offset++];
548                 }
549
550                 static int decode_short (byte[] packet, ref int offset) {
551                         int res = ((int)packet [offset] << 8) | (int)packet [offset + 1];
552                         offset += 2;
553                         return res;
554                 }
555
556                 static int decode_int (byte[] packet, ref int offset) {
557                         int res = ((int)packet [offset] << 24) | ((int)packet [offset + 1] << 16) | ((int)packet [offset + 2] << 8) | (int)packet [offset + 3];
558                         offset += 4;
559                         return res;
560                 }
561
562                 static long decode_id (byte[] packet, ref int offset) {
563                         return decode_int (packet, ref offset);
564                 }
565
566                 static long decode_long (byte[] packet, ref int offset) {
567                         uint high = (uint)decode_int (packet, ref offset);
568                         uint low = (uint)decode_int (packet, ref offset);
569
570                         return (long)(((ulong)high << 32) | (ulong)low);
571                 }
572
573                 internal static SuspendPolicy decode_suspend_policy (int suspend_policy) {
574                         switch ((WPSuspendPolicy)suspend_policy) {
575                         case WPSuspendPolicy.NONE:
576                                 return SuspendPolicy.None;
577                         case WPSuspendPolicy.EVENT_THREAD:
578                                 return SuspendPolicy.EventThread;
579                         case WPSuspendPolicy.ALL:
580                                 return SuspendPolicy.All;
581                         default:
582                                 throw new NotImplementedException ();
583                         }
584                 }
585
586                 static Header decode_command_header (byte[] packet) {
587                         int offset = 0;
588                         Header res = new Header ();
589
590                         decode_int (packet, ref offset);
591                         res.id = decode_int (packet, ref offset);
592                         res.flags = decode_byte (packet, ref offset);
593                         res.command_set = decode_byte (packet, ref offset);
594                         res.command = decode_byte (packet, ref offset);
595
596                         return res;
597                 }
598
599                 static void encode_byte (byte[] buf, int b, ref int offset) {
600                         buf [offset] = (byte)b;
601                         offset ++;
602                 }
603
604                 static void encode_int (byte[] buf, int i, ref int offset) {
605                         buf [offset] = (byte)((i >> 24) & 0xff);
606                         buf [offset + 1] = (byte)((i >> 16) & 0xff);
607                         buf [offset + 2] = (byte)((i >> 8) & 0xff);
608                         buf [offset + 3] = (byte)((i >> 0) & 0xff);
609                         offset += 4;
610                 }
611
612                 static void encode_id (byte[] buf, long id, ref int offset) {
613                         encode_int (buf, (int)id, ref offset);
614                 }
615
616                 static void encode_long (byte[] buf, long l, ref int offset) {
617                         encode_int (buf, (int)((l >> 32) & 0xffffffff), ref offset);
618                         encode_int (buf, (int)(l & 0xffffffff), ref offset);
619                 }
620
621                 internal static byte[] EncodePacket (int id, int commandSet, int command, byte[] data, int dataLen) {
622                         byte[] buf = new byte [dataLen + 11];
623                         int offset = 0;
624                         
625                         encode_int (buf, buf.Length, ref offset);
626                         encode_int (buf, id, ref offset);
627                         encode_byte (buf, 0, ref offset);
628                         encode_byte (buf, commandSet, ref offset);
629                         encode_byte (buf, command, ref offset);
630
631                         for (int i = 0; i < dataLen; ++i)
632                                 buf [offset + i] = data [i];
633
634                         return buf;
635                 }
636
637                 class PacketReader {
638                         byte[] packet;
639                         int offset;
640
641                         public PacketReader (byte[] packet) {
642                                 this.packet = packet;
643
644                                 // For event packets
645                                 Header header = decode_command_header (packet);
646                                 CommandSet = (CommandSet)header.command_set;
647                                 Command = header.command;
648
649                                 // For reply packets
650                                 offset = 0;
651                                 ReadInt (); // length
652                                 ReadInt (); // id
653                                 ReadByte (); // flags
654                                 ErrorCode = ReadShort ();
655                         }
656
657                         public CommandSet CommandSet {
658                                 get; set;
659                         }
660
661                         public int Command {
662                                 get; set;
663                         }
664
665                         public int ErrorCode {
666                                 get; set;
667                         }
668
669                         public int Offset {
670                                 get {
671                                         return offset;
672                                 }
673                         }
674
675                         public int ReadByte () {
676                                 return decode_byte (packet, ref offset);
677                         }
678
679                         public int ReadShort () {
680                                 return decode_short (packet, ref offset);
681                         }
682
683                         public int ReadInt () {
684                                 return decode_int (packet, ref offset);
685                         }
686
687                         public long ReadId () {
688                                 return decode_id (packet, ref offset);
689                         }
690
691                         public long ReadLong () {
692                                 return decode_long (packet, ref offset);
693                         }
694
695                         public float ReadFloat () {
696                                 float f = DataConverter.FloatFromBE (packet, offset);
697                                 offset += 4;
698                                 return f;
699                         }
700
701                         public double ReadDouble () {
702                                 double d = DataConverter.DoubleFromBE (packet, offset);
703                                 offset += 8;
704                                 return d;
705                         }
706
707                         public string ReadString () {
708                                 int len = decode_int (packet, ref offset);
709                                 string res = new String (Encoding.UTF8.GetChars (packet, offset, len));
710                                 offset += len;
711                                 return res;
712                         }
713
714                         public ValueImpl ReadValue () {
715                                 ElementType etype = (ElementType)ReadByte ();
716
717                                 switch (etype) {
718                                 case ElementType.Void:
719                                         return new ValueImpl { Type = etype };
720                                 case ElementType.I1:
721                                         return new ValueImpl { Type = etype, Value = (sbyte)ReadInt () };
722                                 case ElementType.U1:
723                                         return new ValueImpl { Type = etype, Value = (byte)ReadInt () };
724                                 case ElementType.Boolean:
725                                         return new ValueImpl { Type = etype, Value = ReadInt () != 0 };
726                                 case ElementType.I2:
727                                         return new ValueImpl { Type = etype, Value = (short)ReadInt () };
728                                 case ElementType.U2:
729                                         return new ValueImpl { Type = etype, Value = (ushort)ReadInt () };
730                                 case ElementType.Char:
731                                         return new ValueImpl { Type = etype, Value = (char)ReadInt () };
732                                 case ElementType.I4:
733                                         return new ValueImpl { Type = etype, Value = ReadInt () };
734                                 case ElementType.U4:
735                                         return new ValueImpl { Type = etype, Value = (uint)ReadInt () };
736                                 case ElementType.I8:
737                                         return new ValueImpl { Type = etype, Value = ReadLong () };
738                                 case ElementType.U8:
739                                         return new ValueImpl { Type = etype, Value = (ulong)ReadLong () };
740                                 case ElementType.R4:
741                                         return new ValueImpl { Type = etype, Value = ReadFloat () };
742                                 case ElementType.R8:
743                                         return new ValueImpl { Type = etype, Value = ReadDouble () };
744                                 case ElementType.I:
745                                 case ElementType.U:
746                                 case ElementType.Ptr:
747                                         // FIXME: The client and the debuggee might have different word sizes
748                                         return new ValueImpl { Type = etype, Value = ReadLong () };
749                                 case ElementType.String:
750                                 case ElementType.SzArray:
751                                 case ElementType.Class:
752                                 case ElementType.Array:
753                                 case ElementType.Object:
754                                         long objid = ReadId ();
755                                         return new ValueImpl () { Type = etype, Objid = objid };
756                                 case ElementType.ValueType:
757                                         bool is_enum = ReadByte () == 1;
758                                         long klass = ReadId ();
759                                         long nfields = ReadInt ();
760                                         ValueImpl[] fields = new ValueImpl [nfields];
761                                         for (int i = 0; i < nfields; ++i)
762                                                 fields [i] = ReadValue ();
763                                         return new ValueImpl () { Type = etype, Klass = klass, Fields = fields, IsEnum = is_enum };
764                                 case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
765                                         return new ValueImpl { Type = etype };
766                                 case (ElementType)ValueTypeId.VALUE_TYPE_ID_TYPE:
767                                         return new ValueImpl () { Type = etype, Id = ReadId () };
768                                 default:
769                                         throw new NotImplementedException ("Unable to handle type " + etype);
770                                 }
771                         }
772                 }
773
774                 class PacketWriter {
775
776                         byte[] data;
777                         int offset;
778
779                         public PacketWriter () {
780                                 data = new byte [1024];
781                                 offset = 0;
782                         }
783
784                         void MakeRoom (int size) {
785                                 if (offset + size >= data.Length) {
786                                         int new_len = data.Length * 2;
787                                         while (new_len < offset + size) {
788                                                 new_len *= 2;
789                                         }
790                                         byte[] new_data = new byte [new_len];
791                                         Array.Copy (data, new_data, data.Length);
792                                         data = new_data;
793                                 }
794                         }
795
796                         public PacketWriter WriteByte (byte val) {
797                                 MakeRoom (1);
798                                 encode_byte (data, val, ref offset);
799                                 return this;
800                         }
801
802                         public PacketWriter WriteInt (int val) {
803                                 MakeRoom (4);
804                                 encode_int (data, val, ref offset);
805                                 return this;
806                         }
807
808                         public PacketWriter WriteId (long id) {
809                                 MakeRoom (8);
810                                 encode_id (data, id, ref offset);
811                                 return this;
812                         }
813
814                         public PacketWriter WriteLong (long val) {
815                                 MakeRoom (8);
816                                 encode_long (data, val, ref offset);
817                                 return this;
818                         }
819
820                         public PacketWriter WriteFloat (float f) {
821                                 MakeRoom (8);
822                                 byte[] b = DataConverter.GetBytesBE (f);
823                                 for (int i = 0; i < 4; ++i)
824                                         data [offset + i] = b [i];
825                                 offset += 4;
826                                 return this;
827                         }
828
829                         public PacketWriter WriteDouble (double d) {
830                                 MakeRoom (8);
831                                 byte[] b = DataConverter.GetBytesBE (d);
832                                 for (int i = 0; i < 8; ++i)
833                                         data [offset + i] = b [i];
834                                 offset += 8;
835                                 return this;
836                         }
837
838                         public PacketWriter WriteInts (int[] ids) {
839                                 for (int i = 0; i < ids.Length; ++i)
840                                         WriteInt (ids [i]);
841                                 return this;
842                         }
843
844                         public PacketWriter WriteIds (long[] ids) {
845                                 for (int i = 0; i < ids.Length; ++i)
846                                         WriteId (ids [i]);
847                                 return this;
848                         }
849
850                         public PacketWriter WriteString (string s) {
851                                 if (s == null)
852                                         return WriteInt (-1);
853
854                                 encode_int (data, s.Length, ref offset);
855                                 byte[] b = Encoding.UTF8.GetBytes (s);
856                                 MakeRoom (b.Length);
857                                 Buffer.BlockCopy (b, 0, data, offset, b.Length);
858                                 offset += b.Length;
859                                 return this;
860                         }
861
862                         public PacketWriter WriteBool (bool val) {
863                                 WriteByte (val ? (byte)1 : (byte)0);
864                                 return this;
865                         }
866
867                         public PacketWriter WriteValue (ValueImpl v) {
868                                 ElementType t;
869
870                                 if (v.Value != null)
871                                         t = TypeCodeToElementType (Type.GetTypeCode (v.Value.GetType ()));
872                                 else
873                                         t = v.Type;
874                                 WriteByte ((byte)t);
875                                 switch (t) {
876                                 case ElementType.Boolean:
877                                         WriteInt ((bool)v.Value ? 1 : 0);
878                                         break;
879                                 case ElementType.Char:
880                                         WriteInt ((int)(char)v.Value);
881                                         break;
882                                 case ElementType.I1:
883                                         WriteInt ((int)(sbyte)v.Value);
884                                         break;
885                                 case ElementType.U1:
886                                         WriteInt ((int)(byte)v.Value);
887                                         break;
888                                 case ElementType.I2:
889                                         WriteInt ((int)(short)v.Value);
890                                         break;
891                                 case ElementType.U2:
892                                         WriteInt ((int)(ushort)v.Value);
893                                         break;
894                                 case ElementType.I4:
895                                         WriteInt ((int)(int)v.Value);
896                                         break;
897                                 case ElementType.U4:
898                                         WriteInt ((int)(uint)v.Value);
899                                         break;
900                                 case ElementType.I8:
901                                         WriteLong ((long)(long)v.Value);
902                                         break;
903                                 case ElementType.U8:
904                                         WriteLong ((long)(ulong)v.Value);
905                                         break;
906                                 case ElementType.R4:
907                                         WriteFloat ((float)v.Value);
908                                         break;
909                                 case ElementType.R8:
910                                         WriteDouble ((double)v.Value);
911                                         break;
912                                 case ElementType.String:
913                                 case ElementType.SzArray:
914                                 case ElementType.Class:
915                                 case ElementType.Array:
916                                 case ElementType.Object:
917                                         WriteId (v.Objid);
918                                         break;
919                                 case ElementType.ValueType:
920                                         // FIXME: 
921                                         if (v.IsEnum)
922                                                 throw new NotImplementedException ();
923                                         WriteByte (0);
924                                         WriteId (v.Klass);
925                                         WriteInt (v.Fields.Length);
926                                         for (int i = 0; i < v.Fields.Length; ++i)
927                                                 WriteValue (v.Fields [i]);
928                                         break;
929                                 case (ElementType)ValueTypeId.VALUE_TYPE_ID_NULL:
930                                         break;
931                                 default:
932                                         throw new NotImplementedException ();
933                                 }
934
935                                 return this;
936                         }
937
938                         public PacketWriter WriteValues (ValueImpl[] values) {
939                                 for (int i = 0; i < values.Length; ++i)
940                                         WriteValue (values [i]);
941                                 return this;
942                         }
943
944                         public byte[] Data {
945                                 get {
946                                         return data;
947                                 }
948                         }
949
950                         public int Offset {
951                                 get {
952                                         return offset;
953                                 }
954                         }
955                 }
956
957                 delegate void ReplyCallback (int packet_id, byte[] packet);
958
959                 bool closed;
960                 Thread receiver_thread;
961                 Dictionary<int, byte[]> reply_packets;
962                 Dictionary<int, ReplyCallback> reply_cbs;
963                 object reply_packets_monitor;
964
965                 internal event EventHandler<ErrorHandlerEventArgs> ErrorHandler;
966
967                 protected Connection () {
968                         closed = false;
969                         reply_packets = new Dictionary<int, byte[]> ();
970                         reply_cbs = new Dictionary<int, ReplyCallback> ();
971                         reply_packets_monitor = new Object ();
972                 }
973                 
974                 protected abstract int TransportReceive (byte[] buf, int buf_offset, int len);
975                 protected abstract int TransportSend (byte[] buf, int buf_offset, int len);
976                 protected abstract void TransportSetTimeouts (int send_timeout, int receive_timeout);
977                 protected abstract void TransportClose ();
978
979                 internal VersionInfo Version;
980                 
981                 int Receive (byte[] buf, int buf_offset, int len) {
982                         int offset = 0;
983
984                         while (offset < len) {
985                                 int n = TransportReceive (buf, buf_offset + offset, len - offset);
986
987                                 if (n == 0)
988                                         return offset;
989                                 offset += n;
990                         }
991
992                         return offset;
993                 }
994                 
995                 // Do the wire protocol handshake
996                 internal void Connect () {
997                         byte[] buf = new byte [HANDSHAKE_STRING.Length];
998                         char[] cbuf = new char [buf.Length];
999
1000                         // FIXME: Add a timeout
1001                         int n = Receive (buf, 0, buf.Length);
1002                         if (n == 0)
1003                                 throw new IOException ("DWP Handshake failed.");
1004                         for (int i = 0; i < buf.Length; ++i)
1005                                 cbuf [i] = (char)buf [i];
1006
1007                         if (new String (cbuf) != HANDSHAKE_STRING)
1008                                 throw new IOException ("DWP Handshake failed.");
1009                         
1010                         TransportSend (buf, 0, buf.Length);
1011
1012                         receiver_thread = new Thread (new ThreadStart (receiver_thread_main));
1013                         receiver_thread.Start ();
1014
1015                         Version = VM_GetVersion ();
1016
1017                         //
1018                         // Tell the debuggee our protocol version, so newer debuggees can work
1019                         // with older clients
1020                         //
1021
1022                         //
1023                         // Older debuggees might not support this request
1024                         EventHandler<ErrorHandlerEventArgs> OrigErrorHandler = ErrorHandler;
1025                         ErrorHandler = null;
1026                         ErrorHandler += delegate (object sender, ErrorHandlerEventArgs args) {
1027                                 throw new NotSupportedException ();
1028                         };
1029                         try {
1030                                 VM_SetProtocolVersion (MAJOR_VERSION, MINOR_VERSION);
1031                         } catch (NotSupportedException) {
1032                         }
1033                         ErrorHandler = OrigErrorHandler;
1034                 }
1035
1036                 internal byte[] ReadPacket () {
1037                         // FIXME: Throw ClosedConnectionException () if the connection is closed
1038                         // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1039                         // FIXME: Locking
1040                         byte[] header = new byte [HEADER_LENGTH];
1041
1042                         int len = Receive (header, 0, header.Length);
1043                         if (len == 0)
1044                                 return new byte [0];
1045                         if (len != HEADER_LENGTH) {
1046                                 // FIXME:
1047                                 throw new IOException ("Packet of length " + len + " is read.");
1048                         }
1049
1050                         int packetLength = GetPacketLength (header);
1051                         if (packetLength < 11)
1052                                 throw new IOException ("Invalid packet length.");
1053
1054                         if (packetLength == 11) {
1055                                 return header;
1056                         } else {
1057                                 byte[] buf = new byte [packetLength];
1058                                 for (int i = 0; i < header.Length; ++i)
1059                                         buf [i] = header [i];
1060                                 len = Receive (buf, header.Length, packetLength - header.Length);
1061                                 if (len != packetLength - header.Length)
1062                                         throw new IOException ();
1063                                 return buf;
1064                         }
1065                 }
1066
1067                 internal void WritePacket (byte[] packet) {
1068                         // FIXME: Throw ClosedConnectionException () if the connection is closed
1069                         // FIXME: Throw ClosedConnectionException () if another thread closes the connection
1070                         // FIXME: Locking
1071                         TransportSend (packet, 0, packet.Length);
1072                 }
1073
1074                 internal void Close () {
1075                         closed = true;
1076                 }
1077
1078                 internal bool IsClosed {
1079                         get {
1080                                 return closed;
1081                         }
1082                 }
1083
1084                 bool disconnected;
1085
1086                 void receiver_thread_main () {
1087                         while (!closed) {
1088                                 try {
1089                                         bool res = ReceivePacket ();
1090                                         if (!res)
1091                                                 break;
1092                                 } catch (Exception ex) {
1093                                         Console.WriteLine (ex);
1094                                         break;
1095                                 }
1096                         }
1097
1098                         lock (reply_packets_monitor) {
1099                                 disconnected = true;
1100                                 Monitor.PulseAll (reply_packets_monitor);
1101                                 TransportClose ();
1102                         }
1103                         EventHandler.VMDisconnect (0, 0, null);
1104                 }
1105
1106                 bool ReceivePacket () {
1107                                 byte[] packet = ReadPacket ();
1108
1109                                 if (packet.Length == 0) {
1110                                         return false;
1111                                 }
1112
1113                                 if (IsReplyPacket (packet)) {
1114                                         int id = GetPacketId (packet);
1115                                         ReplyCallback cb = null;
1116                                         lock (reply_packets_monitor) {
1117                                                 reply_cbs.TryGetValue (id, out cb);
1118                                                 if (cb == null) {
1119                                                         reply_packets [id] = packet;
1120                                                         Monitor.PulseAll (reply_packets_monitor);
1121                                                 }
1122                                         }
1123
1124                                         if (cb != null)
1125                                                 cb.Invoke (id, packet);
1126                                 } else {
1127                                         PacketReader r = new PacketReader (packet);
1128
1129                                         if (r.CommandSet == CommandSet.EVENT && r.Command == (int)CmdEvent.COMPOSITE) {
1130                                                 int spolicy = r.ReadByte ();
1131                                                 int nevents = r.ReadInt ();
1132
1133                                                 SuspendPolicy suspend_policy = decode_suspend_policy (spolicy);
1134
1135                                                 EventInfo[] events = new EventInfo [nevents];
1136
1137                                                 for (int i = 0; i < nevents; ++i) {
1138                                                         EventKind kind = (EventKind)r.ReadByte ();
1139                                                         int req_id = r.ReadInt ();
1140
1141                                                         EventType etype = (EventType)kind;
1142
1143                                                         if (kind == EventKind.VM_START) {
1144                                                                 long thread_id = r.ReadId ();
1145                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id };
1146                                                                 //EventHandler.VMStart (req_id, thread_id, null);
1147                                                         } else if (kind == EventKind.VM_DEATH) {
1148                                                                 //EventHandler.VMDeath (req_id, 0, null);
1149                                                                 events [i] = new EventInfo (etype, req_id) { };
1150                                                         } else if (kind == EventKind.THREAD_START) {
1151                                                                 long thread_id = r.ReadId ();
1152                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1153                                                                 //EventHandler.ThreadStart (req_id, thread_id, thread_id);
1154                                                         } else if (kind == EventKind.THREAD_DEATH) {
1155                                                                 long thread_id = r.ReadId ();
1156                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = thread_id };
1157                                                                 //EventHandler.ThreadDeath (req_id, thread_id, thread_id);
1158                                                         } else if (kind == EventKind.ASSEMBLY_LOAD) {
1159                                                                 long thread_id = r.ReadId ();
1160                                                                 long id = r.ReadId ();
1161                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1162                                                                 //EventHandler.AssemblyLoad (req_id, thread_id, id);
1163                                                         } else if (kind == EventKind.ASSEMBLY_UNLOAD) {
1164                                                                 long thread_id = r.ReadId ();
1165                                                                 long id = r.ReadId ();
1166                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1167                                                                 //EventHandler.AssemblyUnload (req_id, thread_id, id);
1168                                                         } else if (kind == EventKind.TYPE_LOAD) {
1169                                                                 long thread_id = r.ReadId ();
1170                                                                 long id = r.ReadId ();
1171                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1172                                                                 //EventHandler.TypeLoad (req_id, thread_id, id);
1173                                                         } else if (kind == EventKind.METHOD_ENTRY) {
1174                                                                 long thread_id = r.ReadId ();
1175                                                                 long id = r.ReadId ();
1176                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1177                                                                 //EventHandler.MethodEntry (req_id, thread_id, id);
1178                                                         } else if (kind == EventKind.METHOD_EXIT) {
1179                                                                 long thread_id = r.ReadId ();
1180                                                                 long id = r.ReadId ();
1181                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1182                                                                 //EventHandler.MethodExit (req_id, thread_id, id);
1183                                                         } else if (kind == EventKind.BREAKPOINT) {
1184                                                                 long thread_id = r.ReadId ();
1185                                                                 long id = r.ReadId ();
1186                                                                 long loc = r.ReadLong ();
1187                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1188                                                                 //EventHandler.Breakpoint (req_id, thread_id, id, loc);
1189                                                         } else if (kind == EventKind.STEP) {
1190                                                                 long thread_id = r.ReadId ();
1191                                                                 long id = r.ReadId ();
1192                                                                 long loc = r.ReadLong ();
1193                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1194                                                                 //EventHandler.Step (req_id, thread_id, id, loc);
1195                                                         } else if (kind == EventKind.EXCEPTION) {
1196                                                                 long thread_id = r.ReadId ();
1197                                                                 long id = r.ReadId ();
1198                                                                 long loc = 0; // FIXME
1199                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1200                                                                 //EventHandler.Exception (req_id, thread_id, id, loc);
1201                                                         } else if (kind == EventKind.APPDOMAIN_CREATE) {
1202                                                                 long thread_id = r.ReadId ();
1203                                                                 long id = r.ReadId ();
1204                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1205                                                                 //EventHandler.AppDomainCreate (req_id, thread_id, id);
1206                                                         } else if (kind == EventKind.APPDOMAIN_UNLOAD) {
1207                                                                 long thread_id = r.ReadId ();
1208                                                                 long id = r.ReadId ();
1209                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id };
1210                                                                 //EventHandler.AppDomainUnload (req_id, thread_id, id);
1211                                                         } else if (kind == EventKind.USER_BREAK) {
1212                                                                 long thread_id = r.ReadId ();
1213                                                                 long id = 0;
1214                                                                 long loc = 0;
1215                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Id = id, Location = loc };
1216                                                                 //EventHandler.Exception (req_id, thread_id, id, loc);
1217                                                         } else if (kind == EventKind.USER_LOG) {
1218                                                                 long thread_id = r.ReadId ();
1219                                                                 int level = r.ReadInt ();
1220                                                                 string category = r.ReadString ();
1221                                                                 string message = r.ReadString ();
1222                                                                 events [i] = new EventInfo (etype, req_id) { ThreadId = thread_id, Level = level, Category = category, Message = message };
1223                                                                 //EventHandler.Exception (req_id, thread_id, id, loc);
1224                                                         } else if (kind == EventKind.KEEPALIVE) {
1225                                                                 events [i] = new EventInfo (etype, req_id) { };
1226                                                         } else {
1227                                                                 throw new NotImplementedException ("Unknown event kind: " + kind);
1228                                                         }
1229                                                 }
1230
1231                                                 EventHandler.Events (suspend_policy, events);
1232                                         }
1233                                 }
1234
1235                                 return true;
1236                 }
1237
1238                 internal IEventHandler EventHandler {
1239                         get; set;
1240                 }
1241
1242                 static String CommandString (CommandSet command_set, int command)
1243                 {
1244                         string cmd;
1245                         switch (command_set) {
1246                         case CommandSet.VM:
1247                                 cmd = ((CmdVM)command).ToString ();
1248                                 break;
1249                         case CommandSet.OBJECT_REF:
1250                                 cmd = ((CmdObjectRef)command).ToString ();
1251                                 break;
1252                         case CommandSet.STRING_REF:
1253                                 cmd = ((CmdStringRef)command).ToString ();
1254                                 break;
1255                         case CommandSet.THREAD:
1256                                 cmd = ((CmdThread)command).ToString ();
1257                                 break;
1258                         case CommandSet.ARRAY_REF:
1259                                 cmd = ((CmdArrayRef)command).ToString ();
1260                                 break;
1261                         case CommandSet.EVENT_REQUEST:
1262                                 cmd = ((CmdEventRequest)command).ToString ();
1263                                 break;
1264                         case CommandSet.STACK_FRAME:
1265                                 cmd = ((CmdStackFrame)command).ToString ();
1266                                 break;
1267                         case CommandSet.APPDOMAIN:
1268                                 cmd = ((CmdAppDomain)command).ToString ();
1269                                 break;
1270                         case CommandSet.ASSEMBLY:
1271                                 cmd = ((CmdAssembly)command).ToString ();
1272                                 break;
1273                         case CommandSet.METHOD:
1274                                 cmd = ((CmdMethod)command).ToString ();
1275                                 break;
1276                         case CommandSet.TYPE:
1277                                 cmd = ((CmdType)command).ToString ();
1278                                 break;
1279                         case CommandSet.MODULE:
1280                                 cmd = ((CmdModule)command).ToString ();
1281                                 break;
1282                         case CommandSet.EVENT:
1283                                 cmd = ((CmdEvent)command).ToString ();
1284                                 break;
1285                         default:
1286                                 cmd = command.ToString ();
1287                                 break;
1288                         }
1289                         return string.Format ("[{0} {1}]", command_set, cmd);
1290                 }
1291
1292                 long total_protocol_ticks;
1293
1294                 void LogPacket (int packet_id, byte[] encoded_packet, byte[] reply_packet, CommandSet command_set, int command, Stopwatch watch) {
1295                         watch.Stop ();
1296                         total_protocol_ticks += watch.ElapsedTicks;
1297                         var ts = TimeSpan.FromTicks (total_protocol_ticks);
1298                         string msg = string.Format ("Packet: {0} sent: {1} received: {2} ms: {3} total ms: {4} {5}",
1299                            packet_id, encoded_packet.Length, reply_packet.Length, watch.ElapsedMilliseconds,
1300                            (ts.Seconds * 1000) + ts.Milliseconds,
1301                            CommandString (command_set, command));
1302
1303                         LoggingStream.WriteLine (msg);
1304                         LoggingStream.Flush ();
1305                 }
1306
1307                 /* Send a request and call cb when a result is received */
1308                 int Send (CommandSet command_set, int command, PacketWriter packet, Action<PacketReader> cb) {
1309                         int id = IdGenerator;
1310
1311                         Stopwatch watch = null;
1312                         if (EnableConnectionLogging)
1313                                 watch = Stopwatch.StartNew ();
1314
1315                         byte[] encoded_packet;
1316                         if (packet == null)
1317                                 encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1318                         else
1319                                 encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1320
1321                         lock (reply_packets_monitor) {
1322                                 reply_cbs [id] = delegate (int packet_id, byte[] p) {
1323                                         if (EnableConnectionLogging)
1324                                                 LogPacket (packet_id, encoded_packet, p, command_set, command, watch);
1325                                         /* Run the callback on a tp thread to avoid blocking the receive thread */
1326                                         PacketReader r = new PacketReader (p);
1327                                         cb.BeginInvoke (r, null, null);
1328                                 };
1329                         }
1330
1331                         WritePacket (encoded_packet);
1332
1333                         return id;
1334                 }
1335
1336                 PacketReader SendReceive (CommandSet command_set, int command, PacketWriter packet) {
1337                         int id = IdGenerator;
1338                         Stopwatch watch = null;
1339
1340                         if (disconnected)
1341                                 throw new VMDisconnectedException ();
1342
1343                         if (EnableConnectionLogging)
1344                                 watch = Stopwatch.StartNew ();
1345
1346                         byte[] encoded_packet;
1347
1348                         if (packet == null)
1349                                 encoded_packet = EncodePacket (id, (int)command_set, command, null, 0);
1350                         else
1351                                 encoded_packet = EncodePacket (id, (int)command_set, command, packet.Data, packet.Offset);
1352
1353                         WritePacket (encoded_packet);
1354
1355                         int packetId = id;
1356
1357                         /* Wait for the reply packet */
1358                         while (true) {
1359                                 lock (reply_packets_monitor) {
1360                                         if (reply_packets.ContainsKey (packetId)) {
1361                                                 byte[] reply = reply_packets [packetId];
1362                                                 reply_packets.Remove (packetId);
1363                                                 PacketReader r = new PacketReader (reply);
1364
1365                                                 if (EnableConnectionLogging)
1366                                                         LogPacket (packetId, encoded_packet, reply, command_set, command, watch);
1367                                                 if (r.ErrorCode != 0) {
1368                                                         if (ErrorHandler != null)
1369                                                                 ErrorHandler (this, new ErrorHandlerEventArgs () { ErrorCode = (ErrorCode)r.ErrorCode });
1370                                                         throw new NotImplementedException ("No error handler set.");
1371                                                 } else {
1372                                                         return r;
1373                                                 }
1374                                         } else {
1375                                                 if (disconnected)
1376                                                         throw new VMDisconnectedException ();
1377                                                 Monitor.Wait (reply_packets_monitor);
1378                                         }
1379                                 }
1380                         }
1381                 }
1382
1383                 PacketReader SendReceive (CommandSet command_set, int command) {
1384                         return SendReceive (command_set, command, null);
1385                 }
1386
1387                 int packet_id_generator;
1388
1389                 int IdGenerator {
1390                         get {
1391                                 return Interlocked.Increment (ref packet_id_generator);
1392                         }
1393                 }
1394
1395                 CattrInfo[] ReadCattrs (PacketReader r) {
1396                         CattrInfo[] res = new CattrInfo [r.ReadInt ()];
1397                         for (int i = 0; i < res.Length; ++i) {
1398                                 CattrInfo info = new CattrInfo ();
1399                                 info.ctor_id = r.ReadId ();
1400                                 info.ctor_args = new ValueImpl [r.ReadInt ()];
1401                                 for (int j = 0; j < info.ctor_args.Length; ++j) {
1402                                         info.ctor_args [j] = r.ReadValue ();
1403                                 }
1404                                 info.named_args = new CattrNamedArgInfo [r.ReadInt ()];
1405                                 for (int j = 0; j < info.named_args.Length; ++j) {
1406                                         CattrNamedArgInfo arg = new CattrNamedArgInfo ();
1407                                         int arg_type = r.ReadByte ();
1408                                         arg.is_property = arg_type == 0x54;
1409                                         arg.id = r.ReadId ();
1410                                         arg.value = r.ReadValue ();
1411                                         info.named_args [j] = arg;
1412                                 }
1413                                 res [i] = info;
1414                         }
1415                         return res;
1416                 }
1417
1418                 static ElementType TypeCodeToElementType (TypeCode c) {
1419                         switch (c) {
1420                         case TypeCode.Boolean:
1421                                 return ElementType.Boolean;
1422                         case TypeCode.Char:
1423                                 return ElementType.Char;
1424                         case TypeCode.SByte:
1425                                 return ElementType.I1;
1426                         case TypeCode.Byte:
1427                                 return ElementType.U1;
1428                         case TypeCode.Int16:
1429                                 return ElementType.I2;
1430                         case TypeCode.UInt16:
1431                                 return ElementType.U2;
1432                         case TypeCode.Int32:
1433                                 return ElementType.I4;
1434                         case TypeCode.UInt32:
1435                                 return ElementType.U4;
1436                         case TypeCode.Int64:
1437                                 return ElementType.I8;
1438                         case TypeCode.UInt64:
1439                                 return ElementType.U8;
1440                         case TypeCode.Single:
1441                                 return ElementType.R4;
1442                         case TypeCode.Double:
1443                                 return ElementType.R8;
1444                         default:
1445                                 throw new NotImplementedException ();
1446                         }
1447                 }
1448
1449                 /*
1450                  * Implementation of debugger commands
1451                  */
1452
1453                 internal VersionInfo VM_GetVersion () {
1454                         var res = SendReceive (CommandSet.VM, (int)CmdVM.VERSION, null);
1455                         VersionInfo info = new VersionInfo ();
1456                         info.VMVersion = res.ReadString ();
1457                         info.MajorVersion = res.ReadInt ();
1458                         info.MinorVersion = res.ReadInt ();
1459                         return info;
1460                 }
1461
1462                 internal void VM_SetProtocolVersion (int major, int minor) {
1463                         SendReceive (CommandSet.VM, (int)CmdVM.SET_PROTOCOL_VERSION, new PacketWriter ().WriteInt (major).WriteInt (minor));
1464                 }
1465
1466                 internal long[] VM_GetThreads () {
1467                         var res = SendReceive (CommandSet.VM, (int)CmdVM.ALL_THREADS, null);
1468                         int len = res.ReadInt ();
1469                         long[] arr = new long [len];
1470                         for (int i = 0; i < len; ++i)
1471                                 arr [i] = res.ReadId ();
1472                         return arr;
1473                 }
1474
1475                 internal void VM_Suspend () {
1476                         SendReceive (CommandSet.VM, (int)CmdVM.SUSPEND);
1477                 }
1478
1479                 internal void VM_Resume () {
1480                         SendReceive (CommandSet.VM, (int)CmdVM.RESUME);
1481                 }
1482
1483                 internal void VM_Exit (int exitCode) {
1484                         SendReceive (CommandSet.VM, (int)CmdVM.EXIT, new PacketWriter ().WriteInt (exitCode));
1485                 }
1486
1487                 internal void VM_Dispose () {
1488                         SendReceive (CommandSet.VM, (int)CmdVM.DISPOSE);
1489                 }
1490
1491                 internal ValueImpl VM_InvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, out ValueImpl exc) {
1492                         exc = null;
1493                         PacketReader r = SendReceive (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments));
1494                         if (r.ReadByte () == 0) {
1495                                 exc = r.ReadValue ();
1496                                 return null;
1497                         } else {
1498                                 return r.ReadValue ();
1499                         }
1500                 }
1501
1502                 internal delegate void InvokeMethodCallback (ValueImpl v, ValueImpl exc, ErrorCode error, object state);
1503
1504                 internal int VM_BeginInvokeMethod (long thread, long method, ValueImpl this_arg, ValueImpl[] arguments, InvokeFlags flags, InvokeMethodCallback callback, object state) {
1505                         return Send (CommandSet.VM, (int)CmdVM.INVOKE_METHOD, new PacketWriter ().WriteId (thread).WriteInt ((int)flags).WriteId (method).WriteValue (this_arg).WriteInt (arguments.Length).WriteValues (arguments), delegate (PacketReader r) {
1506                                         ValueImpl v, exc;
1507
1508                                         if (r.ErrorCode != 0) {
1509                                                 callback (null, null, (ErrorCode)r.ErrorCode, state);
1510                                         } else {
1511                                                 if (r.ReadByte () == 0) {
1512                                                         exc = r.ReadValue ();
1513                                                         v = null;
1514                                                 } else {
1515                                                         v = r.ReadValue ();
1516                                                         exc = null;
1517                                                 }
1518
1519                                                 callback (v, exc, 0, state);
1520                                         }
1521                                 });
1522                 }
1523
1524                 internal void VM_AbortInvoke (long thread, int id)
1525                 {
1526                         SendReceive (CommandSet.VM, (int)CmdVM.ABORT_INVOKE, new PacketWriter ().WriteId (thread).WriteInt (id));
1527                 }
1528
1529                 internal void SetSocketTimeouts (int send_timeout, int receive_timeout, int keepalive_interval)
1530                 {
1531                         TransportSetTimeouts (send_timeout, receive_timeout);
1532                         SendReceive (CommandSet.VM, (int)CmdVM.SET_KEEPALIVE, new PacketWriter ().WriteId (keepalive_interval));
1533                 }
1534
1535                 internal long[] VM_GetTypesForSourceFile (string fname, bool ignoreCase) {
1536                         var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES_FOR_SOURCE_FILE, new PacketWriter ().WriteString (fname).WriteBool (ignoreCase));
1537                         int count = res.ReadInt ();
1538                         long[] types = new long [count];
1539                         for (int i = 0; i < count; ++i)
1540                                 types [i] = res.ReadId ();
1541                         return types;
1542                 }
1543
1544                 internal long[] VM_GetTypes (string name, bool ignoreCase) {
1545                         var res = SendReceive (CommandSet.VM, (int)CmdVM.GET_TYPES, new PacketWriter ().WriteString (name).WriteBool (ignoreCase));
1546                         int count = res.ReadInt ();
1547                         long[] types = new long [count];
1548                         for (int i = 0; i < count; ++i)
1549                                 types [i] = res.ReadId ();
1550                         return types;
1551                 }
1552
1553                 /*
1554                  * DOMAIN
1555                  */
1556
1557                 internal long RootDomain {
1558                         get {
1559                                 return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ROOT_DOMAIN, null).ReadId ();
1560                         }
1561                 }
1562
1563                 internal string Domain_GetName (long id) {
1564                         return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_FRIENDLY_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1565                 }
1566
1567                 internal long[] Domain_GetAssemblies (long id) {
1568                         var res = SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ASSEMBLIES, new PacketWriter ().WriteId (id));
1569                         int count = res.ReadInt ();
1570                         long[] assemblies = new long [count];
1571                         for (int i = 0; i < count; ++i)
1572                                 assemblies [i] = res.ReadId ();
1573                         return assemblies;
1574                 }
1575
1576                 internal long Domain_GetEntryAssembly (long id) {
1577                         return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_ENTRY_ASSEMBLY, new PacketWriter ().WriteId (id)).ReadId ();
1578                 }
1579
1580                 internal long Domain_GetCorlib (long id) {
1581                         return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.GET_CORLIB, new PacketWriter ().WriteId (id)).ReadId ();
1582                 }
1583
1584                 internal long Domain_CreateString (long id, string s) {
1585                         return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_STRING, new PacketWriter ().WriteId (id).WriteString (s)).ReadId ();
1586                 }
1587
1588                 internal long Domain_CreateBoxedValue (long id, long type_id, ValueImpl v) {
1589                         return SendReceive (CommandSet.APPDOMAIN, (int)CmdAppDomain.CREATE_BOXED_VALUE, new PacketWriter ().WriteId (id).WriteId (type_id).WriteValue (v)).ReadId ();
1590                 }
1591
1592                 /*
1593                  * METHOD
1594                  */
1595
1596                 internal string Method_GetName (long id) {
1597                         return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1598                 }
1599
1600                 internal long Method_GetDeclaringType (long id) {
1601                         return SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DECLARING_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
1602                 }
1603
1604                 internal DebugInfo Method_GetDebugInfo (long id) {
1605                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_DEBUG_INFO, new PacketWriter ().WriteId (id));
1606
1607                         DebugInfo info = new DebugInfo ();
1608                         info.max_il_offset = res.ReadInt ();
1609                         info.filename = res.ReadString ();
1610
1611                         int n_il_offsets = res.ReadInt ();
1612                         info.il_offsets = new int [n_il_offsets];
1613                         info.line_numbers = new int [n_il_offsets];
1614                         for (int i = 0; i < n_il_offsets; ++i) {
1615                                 info.il_offsets [i] = res.ReadInt ();
1616                                 info.line_numbers [i] = res.ReadInt ();
1617                         }
1618
1619                         return info;
1620                 }
1621
1622                 internal ParamInfo Method_GetParamInfo (long id) {
1623                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_PARAM_INFO, new PacketWriter ().WriteId (id));
1624
1625                         ParamInfo info = new ParamInfo ();
1626                         info.call_conv = res.ReadInt ();
1627                         info.param_count = res.ReadInt ();
1628                         info.generic_param_count = res.ReadInt ();
1629                         info.ret_type = res.ReadId ();
1630                         info.param_types = new long [info.param_count];
1631                         for (int i = 0; i < info.param_count; ++i)
1632                                 info.param_types [i] = res.ReadId ();
1633                         info.param_names = new string [info.param_count];                       
1634                         for (int i = 0; i < info.param_count; ++i)
1635                                 info.param_names [i] = res.ReadString ();
1636
1637                         return info;
1638                 }
1639
1640                 internal LocalsInfo Method_GetLocalsInfo (long id) {
1641                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_LOCALS_INFO, new PacketWriter ().WriteId (id));
1642
1643                         LocalsInfo info = new LocalsInfo ();
1644                         int nlocals = res.ReadInt ();
1645                         info.types = new long [nlocals];
1646                         for (int i = 0; i < nlocals; ++i)
1647                                 info.types [i] = res.ReadId ();
1648                         info.names = new string [nlocals];
1649                         for (int i = 0; i < nlocals; ++i)
1650                                 info.names [i] = res.ReadString ();
1651                         info.live_range_start = new int [nlocals];
1652                         info.live_range_end = new int [nlocals];
1653                         for (int i = 0; i < nlocals; ++i) {
1654                                 info.live_range_start [i] = res.ReadInt ();
1655                                 info.live_range_end [i] = res.ReadInt ();
1656                         }
1657
1658                         return info;
1659                 }
1660
1661                 internal MethodInfo Method_GetInfo (long id) {
1662                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_INFO, new PacketWriter ().WriteId (id));
1663
1664                         MethodInfo info = new MethodInfo ();
1665                         info.attributes = res.ReadInt ();
1666                         info.iattributes = res.ReadInt ();
1667                         info.token = res.ReadInt ();
1668
1669                         return info;
1670                 }
1671
1672                 internal MethodBodyInfo Method_GetBody (long id) {
1673                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.GET_BODY, new PacketWriter ().WriteId (id));
1674
1675                         MethodBodyInfo info = new MethodBodyInfo ();
1676                         info.il = new byte [res.ReadInt ()];
1677                         for (int i = 0; i < info.il.Length; ++i)
1678                                 info.il [i] = (byte)res.ReadByte ();
1679
1680                         return info;
1681                 }
1682
1683                 internal ResolvedToken Method_ResolveToken (long id, int token) {
1684                         var res = SendReceive (CommandSet.METHOD, (int)CmdMethod.RESOLVE_TOKEN, new PacketWriter ().WriteId (id).WriteInt (token));
1685
1686                         TokenType type = (TokenType)res.ReadByte ();
1687                         switch (type) {
1688                         case TokenType.STRING:
1689                                 return new ResolvedToken () { Type = type, Str = res.ReadString () };
1690                         case TokenType.TYPE:
1691                         case TokenType.METHOD:
1692                         case TokenType.FIELD:
1693                                 return new ResolvedToken () { Type = type, Id = res.ReadId () };
1694                         case TokenType.UNKNOWN:
1695                                 return new ResolvedToken () { Type = type };
1696                         default:
1697                                 throw new NotImplementedException ();
1698                         }
1699                 }
1700
1701                 /*
1702                  * THREAD
1703                  */
1704
1705                 internal string Thread_GetName (long id) {
1706                         return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1707                 }
1708
1709                 internal FrameInfo[] Thread_GetFrameInfo (long id, int start_frame, int length) {
1710                         var res = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_FRAME_INFO, new PacketWriter ().WriteId (id).WriteInt (start_frame).WriteInt (length));
1711                         int count = res.ReadInt ();
1712
1713                         var frames = new FrameInfo [count];
1714                         for (int i = 0; i < count; ++i) {
1715                                 frames [i].id = res.ReadInt ();
1716                                 frames [i].method = res.ReadId ();
1717                                 frames [i].il_offset = res.ReadInt ();
1718                                 frames [i].flags = (StackFrameFlags)res.ReadByte ();
1719                         }
1720                         return frames;
1721                 }
1722
1723                 internal int Thread_GetState (long id) {
1724                         return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_STATE, new PacketWriter ().WriteId (id)).ReadInt ();
1725                 }
1726
1727                 internal ThreadInfo Thread_GetInfo (long id) {
1728                         PacketReader r = SendReceive (CommandSet.THREAD, (int)CmdThread.GET_INFO, new PacketWriter ().WriteId (id));
1729
1730                         ThreadInfo res = new ThreadInfo () { is_thread_pool = r.ReadByte () > 0 ? true : false };
1731
1732                         return res;
1733                 }
1734
1735                 internal long Thread_GetId (long id) {
1736                         return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_ID, new PacketWriter ().WriteId (id)).ReadLong ();
1737                 }
1738
1739                 internal long Thread_GetTID (long id) {
1740                         return SendReceive (CommandSet.THREAD, (int)CmdThread.GET_TID, new PacketWriter ().WriteId (id)).ReadLong ();
1741                 }
1742
1743                 /*
1744                  * MODULE
1745                  */
1746
1747                 internal ModuleInfo Module_GetInfo (long id) {
1748                         PacketReader r = SendReceive (CommandSet.MODULE, (int)CmdModule.GET_INFO, new PacketWriter ().WriteId (id));
1749                         ModuleInfo info = new ModuleInfo { Name = r.ReadString (), ScopeName = r.ReadString (), FQName = r.ReadString (), Guid = r.ReadString (), Assembly = r.ReadId () };
1750                         return info;
1751                 }
1752
1753                 /*
1754                  * ASSEMBLY
1755                  */
1756
1757                 internal string Assembly_GetLocation (long id) {
1758                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_LOCATION, new PacketWriter ().WriteId (id)).ReadString ();
1759                 }
1760
1761                 internal long Assembly_GetEntryPoint (long id) {
1762                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_ENTRY_POINT, new PacketWriter ().WriteId (id)).ReadId ();
1763                 }
1764
1765                 internal long Assembly_GetManifestModule (long id) {
1766                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_MANIFEST_MODULE, new PacketWriter ().WriteId (id)).ReadId ();
1767                 }
1768
1769                 internal long Assembly_GetObject (long id) {
1770                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
1771                 }
1772
1773                 internal long Assembly_GetType (long id, string name, bool ignoreCase) {
1774                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_TYPE, new PacketWriter ().WriteId (id).WriteString (name).WriteBool (ignoreCase)).ReadId ();
1775                 }
1776
1777                 internal string Assembly_GetName (long id) {
1778                         return SendReceive (CommandSet.ASSEMBLY, (int)CmdAssembly.GET_NAME, new PacketWriter ().WriteId (id)).ReadString ();
1779                 }
1780
1781                 /*
1782                  * TYPE
1783                  */
1784
1785                 internal TypeInfo Type_GetInfo (long id) {
1786                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_INFO, new PacketWriter ().WriteId (id));
1787                         TypeInfo res = new TypeInfo ();
1788
1789                         res.ns = r.ReadString ();
1790                         res.name = r.ReadString ();
1791                         res.full_name = r.ReadString ();
1792                         res.assembly = r.ReadId ();
1793                         res.module = r.ReadId ();
1794                         res.base_type = r.ReadId ();
1795                         res.element_type = r.ReadId ();
1796                         res.token = r.ReadInt ();
1797                         res.rank = r.ReadByte ();
1798                         res.attributes = r.ReadInt ();
1799                         int b = r.ReadByte ();
1800                         res.is_byref = (b & 1) != 0;
1801                         res.is_pointer = (b & 2) != 0;
1802                         res.is_primitive = (b & 4) != 0;
1803                         res.is_valuetype = (b & 8) != 0;
1804                         res.is_enum = (b & 16) != 0;
1805
1806                         int nested_len = r.ReadInt ();
1807                         res.nested = new long [nested_len];
1808                         for (int i = 0; i < nested_len; ++i)
1809                                 res.nested [i] = r.ReadId ();
1810
1811                         return res;
1812                 }
1813
1814                 internal long[] Type_GetMethods (long id) {
1815                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_METHODS, new PacketWriter ().WriteId (id));
1816
1817                         int n = r.ReadInt ();
1818                         long[] res = new long [n];
1819                         for (int i = 0; i < n; ++i)
1820                                 res [i] = r.ReadId ();
1821                         return res;
1822                 }
1823
1824                 internal long[] Type_GetFields (long id, out string[] names, out long[] types, out int[] attrs) {
1825                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELDS, new PacketWriter ().WriteId (id));
1826
1827                         int n = r.ReadInt ();
1828                         long[] res = new long [n];
1829                         names = new string [n];
1830                         types = new long [n];
1831                         attrs = new int [n];
1832                         for (int i = 0; i < n; ++i) {
1833                                 res [i] = r.ReadId ();
1834                                 names [i] = r.ReadString ();
1835                                 types [i] = r.ReadId ();
1836                                 attrs [i] = r.ReadInt ();
1837                         }
1838                         return res;
1839                 }
1840
1841                 internal PropInfo[] Type_GetProperties (long id) {
1842                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTIES, new PacketWriter ().WriteId (id));
1843
1844                         int n = r.ReadInt ();
1845                         PropInfo[] res = new PropInfo [n];
1846                         for (int i = 0; i < n; ++i) {
1847                                 res [i] = new PropInfo ();
1848                                 res [i].id = r.ReadId ();
1849                                 res [i].name = r.ReadString ();
1850                                 res [i].get_method = r.ReadId ();
1851                                 res [i].set_method = r.ReadId ();
1852                                 res [i].attrs = r.ReadInt ();
1853                         }
1854
1855                         return res;
1856                 }
1857
1858                 internal long Type_GetObject (long id) {
1859                         return SendReceive (CommandSet.TYPE, (int)CmdType.GET_OBJECT, new PacketWriter ().WriteId (id)).ReadId ();
1860                 }
1861
1862                 internal ValueImpl[] Type_GetValues (long id, long[] fields, long thread_id) {
1863                         int len = fields.Length;
1864                         PacketReader r;
1865                         if (thread_id != 0)
1866                                 r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES_2, new PacketWriter ().WriteId (id).WriteId (thread_id).WriteInt (len).WriteIds (fields));
1867                         else
1868                                 r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
1869
1870                         ValueImpl[] res = new ValueImpl [len];
1871                         for (int i = 0; i < len; ++i)
1872                                 res [i] = r.ReadValue ();
1873                         return res;
1874                 }                       
1875
1876                 internal void Type_SetValues (long id, long[] fields, ValueImpl[] values) {
1877                         SendReceive (CommandSet.TYPE, (int)CmdType.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
1878                 }
1879
1880                 internal string[] Type_GetSourceFiles (long id, bool return_full_paths) {
1881                         var r = SendReceive (CommandSet.TYPE, return_full_paths ? (int)CmdType.GET_SOURCE_FILES_2 : (int)CmdType.GET_SOURCE_FILES, new PacketWriter ().WriteId (id));
1882                         int len = r.ReadInt ();
1883                         string[] res = new string [len];
1884                         for (int i = 0; i < len; ++i)
1885                                 res [i] = r.ReadString ();
1886                         return res;
1887                 }
1888
1889                 internal bool Type_IsAssignableFrom (long id, long c_id) {
1890                         return SendReceive (CommandSet.TYPE, (int)CmdType.IS_ASSIGNABLE_FROM, new PacketWriter ().WriteId (id).WriteId (c_id)).ReadByte () > 0;
1891                 }
1892
1893                 internal CattrInfo[] Type_GetCustomAttributes (long id, long attr_type_id, bool inherit) {
1894                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_CATTRS, new PacketWriter ().WriteId (id).WriteId (attr_type_id));
1895                         return ReadCattrs (r);
1896                 }
1897
1898                 internal CattrInfo[] Type_GetFieldCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
1899                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_FIELD_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
1900                         return ReadCattrs (r);
1901                 }
1902
1903                 internal CattrInfo[] Type_GetPropertyCustomAttributes (long id, long field_id, long attr_type_id, bool inherit) {
1904                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.GET_PROPERTY_CATTRS, new PacketWriter ().WriteId (id).WriteId (field_id).WriteId (attr_type_id));
1905                         return ReadCattrs (r);
1906                 }
1907
1908                 public long[] Type_GetMethodsByNameFlags (long id, string name, int flags, bool ignoreCase) {
1909                         flags |= ignoreCase ? (int)BindingFlagsExtensions.BINDING_FLAGS_IGNORE_CASE : 0;
1910                         PacketReader r = SendReceive (CommandSet.TYPE, (int)CmdType.CMD_TYPE_GET_METHODS_BY_NAME_FLAGS, new PacketWriter ().WriteId (id).WriteString (name).WriteInt (flags));
1911                         int len = r.ReadInt ();
1912                         long[] res = new long [len];
1913                         for (int i = 0; i < len; ++i)
1914                                 res [i] = r.ReadId ();
1915                         return res;
1916                 }
1917                 /*
1918                  * EVENTS
1919                  */
1920
1921                 internal int EnableEvent (EventType etype, SuspendPolicy suspend_policy, List<Modifier> mods) {
1922                         var w = new PacketWriter ().WriteByte ((byte)etype).WriteByte ((byte)suspend_policy);
1923                         if (mods != null) {
1924                                 if (mods.Count > 255)
1925                                         throw new NotImplementedException ();
1926                                 w.WriteByte ((byte)mods.Count);
1927                                 foreach (Modifier mod in mods) {
1928                                         if (mod is CountModifier) {
1929                                                 w.WriteByte ((byte)ModifierKind.COUNT);
1930                                                 w.WriteInt ((mod as CountModifier).Count);
1931                                         } else if (mod is LocationModifier) {
1932                                                 w.WriteByte ((byte)ModifierKind.LOCATION_ONLY);
1933                                                 w.WriteId ((mod as LocationModifier).Method);
1934                                                 w.WriteLong ((mod as LocationModifier).Location);
1935                                         } else if (mod is StepModifier) {
1936                                                 w.WriteByte ((byte)ModifierKind.STEP);
1937                                                 w.WriteId ((mod as StepModifier).Thread);
1938                                                 w.WriteInt ((mod as StepModifier).Size);
1939                                                 w.WriteInt ((mod as StepModifier).Depth);
1940                                         } else if (mod is ThreadModifier) {
1941                                                 w.WriteByte ((byte)ModifierKind.THREAD_ONLY);
1942                                                 w.WriteId ((mod as ThreadModifier).Thread);
1943                                         } else if (mod is ExceptionModifier) {
1944                                                 var em = mod as ExceptionModifier;
1945                                                 w.WriteByte ((byte)ModifierKind.EXCEPTION_ONLY);
1946                                                 w.WriteId (em.Type);
1947                                                 if (Version.MajorVersion > 2 || Version.MinorVersion > 0) {
1948                                                         /* This is only supported in protocol version 2.1 */
1949                                                         w.WriteBool (em.Caught);
1950                                                         w.WriteBool (em.Uncaught);
1951                                                 } else if (!em.Caught || !em.Uncaught) {
1952                                                         throw new NotSupportedException ("This request is not supported by the protocol version implemented by the debuggee.");
1953                                                 }
1954                                         } else if (mod is AssemblyModifier) {
1955                                                 w.WriteByte ((byte)ModifierKind.ASSEMBLY_ONLY);
1956                                                 var amod = (mod as AssemblyModifier);
1957                                                 w.WriteInt (amod.Assemblies.Length);
1958                                                 foreach (var id in amod.Assemblies)
1959                                                         w.WriteId (id);
1960                                         } else if (mod is SourceFileModifier) {
1961                                                 w.WriteByte ((byte)ModifierKind.SOURCE_FILE_ONLY);
1962                                                 var smod = (mod as SourceFileModifier);
1963                                                 w.WriteInt (smod.SourceFiles.Length);
1964                                                 foreach (var s in smod.SourceFiles)
1965                                                         w.WriteString (s);
1966                                         } else {
1967                                                 throw new NotImplementedException ();
1968                                         }
1969                                 }
1970                         } else {
1971                                 w.WriteByte (0);
1972                         }
1973                         return SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.SET, w).ReadInt ();
1974                 }
1975
1976                 internal void ClearEventRequest (EventType etype, int req_id) {
1977                         SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR, new PacketWriter ().WriteByte ((byte)etype).WriteInt (req_id));
1978                 }                       
1979
1980                 internal void ClearAllBreakpoints () {
1981                         SendReceive (CommandSet.EVENT_REQUEST, (int)CmdEventRequest.CLEAR_ALL_BREAKPOINTS, new PacketWriter ());
1982                 }
1983                         
1984                 /*
1985                  * STACK FRAME
1986                  */
1987                 internal ValueImpl StackFrame_GetThis (long thread_id, long id) {
1988                         PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_THIS, new PacketWriter ().WriteId (thread_id).WriteId (id));
1989                         return r.ReadValue ();
1990                 }
1991
1992                 internal ValueImpl[] StackFrame_GetValues (long thread_id, long id, int[] pos) {
1993                         /* pos < 0 -> argument at pos (-pos) - 1 */
1994                         /* pos >= 0 -> local at pos */
1995                         int len = pos.Length;
1996                         PacketReader r = SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.GET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos));
1997
1998                         ValueImpl[] res = new ValueImpl [len];
1999                         for (int i = 0; i < len; ++i)
2000                                 res [i] = r.ReadValue ();
2001                         return res;
2002                 }
2003
2004                 internal void StackFrame_SetValues (long thread_id, long id, int[] pos, ValueImpl[] values) {
2005                         /* pos < 0 -> argument at pos (-pos) - 1 */
2006                         /* pos >= 0 -> local at pos */
2007                         int len = pos.Length;
2008                         SendReceive (CommandSet.STACK_FRAME, (int)CmdStackFrame.SET_VALUES, new PacketWriter ().WriteId (thread_id).WriteId (id).WriteInt (len).WriteInts (pos).WriteValues (values));
2009                 }
2010
2011                 /*
2012                  * ARRAYS
2013                  */
2014                 internal int[] Array_GetLength (long id, out int rank, out int[] lower_bounds) {
2015                         var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_LENGTH, new PacketWriter ().WriteId (id));
2016                         rank = r.ReadInt ();
2017                         int[] res = new int [rank];
2018                         lower_bounds = new int [rank];
2019                         for (int i = 0; i < rank; ++i) {
2020                                 res [i] = r.ReadInt ();
2021                                 lower_bounds [i] = r.ReadInt ();
2022                         }
2023                         return res;
2024                 }
2025
2026                 internal ValueImpl[] Array_GetValues (long id, int index, int len) {
2027                         var r = SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (len));
2028                         ValueImpl[] res = new ValueImpl [len];
2029                         for (int i = 0; i < len; ++i)
2030                                 res [i] = r.ReadValue ();
2031                         return res;
2032                 }
2033
2034                 internal void Array_SetValues (long id, int index, ValueImpl[] values) {
2035                         SendReceive (CommandSet.ARRAY_REF, (int)CmdArrayRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (index).WriteInt (values.Length).WriteValues (values));
2036                 }
2037
2038                 /*
2039                  * STRINGS
2040                  */
2041                 internal string String_GetValue (long id) {
2042                         return SendReceive (CommandSet.STRING_REF, (int)CmdStringRef.GET_VALUE, new PacketWriter ().WriteId (id)).ReadString ();
2043                 }                       
2044
2045                 /*
2046                  * OBJECTS
2047                  */
2048                 internal long Object_GetType (long id) {
2049                         return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_TYPE, new PacketWriter ().WriteId (id)).ReadId ();
2050                 }                       
2051
2052                 internal long Object_GetDomain (long id) {
2053                         return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_DOMAIN, new PacketWriter ().WriteId (id)).ReadId ();
2054                 }                       
2055
2056                 internal ValueImpl[] Object_GetValues (long id, long[] fields) {
2057                         int len = fields.Length;
2058                         PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_VALUES, new PacketWriter ().WriteId (id).WriteInt (len).WriteIds (fields));
2059
2060                         ValueImpl[] res = new ValueImpl [len];
2061                         for (int i = 0; i < len; ++i)
2062                                 res [i] = r.ReadValue ();
2063                         return res;
2064                 }
2065
2066                 internal void Object_SetValues (long id, long[] fields, ValueImpl[] values) {
2067                         SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.SET_VALUES, new PacketWriter ().WriteId (id).WriteInt (fields.Length).WriteIds (fields).WriteValues (values));
2068                 }
2069
2070                 internal bool Object_IsCollected (long id) {
2071                         return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.IS_COLLECTED, new PacketWriter ().WriteId (id)).ReadInt () == 1;
2072                 }                       
2073
2074                 internal long Object_GetAddress (long id) {
2075                         return SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_ADDRESS, new PacketWriter ().WriteId (id)).ReadLong ();
2076                 }                       
2077
2078                 internal ObjectRefInfo Object_GetInfo (long id) {
2079                         ObjectRefInfo res = new ObjectRefInfo ();
2080                         PacketReader r = SendReceive (CommandSet.OBJECT_REF, (int)CmdObjectRef.GET_INFO, new PacketWriter ().WriteId (id));
2081
2082                         res.type_id = r.ReadId ();
2083                         res.domain_id = r.ReadId ();
2084                         return res;
2085                 }
2086
2087         }
2088         
2089         class TcpConnection : Connection
2090         {
2091                 Socket socket;
2092                 
2093                 internal TcpConnection (Socket socket)
2094                 {
2095                         this.socket = socket;
2096                         //socket.SetSocketOption (SocketOptionLevel.IP, SocketOptionName.NoDelay, 1);
2097                 }
2098                 
2099                 internal EndPoint EndPoint {
2100                         get {
2101                                 return socket.RemoteEndPoint;
2102                         }
2103                 }
2104                 
2105                 protected override int TransportSend (byte[] buf, int buf_offset, int len)
2106                 {
2107                         return socket.Send (buf, buf_offset, len, SocketFlags.None);
2108                 }
2109                 
2110                 protected override int TransportReceive (byte[] buf, int buf_offset, int len)
2111                 {
2112                         return socket.Receive (buf, buf_offset, len, SocketFlags.None);
2113                 }
2114                 
2115                 protected override void TransportSetTimeouts (int send_timeout, int receive_timeout)
2116                 {
2117                         socket.SendTimeout = send_timeout;
2118                         socket.ReceiveTimeout = receive_timeout;
2119                 }
2120                 
2121                 protected override void TransportClose ()
2122                 {
2123                         socket.Close ();
2124                 }
2125         }
2126
2127         /* This is the interface exposed by the debugger towards the debugger agent */
2128         interface IEventHandler
2129         {
2130                 void Events (SuspendPolicy suspend_policy, EventInfo[] events);
2131
2132                 void VMDisconnect (int req_id, long thread_id, string vm_uri);
2133         }
2134 }