/// <summary>
        /// Callback to accept tcp connections
        /// </summary>
        /// <param name="result">Async Result/State</param>
        private void OnAccept(IAsyncResult result)
        {
            if (!IsListening) return;
            if (socket != null)
            {
                if (!socket.IsBound) return;
                if (!result.IsCompleted) return;
                try
                {
                    if (socket != ((Socket)result.AsyncState)) return;
                    Socket accept_socket = (Socket)result.AsyncState;
                    if (accept_socket == null) return;
                    if (!accept_socket.IsBound) return;
                    Socket client_socket = socket.EndAccept(result);
                    if (!client_socket.Connected) return;
                    //Console.WriteLine("new client connected.");
                    Client client = new Client(client_socket);
                    client.RequestReceived += delegate(Client requester, Request request)
                    {
                        //TODO check if threading in this case is overkill
                        //System.Threading.Thread thread = new System.Threading.Thread(delegate()
                        //{
                            if (RequestReceived != null)
                                RequestReceived(this, request);
                        //});
                        //thread.Start();
                    };
                    clients.Add(client);
                    client.StartReceiving();
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Error accepting connection: " + ex.Message);
                }
                try
                {
                    AsyncCallback event_accept = new AsyncCallback(OnAccept);
                    socket.BeginAccept(event_accept, socket);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("Fatal Error accepting connection: " + ex.Message);
                }

            }
            else Console.WriteLine("Accept on tcp socket aborted.");
        }
            public Request(string header_string,string body_string,Client request_client)
            {
                if (request_client == null)
                    is_valid = false;
                this.request_client = request_client;
                //Console.WriteLine("Initiating Request from request string: "+request_string);
                string[] seps = {"\r\n"};
                string[] header_lines = header_string.Split(seps,StringSplitOptions.None);
                if (header_lines.Length > 0)
                {
                    string[] seps2 ={ " " };
                    string[] header_line_parts = header_lines[0].Split(seps2, StringSplitOptions.RemoveEmptyEntries);
                    if (header_line_parts.Length >= 3)
                    {
                        method = header_line_parts[0];
                        url = header_line_parts[1];
                        version = header_line_parts[2];

                        int i = 0;
                        foreach (string line in header_lines) //i know i should skip the first line , but this is so convenient
                        {//read header values into our headers list
                            if (line == "\r\n")
                                break;
                            if (i++ != 0)
                            {//skipping the first line which is not a header
                                int colon_pos = line.IndexOf(":");
                                if (colon_pos != -1)
                                {
                                    headers.Add(line.Substring(0, colon_pos), line.Substring(colon_pos + 1).Trim());
                                }
                                else
                                {
                                    Console.WriteLine("invalid header line without a colon");
                                    is_valid = false;
                                }

                            }
                        }

                        //retrieve values from post body if type== x-www-form-url-encoded
                        //get query values from url if present ?
                        body = body_string;
                        //check if post and query values were given in body
                        string content_type = headers.Get("Content-Type");
                        if (content_type == "application/x-www-form-urlencoded")
                        {
                            //Console.WriteLine("body: " + body_string);
                            ParseValues(body_string, true);
                        }
                        //check if url contains query values
                        int query_start=url.IndexOf("?");
                        if (query_start != -1)
                        {
                            if (query_start + 1 < url.Length)
                            {
                                string query = url.Substring(query_start + 1);
                                ParseValues(query, false);
                            }
                            url = url.Substring(0, query_start);
                        }

                        //check headers for basic authentification
                        string auth_value = headers.Get("Authorization");
                        if (!string.IsNullOrEmpty(auth_value))
                        {
                            string[] seps3 = { " "};
                            string[] fields = auth_value.Split(seps3,StringSplitOptions.RemoveEmptyEntries);
                            if (fields.Length == 2)
                            {
                                byte[] decode = Convert.FromBase64String(fields[1]);
                                string creds = System.Text.Encoding.Default.GetString(decode);
                                //Console.WriteLine("creds: "+creds);
                                int colon_pos2 = creds.IndexOf(":");
                                if (colon_pos2 != -1)
                                {
                                    auth_username = creds.Substring(0, colon_pos2);
                                    auth_password = creds.Substring(colon_pos2 + 1);
                                }
                            }
                        }

                    }
                    else
                    {
                        Console.WriteLine("first request line had not enough fields");
                        is_valid = false;
                    }
                }
                else
                {
                    Console.WriteLine("header is empty");
                    is_valid = false;
                }
            }