/// <summary>
        /// Runs the server in its own Thread.
        /// </summary>
        private void ThreadMain()
        {
            Exception workException = null;
            try
            {
                Debug.Print("Accepted Socket, workerid: " + this.WorkerID.ToString());
                _SocketAcceptedHandler(this);
                if (_ConnectionSocket.Poll(-1, SelectMode.SelectRead))
                {
                    // Create buffer and receive raw bytes.

                    byte[] firstLanPacket = new byte[_LanPacketByteCount];
                    int count = 0;
                    SocketFlags socketFlags = new SocketFlags();
                    count = _ConnectionSocket.Receive(firstLanPacket, count, _ConnectionSocket.Available - count, socketFlags);
                    if (firstLanPacket[0] == 0)
                    {
                        Debug.Print("empty request, count: " + count.ToString());
                        workException = new Exception("Empty Packet found" + this.WorkerID.ToString());// exception not thrown just sent back
                    }
                    else
                    {
                        string rawHeader = new string(Encoding.UTF8.GetChars(firstLanPacket));
                        Hashtable headerFields = null;
                        int contentStart = -1;
                        EnumRequestType requestType = EnumRequestType.Get;// check for get first
                        BaseRequest.LoadHeader(firstLanPacket, count, out contentStart, out headerFields, out requestType);
                        BaseRequest request = null;
                        try
                        {
                            if (requestType == EnumRequestType.Get)
                            {
                                request = new BaseRequest(firstLanPacket, count, 0, headerFields, requestType);// no content
                            }
                            else
                            {
                                if (requestType == EnumRequestType.Post)
                                {
                                    request = new PostRequest(firstLanPacket, count, 0, headerFields, requestType, _ConnectionSocket, GetMoreBytes);// todo put delegate
                                }
                                else
                                {
                                    throw new NotImplementedException("Http PUT is not implemented.");
                                }
                            }
                        }
                        catch (Exception ex)
                        {
                            //return server 500;
                            workException = ex;
                            SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID);
                            request = null;
                        }
            //                            ConsoleWrite.CollectMemoryAndPrint(true, this.WorkerID);
                        //requestQueue.Enqueue(request);todo
                        if (request != null)
                        {
                            string requestMimeType = GetMimeType(request.Uri);
                            Debug.Print("Request MIME Type: " + requestMimeType);
                            if (requestMimeType.Length > 0)
                            {   // file request
                                try
                                {
                                    string fullFilePath = SDCard.GetFullPathFromUri(request.BaseUri);
                                    Debug.Print("File Request received:" + fullFilePath);
                                    // send start
                                    long fileSize = SDCard.GetFileSize(fullFilePath);
                                    if (fileSize > 0)
                                    {
                                        int maxAge = GetMaxAgeFromMimeType(requestMimeType);
                                        string header = HttpGeneral.GetHttpHeader(fileSize, requestMimeType, maxAge);
                                        byte[] returnBytes = Encoding.UTF8.GetBytes(header);
                                        _ConnectionSocket.Send(returnBytes, returnBytes.Length, SocketFlags.None);
                                        SDCard.ReadInChunks(fullFilePath, _ConnectionSocket);// boolean result doesnt really do much so ignore.
                                    }
                                    else
                                    {
                                        SendErrorResponse(_ConnectionSocket, SupportedErrors.FileNotFound, request, null, this.WorkerID);
                                    }
                                }
                                catch (Exception ex)
                                {
                                    //return server 500;
                                    workException = ex;
                                    SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID);
                                }
                            }
                            else
                            {// page request
                                if (_ResponseHandler != null)
                                {
                                    try
                                    {
                                        string response = _ResponseHandler(request);
                                        byte[] returnBytes = Encoding.UTF8.GetBytes(response);
                                        _ConnectionSocket.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None);
                                    }
                                    catch (Exception ex)
                                    {
                                        //return server 500;
                                        workException = ex;
                                        SendErrorResponse(_ConnectionSocket, SupportedErrors.ServerError, request, ex, this.WorkerID);
                                    }
                                }
                            }
                        }
                    }
                }
            }// using statement can throw in the dispose.
            catch (Exception ex)
            {
                workException = ex;
                Debug.Print("Exception, workerid: " + this.WorkerID.ToString() + ", ex: " + ex.Message);
            }
            finally
            {
                if (_ConnectionSocket != null)
                {
                    ((IDisposable)_ConnectionSocket).Dispose();
                }
                _WorkFinishedHandler(workException, this);
            }
        }
 private void SendErrorResponse(Socket connectionSocket, SupportedErrors errorType, BaseRequest request, Exception ex, int workerID)
 {
     string errorTypeText = "";
     if (errorType == SupportedErrors.ServerError)
     {
         errorTypeText = "500 Server Error";
         Debug.Print("SendErrorResponse, workerid: " + workerID.ToString() + ", ex: " + ex.Message + " " + errorTypeText);
     }
     else
     {
         errorTypeText = "404 File not found";
         Debug.Print("SendErrorResponse, workerid: " + workerID.ToString() + " " + errorTypeText);
     }
     string header = "";
     string content = HtmlGeneral.HtmlStart + "<h1>" + errorTypeText + "</h1>" + "<h3>Uri: " + request.Uri + "</h3>";
     if (ex != null)
     {
         content += "<p>Error: " + ex.Message + "</p>";
     }
     content += HtmlGeneral.HtmlEnd;
     if (errorType == SupportedErrors.ServerError)
     {
         header = HttpGeneral.Get500Header(content.Length);
     }
     else
     {
         header = HttpGeneral.Get404Header(content.Length);
     }
     byte[] returnBytes = Encoding.UTF8.GetBytes(header + content);
     connectionSocket.Send(returnBytes, 0, returnBytes.Length, SocketFlags.None);
 }