docs: function send(httpMethod, path, req) {
      req = req || {};
      httpMethod = httpMethod.toUpperCase();
  
      var deferred = Q.defer();
      var url = baseUrl + path;
      var data = req.data || {};          // separate out data from request
      delete req.data;
  
      var isAdmin = req.caller && req.caller.role === 'admin';
      delete req.caller;
  
      var id = req._id || data._id;       // get id from request or data
      if (req._id) { delete req._id; }    // delete id from request so no dupe
  
      var session = cls.getNamespace('appSession');
      var caller = session && session.active && session.get('caller');
      if (caller && !isAdmin) {
          _.extend(req, {                 // onBehalfOf used by API to know who is the caller
              onBehalfOfType: caller.type,
              onBehalfOfId:   caller._id + '',
              onBehalfOfRole: caller.role,
              onBehalfOfName: caller.name
          });
      }
  
      _.each(req, function (val, key) {
          if (!_.isString(val)) { req[key] = JSON.stringify(val); }
      });
  
      // replace the ID portion of the URL
      url = id ?
          url.replace('{_id}', id + '') :
          url.replace('/{_id}', '');
  
      var reqConfig = {
          headers:    headers,
          url:        url,
          method:     httpMethod,
          qs:         _.isEmpty(req) ? undefined : req,
          json:       _.isEmpty(data) ? true : data
      };
  
      // if baseUrl not there yet, wait for 100 seconds until it is (i.e. during system startup)
      if (!baseUrl) {
          setTimeout(function () {
              makeRequest(reqConfig, deferred);
          }, 100);
      }
      else {
          makeRequest(reqConfig, deferred);
      }
  
      return deferred.promise;
  }