private static void Stream(int id, NetworkStream stream, int streamId)
        {
            Stream streamToSend = waitingStreams [streamId];

            bool closed = false;
            while (!closed) {
                StreamActionMessage message = stream.DataReceive<StreamActionMessage> ();

                try {
                    switch (message.Action) {
                    case StreamAction.CanRead:
                        bool canRead = streamToSend.CanRead;
                        stream.ActionFinishedSuccess ();
                        stream.DataSend (canRead);
                        break;
                    case StreamAction.CanSeek:
                        bool canSeek = streamToSend.CanSeek;
                        stream.ActionFinishedSuccess ();
                        stream.DataSend (canSeek);
                        break;
                    case StreamAction.CanWrite:
                        bool canWrite = streamToSend.CanWrite;
                        stream.ActionFinishedSuccess ();
                        stream.DataSend (canWrite);
                        break;
                    case StreamAction.Length:
                        long length = streamToSend.Length;
                        stream.ActionFinishedSuccess ();
                        stream.DataSend (length);
                        break;
                    case StreamAction.GetPosition:
                        long position = streamToSend.Position;
                        stream.ActionFinishedSuccess ();
                        stream.DataSend (position);
                        break;
                    case StreamAction.SetPosition:
                        streamToSend.Position = message.Position;
                        stream.ActionFinishedSuccess ();
                        break;
                    case StreamAction.Close:
                        closed = true;
                        streamToSend.Close ();
                        stream.DataSend (new OperationResultMessage (true));
                        break;
                    case StreamAction.Flush:
                        streamToSend.Flush ();
                        stream.DataSend (new OperationResultMessage (true));
                        break;
                    case StreamAction.Read:
                        byte[] buffer = new byte[Convert.ToInt32 (message.Size)];
                        streamToSend.Read (buffer, 0, Convert.ToInt32 (message.Size));
                        stream.DataSend (buffer.Take (Convert.ToInt32 (message.Size)).ToArray ());
                        stream.DataSend (new OperationResultMessage (true));
                        break;
                    case StreamAction.Seek:
                        long seeked = streamToSend.Seek (message.Offset, message.Position == 0 ? SeekOrigin.Begin : (message.Position == 1 ? SeekOrigin.Current : SeekOrigin.End));
                        stream.DataSend (new OperationResultMessage (true));
                        stream.DataSend (seeked);
                        break;
                    case StreamAction.SetLength:
                        streamToSend.SetLength (message.Size);
                        stream.DataSend (new OperationResultMessage (true));
                        break;
                    case StreamAction.Write:
                        byte[] data = stream.DataReceive<byte[]> ();
                        streamToSend.Write (data, 0, data.Length);
                        stream.DataSend (new OperationResultMessage (true));
                        break;
                    default:
                        throw (new NotImplementedException ());
                    }
                } catch (Exception ex) {
                    stream.DataSend (new OperationResultMessage (ex));
                }
            }

            lock (waitingStreams) {
                waitingStreams.Remove (id);
            }

            ServiceStop (id, null);
        }