static void Main(string[] args)
        {
            IPEndPoint ipep = new IPEndPoint(IPAddress.Parse("127.0.0.1"), 21344);
            Socket server = new Socket(AddressFamily.InterNetwork, SocketType.Stream, ProtocolType.Tcp);
            server.Bind(ipep);
            server.Listen(10);
            Socket client = server.Accept();

            NetworkStream ns = new NetworkStream(client, true);
            DataSocketWriter dsw = new DataSocketWriter(ns);

            List<Value> list_values = new List<Value>();
            list_values.Add(Value.Create("A string value"));
            list_values.Add(Value.Create(1234));
            list_values.Add(Value.Create(4321.001));
            ValueVector val_vector = new ValueVector { values = list_values.ToArray() };

            dsw.Send(val_vector);

            while(true)
            {
                // server needs to halt here, else process exit and things are not sent
                Thread.Sleep(0);
            }
        }
        public Value ReadValue()
        {
            Value val = null;
            CsFaslTags type = (CsFaslTags)_br.ReadByte();
            switch(type)
            {
                case CsFaslTags.CsFaslTagUndefined:
                    val = new Value { type = CsFaslTags.CsFaslTagUndefined };
                    break;

                case CsFaslTags.CsFaslTagNull:
                    val = new Value { type = CsFaslTags.CsFaslTagNull };
                    break;

                case CsFaslTags.CsFaslTagTrue:
                    val = new Value { type = CsFaslTags.CsFaslTagTrue };
                    break;

                case CsFaslTags.CsFaslTagFalse:
                    val = new Value { type = CsFaslTags.CsFaslTagFalse };
                    break;

                case CsFaslTags.CsFaslTagProxy:
                    int id = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    val = new Value { type = CsFaslTags.CsFaslTagProxy, intPayload = id };
                    break;

                case CsFaslTags.CsFaslTagCode:
                    int codesz = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    Debug.Assert(false);
                    // TODO
                    break;

                case CsFaslTags.CsFaslTagVector:
                    int vectorsz = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    ValueVector vector = new ValueVector();
                    vector.values = new Value[vectorsz];
                    for(int i = 0; i < vectorsz; i++)
                        vector.values[i] = this.ReadValue();
                    val = vector;
                    break;

                case CsFaslTags.CsFaslTagObject:
                    CsFaslTags undefined = (CsFaslTags)_br.ReadByte();// TODO("handle class names!")
                    int prop_count = IPAddress.NetworkToHostOrder(_br.ReadInt32());

                    ValueObject obj = new ValueObject();
                    obj.props = new Dictionary<string, Value>(prop_count);

                    for(int i = 0; i < prop_count; i++)
                    {
                        Value vprop = this.ReadValue();
                        Value vvalue = this.ReadValue();

                        if(vprop.type == CsFaslTags.CsFaslTagSymbol)
                        {
                            string key = (vprop as ValueSymbol).sym;
                            obj.props.Add(key, vvalue);
                        }
                        else
                        {
                            Debug.Assert(false);
                        }
                    }
                    val = obj;
                    break;

                case CsFaslTags.CsFaslTagSymbol:
                    int symID = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    val = new ValueSymbol { sym = _id2symbol[symID] };
                    break;

                case CsFaslTags.CsFaslTagString:
                    int strsz = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    var bytes = _br.ReadBytes(strsz);
                    val = new ValueString { str = Encoding.UTF8.GetString(bytes) };
                    break;

                case CsFaslTags.CsFaslTagInteger:
                    val = new Value { type = CsFaslTags.CsFaslTagInteger, intPayload = IPAddress.NetworkToHostOrder(_br.ReadInt32()) };
                    break;

                case CsFaslTags.CsFaslTagFloat:
                    long f = _br.ReadInt64();
                    val = new ValueFloat { d = BitConverter.Int64BitsToDouble(IPAddress.NetworkToHostOrder(f)) };
                    break;

                case CsFaslTags.CsFaslTagBytes:
                    int bytessz = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    val = new ValueBytes { bytes = _br.ReadBytes(bytessz) };
                    break;

                case CsFaslTags.CsFaslTagDate:
                    long ft = IPAddress.NetworkToHostOrder(_br.ReadInt64());
                    val = new ValueDate { dt = DateTime.FromFileTime(ft) };
                    break;

                case CsFaslTags.CsFaslTagColor:
                    val = new Value { type = CsFaslTags.CsFaslTagColor, intPayload = IPAddress.NetworkToHostOrder(_br.ReadInt32()) };
                    break;

                case CsFaslTags.CsFaslTagLength:
                    val = new ValueLength
                    {
                        n = IPAddress.NetworkToHostOrder(_br.ReadInt32()),
                        u = IPAddress.NetworkToHostOrder(_br.ReadInt32())
                    };
                    break;

                case CsFaslTags.CsFaslTagTuple:
                    Value val_name = ReadValue();
                    Debug.Assert(val_name.type == CsFaslTags.CsFaslTagString);

                    int tuple_sz = IPAddress.NetworkToHostOrder(_br.ReadInt32());
                    ValueTuple val_tuple = new ValueTuple { name = val_name, values = new Value[tuple_sz] };
                    for(int i = 0; i < tuple_sz; i++)
                        val_tuple.values[i] = ReadValue();
                    val = val_tuple;
                    break;

                case CsFaslTags.CsFaslTagAngle:
                    val = new ValueAngle
                    {
                        n = IPAddress.NetworkToHostOrder(_br.ReadInt32()),
                        u = IPAddress.NetworkToHostOrder(_br.ReadInt32())
                    };
                    break;

                case CsFaslTags.CsFaslTagDuration:
                    long l = IPAddress.NetworkToHostOrder(_br.ReadInt64());
                    double d = BitConverter.Int64BitsToDouble(l);
                    val = new ValueDuration { dur = TimeSpan.FromSeconds(d) };
                    break;

                default:
                    Debug.Assert(false);
                    break;
            }
            return val;
        }