public BrokerMessage process(BrokerMessage request)
        {
            Data bodyData = Serializer.Serialize(request);
            log.debug(bodyData, "bodyData");

            Entity entity = new DataEntity(bodyData);
            String requestUri;
            if (null == _authenticator)
            {
                requestUri = "/_dynamic_/open/services";
            }
            else
            {
                if (_authenticator.AuthInt)
                {
                    requestUri = "/_dynamic_/auth-int/services";
                }
                else
                {
                    requestUri = "/_dynamic_/auth/services";
                }
            }
            HttpRequestAdapter requestAdapter = new HttpRequestAdapter(requestUri);
            requestAdapter.RequestEntity = entity;

            _httpDispatcher.post(requestAdapter, _authenticator, _responseHandler);
            return _responseHandler.getResponse();
        }
        ////////////////////////////////////////////////////////////////////////////
            
        // authenticator can be null 
        private HttpWebRequest buildGetRequest(HttpRequestAdapter requestAdapter, Authenticator authenticator)
        {

            String host = _networkAddress.getHostAddress();
            int port = _networkAddress.Port;

            String requestUri = requestAdapter.RequestUri;


            String uri = String.Format("http://{0}:{1}{2}", host, port, requestUri);
            log.debug(uri, "uri");

            HttpWebRequest answer = (HttpWebRequest)HttpWebRequest.Create(uri);
            answer.Method = "GET";


            // extra headers ... 
            {
                Dictionary<String, String> requestHeaders = requestAdapter.RequestHeaders;
                foreach (KeyValuePair<String, String> kvp in requestHeaders)
                {
                    answer.Headers[kvp.Key] = kvp.Value;

                }
                
            }

            if (null != authenticator)
            {
                String authorization = authenticator.getRequestAuthorization(answer.Method, requestUri, null);
                log.debug(authorization, "authorization");
                if (null != authorization)
                {
                    answer.Headers["Authorization"] = authorization;
                }

            }

            // vvv http://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx 

            answer.ServicePoint.Expect100Continue = false;

            // ^^^ http://msdn.microsoft.com/en-us/library/system.net.webrequest.getrequeststream.aspx#Y600 

            return answer;


        }
        ////////////////////////////////////////////////////////////////////////////

        // authenticator can be null
        private HttpWebRequest buildPostRequest(HttpRequestAdapter requestAdapter, Authenticator authenticator)
        {
            String host = _networkAddress.getHostAddress();
            int port = _networkAddress.Port;

            String requestUri = requestAdapter.RequestUri;


            String uri = String.Format("http://{0}:{1}{2}", host, port, requestUri);
            log.debug(uri, "uri");

            HttpWebRequest answer = (HttpWebRequest)HttpWebRequest.Create(uri);
            answer.Method = "POST";


            // extra headers ... 
            {
                Dictionary<String, String> requestHeaders = requestAdapter.RequestHeaders;
                foreach (KeyValuePair<String, String> kvp in requestHeaders)
                {
                    answer.Headers[kvp.Key] = kvp.Value;

                }

            }

            if (null != authenticator)
            {
                String authorization = authenticator.getRequestAuthorization(answer.Method, requestUri, null);
                log.debug(authorization, "authorization");
                if (null != authorization)
                {
                    answer.Headers["Authorization"] = authorization;
                }

            }

            Entity requestEntity = requestAdapter.RequestEntity;
            Stream destinationStream = answer.GetRequestStream();
            bool failed = true;
            try
            {
                // vvv http://haacked.com/archive/2004/05/15/http-web-request-expect-100-continue.aspx 

                answer.ServicePoint.Expect100Continue = false;

                Entity entity = requestAdapter.RequestEntity;
                StreamHelper.write(entity.getContentLength(), entity.getContent(), answer.GetRequestStream());

                // ^^^ http://msdn.microsoft.com/en-us/library/system.net.webrequest.getrequeststream.aspx#Y600 

                failed = false;
            }
            finally
            {
                bool swallowExceptions = false;
                if( failed ) { 
                    swallowExceptions = true;
                }

                StreamHelper.close(requestEntity.getContent(), swallowExceptions, this);
                StreamHelper.close(destinationStream, swallowExceptions, this);
            }

            return answer;
        }
        public void post(HttpRequestAdapter requestAdapter, HttpResponseHandler responseAdapter)
        {
            HttpWebRequest request = buildPostRequest(requestAdapter, null);
            int statusCode = dispatch(request, null, responseAdapter);

            if (statusCode < 200 || statusCode > 299)
            {
                BaseException e = new BaseException(this, HttpStatus.getReason(statusCode));
                e.FaultCode = statusCode;
                String requestUri = requestAdapter.RequestUri;
                e.addContext("requestUri", requestUri);
                throw e;
            }

        }
        ////////////////////////////////////////////////////////////////////////////

        public void get(HttpRequestAdapter requestAdapter, Authenticator authenticator, HttpResponseHandler responseAdapter)
        {
            HttpWebRequest request = buildGetRequest(requestAdapter, authenticator);
            int statusCode = dispatch(request, authenticator, responseAdapter);

            if (401 == statusCode)
            {
                request = buildGetRequest(requestAdapter, authenticator);
                statusCode = dispatch(request, authenticator, responseAdapter);
            }

            if (statusCode < 200 || statusCode > 299)
            {
                BaseException e = new BaseException(this, HttpStatus.getReason(statusCode));
                e.FaultCode = statusCode;
                String requestUri = requestAdapter.RequestUri;
                e.addContext("requestUri", requestUri);
                throw e;
            }

        }