docs: function(config) {        
          // apply default config - proxy host may have changed
          var defaultConfig = OpenLayers.Util.extend(
              this.DEFAULT_CONFIG,
              {proxy: OpenLayers.ProxyHost}
          );
          config = config || {};
          config.headers = config.headers || {};
          config = OpenLayers.Util.applyDefaults(config, defaultConfig);
          config.headers = OpenLayers.Util.applyDefaults(config.headers, defaultConfig.headers);
          // Always set the "X-Requested-With" header to signal that this request
          // was issued through the XHR-object. Since header keys are case 
          // insensitive and we want to allow overriding of the "X-Requested-With"
          // header through the user we cannot use applyDefaults, but have to 
          // check manually whether we were called with a "X-Requested-With"
          // header.
          var customRequestedWithHeader = false,
              headerKey;
          for(headerKey in config.headers) {
              if (config.headers.hasOwnProperty( headerKey )) {
                  if (headerKey.toLowerCase() === 'x-requested-with') {
                      customRequestedWithHeader = true;
                  }
              }
          }
          if (customRequestedWithHeader === false) {
              // we did not have a custom "X-Requested-With" header
              config.headers['X-Requested-With'] = 'XMLHttpRequest';
          }
  
          // create request, open, and set headers
          var request = new OpenLayers.Request.XMLHttpRequest();
          var url = OpenLayers.Util.urlAppend(config.url, 
              OpenLayers.Util.getParameterString(config.params || {}));
          url = OpenLayers.Request.makeSameOrigin(url, config.proxy);
          request.open(
              config.method, url, config.async, config.user, config.password
          );
          for(var header in config.headers) {
              request.setRequestHeader(header, config.headers[header]);
          }
  
          var events = this.events;
  
          // we want to execute runCallbacks with "this" as the
          // execution scope
          var self = this;
          
          request.onreadystatechange = function() {
              if(request.readyState == OpenLayers.Request.XMLHttpRequest.DONE) {
                  var proceed = events.triggerEvent(
                      "complete",
                      {request: request, config: config, requestUrl: url}
                  );
                  if(proceed !== false) {
                      self.runCallbacks(
                          {request: request, config: config, requestUrl: url}
                      );
                  }
              }
          };
          
          // send request (optionally with data) and return
          // call in a timeout for asynchronous requests so the return is
          // available before readyState == 4 for cached docs
          if(config.async === false) {
              request.send(config.data);
          } else {
              window.setTimeout(function(){
                  if (request.readyState !== 0) { // W3C: 0-UNSENT
                      request.send(config.data);
                  }
              }, 0);
          }
          return request;
      }