protected void SendReply(ProcessState state, MemoryStream reply, int replyLength)
		{
			SocketError socketError;
			try
			{
				int replySize = replyLength + 4;
				if (state.messageId != 0) //if the client sent a message Id, we need to send it back
				{
					replySize += 2;
				}

				state.replyBuffer = bufferPool.GetItem();
				if (state.replyBuffer.Item.Position > 0)
				{

					if (log.IsErrorEnabled)
						log.ErrorFormat("Buffer from pool had position {0}!. Resetting position and length.", state.replyBuffer.Item.Position.ToString("N0"));
					state.replyBuffer.Item.Seek(0, SeekOrigin.Begin);
					state.replyBuffer.Item.SetLength(0);
				}
				if (UseDefaultReplyHeader)
				{
					state.replyBuffer.Item.Write(BitConverter.GetBytes(GetNetworkOrdered(replySize, useNetworkOrder)), 0, 4);
					if (state.messageId != 0)
					{
						state.replyBuffer.Item.Write(BitConverter.GetBytes(GetNetworkOrdered(state.messageId, useNetworkOrder)), 0, 2);
					}
					state.replyBuffer.Item.Write(reply.GetBuffer(), 0, replyLength);
				}
				if (state.socket.Connected)
				{
					state.socket.BeginSend(state.replyBuffer.Item.GetBuffer(), 0, replySize, SocketFlags.None, out socketError, replyCallBack, state);
					if (socketError != SocketError.Success)
					{
						if (log.IsErrorEnabled)
							log.ErrorFormat("Error sending reply to {0}: {1}.", state.remoteEndpoint, socketError);
						if (!state.socket.Connected)
						{
							state.socket.Shutdown(SocketShutdown.Both);
							state.socket.Close();
						}
						RemoveConnection(state.remoteEndpoint);
					}
				}
				else
				{

					if (log.IsErrorEnabled)
						log.ErrorFormat("Connection dropped before reply sent to {0}", state.remoteEndpoint);
					bufferPool.ReleaseItem(state.replyBuffer);
					state.replyBuffer = null;
				}
			}
			catch (SocketException ex)
			{
				if (state.replyBuffer != null)
				{
					bufferPool.ReleaseItem(state.replyBuffer);
					state.replyBuffer = null;
				}

				if (log.IsErrorEnabled)
					log.ErrorFormat("Socket Exception during SendReply to {0}: {1}.  Removing connection.", state.remoteEndpoint, ex);
				try
				{
					if (state.socket.Connected)
					{
						state.socket.Shutdown(SocketShutdown.Both);
						state.socket.Close();
					}
					RemoveConnection(state.remoteEndpoint);
				}
				catch (Exception exc)
				{

					if (log.IsErrorEnabled)
						log.ErrorFormat("Socket Server Exception attempted to remove connection in SendReply exception cleanup: {0}", exc);
				}
			}
			catch (ObjectDisposedException)
			{
				if (state.replyBuffer != null)
				{
					bufferPool.ReleaseItem(state.replyBuffer);
					state.replyBuffer = null;
				}
			}
			catch (Exception ex)
			{
				if (state.replyBuffer != null)
				{
					bufferPool.ReleaseItem(state.replyBuffer);
					state.replyBuffer = null;
				}

				if (log.IsErrorEnabled)
					log.ErrorFormat("Socket Server Exception during SendReply to {0}: {1}.", state.remoteEndpoint, ex);
			}
		}
		private void SendReply(ProcessState state, MemoryStream replyStream)
		{
			int replyLength;
			if (replyStream == null)
			{
				replyStream = emptyReplyStream;
				replyLength = 4;
			}
			else
			{
				replyLength = (int)replyStream.Length;
			}
			SendReply(state, replyStream, replyLength);
		}
		protected void ProcessCall(ProcessState state)
		{
			MemoryStream messageStream = null;
			MemoryStream replyStream = null;

			MessageState message = null;
			try
			{
				messageStream = state.message.Item;

				if (asyncMessageHandler != null)
				{
					message = new MessageState
					{
						CommandId = state.commandId,
						Message = messageStream,
						Length = state.messageLength,
						ClientIP = state.remoteEndpoint
					};

					asyncMessageHandler.BeginHandleMessage(message, (asyncResult) =>
					{
						try
						{
							MemoryStream reply = asyncMessageHandler.EndHandleMessage(asyncResult);
							CompleteProcessCall(state, reply); //not APM
						}
						catch (Exception exc)
						{
							if (log.IsErrorEnabled)
								log.Error(exc);
						}
					});

					return; //very important
				}

				if (AsynMessageHandler != null)
				{
					replyStream = AsynMessageHandler.Invoke((int)state.commandId, messageStream, state.remoteEndpoint.Address);
				}
				else if (MessageHandler != null)
				{
					replyStream = MessageHandler.HandleMessage((int)state.commandId, messageStream, state.messageLength);
				}
			}
			catch (Exception ex)
			{
				try
				{
					string endPoint = state.socket.RemoteEndPoint.ToString();

					if (log.IsErrorEnabled)
						log.ErrorFormat("Socket Server Exception handling message from {0}: {1}.", endPoint, ex);
					replyStream = null;
				}
				catch (ObjectDisposedException) { }
			}
			finally
			{
				if (message != null)
				{
					message.Message = null;
					message.Length = 0;
				}
				bufferPool.ReleaseItem(state.message);
				state.message = null;
			}

			CompleteProcessCall(state, replyStream);
		}
		private void CompleteProcessCall(ProcessState state, MemoryStream replyStream)
		{
			if (countersInitialized)
			{
				avgHandlerTimeBase.Increment();
			}

			if (state.sendReply)
			{
				SendReply(state, replyStream);
			}
		}
		protected void HandleCompleteConnectionState(ConnectionState state)
		{
			bool sendReply = false;

			byte[] buff = state.messageBuffer.GetBuffer();
			short commandId = 0;
			short messageId;

			try
			{
				if (useNetworkOrder)
				{
					messageId = GetHostOrdered(BitConverter.ToInt16(buff, 6), true);
					commandId = GetHostOrdered(BitConverter.ToInt16(buff, 8), true);
				}
				else
				{
					commandId = BitConverter.ToInt16(buff, 6);
					messageId = BitConverter.ToInt16(buff, 8);
				}
				sendReply = BitConverter.ToBoolean(buff, 10);
				if (countersInitialized)
				{
					if (sendReply)
						syncPerSecCounter.Increment();
					else
						onewayPerSecCounter.Increment();
				}
			}
			catch (Exception e)
			{
				if (log.IsErrorEnabled)
					log.ErrorFormat("Socket Server Exception extracting message info from {0}: {1} . Resetting connection state.", state.remoteEndPoint, e);
				ResetConnectionStateMessageBuffer(state);
				return;
			}

			if (!CheckForMessageTerminator(buff, state.messageSize))
			{
				if (log.IsErrorEnabled)
					log.ErrorFormat("Message without end terminator found from {0}. Resetting connection state.", state.remoteEndPoint);

				ResetConnectionStateMessageBuffer(state);
				return;
			}




			try
			{
				#region if replychannel
				if (commandId == SocketServer.ReplyChannelCreationCommandId)
				{
					try
					{
						byte[] justAddress = new byte[4];
						Array.Copy(buff, 11, justAddress, 0, 4);
						IPAddress sendChannelAddress = new IPAddress(justAddress);
						IPEndPoint sendChannelEndPoint = new IPEndPoint(sendChannelAddress, BitConverter.ToInt32(buff, 15));

						connections[sendChannelEndPoint].ReplySocket = state.WorkSocket;
						SendReplyChannelConfirmation(state.WorkSocket, true);
					}
					catch (Exception ex)
					{
						if (log.IsErrorEnabled)
							log.ErrorFormat("Socket Server Exception creating reply socket for {0}: {1}", state.remoteEndPoint, ex);
						SendReplyChannelConfirmation(state.WorkSocket, false);
					}
				}
				#endregion
				else
				{
					ResourcePoolItem<MemoryStream> messageBuffer = bufferPool.GetItem();
					ProcessState processState = null;
					try
					{
						messageBuffer.Item.Write(buff, 11, state.messageSize - 13);
						messageBuffer.Item.Seek(0, SeekOrigin.Begin);

						processState = new ProcessState(state.ReplySocket, commandId, messageId, sendReply, messageBuffer, state.messageSize - 13);

						if (sendReply)
						{
							SyncMessagePort.Post(processState);
						}
						else
						{

							OnewayMessagePort.Post(processState);
						}
					}
					catch (Exception ex)
					{

						if (log.IsErrorEnabled)
							log.ErrorFormat("Socket Server Exception enqueueing message work item for {0}: {1}. Releasing buffer.", state.remoteEndPoint, ex);
						bufferPool.ReleaseItem(messageBuffer);
					}
				}

			}
			catch (Exception ex)
			{

				if (log.IsErrorEnabled)
					log.ErrorFormat("Socket Server Exception while handling message for {0}: {1}. Resetting message state.", state.remoteEndPoint, ex);
				ResetConnectionStateMessageBuffer(state);
				return;
			}
		}