Added mocks for the generated service objects. Also fixed a bunch of formatting.
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index 1660288..36d38e7 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -32,31 +32,15 @@
     from urlparse import parse_qsl
 except ImportError:
     from cgi import parse_qsl
+
 from apiclient.http import HttpRequest
 from apiclient.json import simplejson
+from apiclient.model import JsonModel
+from apiclient.errors import HttpError
+from apiclient.errors import UnknownLinkType
 
 URITEMPLATE = re.compile('{[^}]*}')
 VARNAME = re.compile('[a-zA-Z0-9_-]+')
-
-class Error(Exception):
-  """Base error for this module."""
-  pass
-
-
-class HttpError(Error):
-  """HTTP data was invalid or unexpected."""
-  def __init__(self, resp, detail):
-    self.resp = resp
-    self.detail = detail
-  def __str__(self):
-    return self.detail
-
-
-class UnknownLinkType(Error):
-  """Link type unknown or unexpected."""
-  pass
-
-
 DISCOVERY_URI = ('https://www.googleapis.com/discovery/v0.2beta1/describe/'
   '{api}/{apiVersion}')
 
@@ -78,52 +62,12 @@
   return ''.join(result)
 
 
-class JsonModel(object):
-
-  def request(self, headers, path_params, query_params, body_value):
-    query = self.build_query(query_params)
-    headers['accept'] = 'application/json'
-    if 'user-agent' in headers:
-      headers['user-agent'] += ' '
-    else:
-      headers['user-agent'] = ''
-    headers['user-agent'] += 'google-api-python-client/1.0'
-    if body_value is None:
-      return (headers, path_params, query, None)
-    else:
-      headers['content-type'] = 'application/json'
-      return (headers, path_params, query, simplejson.dumps(body_value))
-
-  def build_query(self, params):
-    params.update({'alt': 'json'})
-    astuples = []
-    for key, value in params.iteritems():
-      if getattr(value, 'encode', False) and callable(value.encode):
-        value = value.encode('utf-8')
-      astuples.append((key, value))
-    return '?' + urllib.urlencode(astuples)
-
-  def response(self, resp, content):
-    # Error handling is TBD, for example, do we retry
-    # for some operation/error combinations?
-    if resp.status < 300:
-      if resp.status == 204:
-        # A 204: No Content response should be treated differently to all the other success states
-        return simplejson.loads('{}')
-      body = simplejson.loads(content)
-      if isinstance(body, dict) and 'data' in body:
-        body = body['data']
-      return body
-    else:
-      logging.debug('Content from bad request was: %s' % content)
-      if resp.get('content-type', '').startswith('application/json'):
-        raise HttpError(resp, simplejson.loads(content)['error'])
-      else:
-        raise HttpError(resp, '%d %s' % (resp.status, resp.reason))
-
-
-def build(serviceName, version, http=None,
-    discoveryServiceUrl=DISCOVERY_URI, developerKey=None, model=JsonModel()):
+def build(serviceName, version,
+    http=None,
+    discoveryServiceUrl=DISCOVERY_URI,
+    developerKey=None,
+    model=JsonModel(),
+    requestBuilder=HttpRequest):
   params = {
       'api': serviceName,
       'apiVersion': version
@@ -159,6 +103,7 @@
       self._baseUrl = base
       self._model = model
       self._developerKey = developerKey
+      self._requestBuilder = requestBuilder
 
     def auth_discovery(self):
       return auth_discovery
@@ -167,7 +112,8 @@
 
     def method(self):
       return createResource(self._http, self._baseUrl, self._model,
-          methodName, self._developerKey, methodDesc, futureDesc)
+                            self._requestBuilder, methodName,
+                            self._developerKey, methodDesc, futureDesc)
 
     setattr(method, '__doc__', 'A description of how to use this function')
     setattr(method, '__is_resource__', True)
@@ -178,8 +124,8 @@
   return Service()
 
 
-def createResource(http, baseUrl, model, resourceName, developerKey,
-                   resourceDesc, futureDesc):
+def createResource(http, baseUrl, model, requestBuilder, resourceName,
+                   developerKey, resourceDesc, futureDesc):
 
   class Resource(object):
     """A class for interacting with a resource."""
@@ -189,11 +135,13 @@
       self._baseUrl = baseUrl
       self._model = model
       self._developerKey = developerKey
+      self._requestBuilder = requestBuilder
 
   def createMethod(theclass, methodName, methodDesc, futureDesc):
     pathUrl = methodDesc['restPath']
     pathUrl = re.sub(r'\{', r'{+', pathUrl)
     httpMethod = methodDesc['httpMethod']
+    methodId = methodDesc['rpcMethod']
 
     argmap = {}
     if httpMethod in ['PUT', 'POST']:
@@ -257,18 +205,23 @@
       headers, params, query, body = self._model.request(headers,
           actual_path_params, actual_query_params, body_value)
 
-      # TODO(ade) This exists to fix a bug in V1 of the Buzz discovery document.
-      # Base URLs should not contain any path elements. If they do then urlparse.urljoin will strip them out
-      # This results in an incorrect URL which returns a 404
+      # TODO(ade) This exists to fix a bug in V1 of the Buzz discovery
+      # document.  Base URLs should not contain any path elements. If they do
+      # then urlparse.urljoin will strip them out This results in an incorrect
+      # URL which returns a 404
       url_result = urlparse.urlsplit(self._baseUrl)
       new_base_url = url_result.scheme + '://' + url_result.netloc
 
       expanded_url = uritemplate.expand(pathUrl, params)
-      url = urlparse.urljoin(new_base_url, url_result.path + expanded_url + query)
+      url = urlparse.urljoin(new_base_url,
+                             url_result.path + expanded_url + query)
 
       logging.info('URL being requested: %s' % url)
-      return HttpRequest(self._http, url, method=httpMethod, body=body,
-                         headers=headers, postproc=self._model.response)
+      return self._requestBuilder(self._http, url,
+                                  method=httpMethod, body=body,
+                                  headers=headers,
+                                  postproc=self._model.response,
+                                  methodId=methodId)
 
     docs = ['A description of how to use this function\n\n']
     for arg in argmap.iterkeys():
@@ -280,7 +233,8 @@
     setattr(method, '__doc__', ''.join(docs))
     setattr(theclass, methodName, method)
 
-  def createNextMethod(theclass, methodName, methodDesc):
+  def createNextMethod(theclass, methodName, methodDesc, futureDesc):
+    methodId = methodDesc['rpcMethod'] + '.next'
 
     def method(self, previous):
       """
@@ -291,12 +245,12 @@
       Returns None if there are no more items in
       the collection.
       """
-      if methodDesc['type'] != 'uri':
-        raise UnknownLinkType(methodDesc['type'])
+      if futureDesc['type'] != 'uri':
+        raise UnknownLinkType(futureDesc['type'])
 
       try:
         p = previous
-        for key in methodDesc['location']:
+        for key in futureDesc['location']:
           p = p[key]
         url = p
       except (KeyError, TypeError):
@@ -315,8 +269,10 @@
       logging.info('URL being requested: %s' % url)
       resp, content = self._http.request(url, method='GET', headers=headers)
 
-      return HttpRequest(self._http, url, method='GET',
-                         headers=headers, postproc=self._model.response)
+      return self._requestBuilder(self._http, url, method='GET',
+                                  headers=headers,
+                                  postproc=self._model.response,
+                                  methodId=methodId)
 
     setattr(theclass, methodName, method)
 
@@ -331,6 +287,7 @@
 
   # Add in nested resources
   if 'resources' in resourceDesc:
+
     def createMethod(theclass, methodName, methodDesc, futureDesc):
 
       def method(self):
@@ -346,12 +303,15 @@
         future = futureDesc['resources'].get(methodName, {})
       else:
         future = {}
-      createMethod(Resource, methodName, methodDesc, future.get(methodName, {}))
+      createMethod(Resource, methodName, methodDesc,
+                   future.get(methodName, {}))
 
   # Add <m>_next() methods to Resource
   if futureDesc:
     for methodName, methodDesc in futureDesc['methods'].iteritems():
       if 'next' in methodDesc and methodName in resourceDesc['methods']:
-        createNextMethod(Resource, methodName + "_next", methodDesc['next'])
+        createNextMethod(Resource, methodName + "_next",
+                         resourceDesc['methods'][methodName],
+                         methodDesc['next'])
 
   return Resource()
diff --git a/apiclient/ext/django_orm.py b/apiclient/ext/django_orm.py
index 4217eaa..d8cb92d 100644
--- a/apiclient/ext/django_orm.py
+++ b/apiclient/ext/django_orm.py
@@ -1,5 +1,6 @@
 from django.db import models
 
+
 class OAuthCredentialsField(models.Field):
 
   __metaclass__ = models.SubfieldBase
@@ -17,6 +18,7 @@
   def get_db_prep_value(self, value):
     return base64.b64encode(pickle.dumps(value))
 
+
 class FlowThreeLeggedField(models.Field):
 
   __metaclass__ = models.SubfieldBase
diff --git a/apiclient/http.py b/apiclient/http.py
index 25d646e..d616c07 100644
--- a/apiclient/http.py
+++ b/apiclient/http.py
@@ -1,19 +1,42 @@
 # Copyright 2010 Google Inc. All Rights Reserved.
 
-"""One-line documentation for http module.
+"""Classes to encapsulate a single HTTP request.
 
-A detailed description of http.
+The classes implement a command pattern, with every
+object supporting an execute() method that does the
+actuall HTTP request.
 """
 
 __author__ = 'jcgregorio@google.com (Joe Gregorio)'
+__all__ = [
+    'HttpRequest', 'RequestMockBuilder'
+    ]
+
+from httplib2 import Response
+from apiclient.model import JsonModel
 
 
 class HttpRequest(object):
-  """Encapsulate an HTTP request.
+  """Encapsulates a single HTTP request.
   """
 
   def __init__(self, http, uri, method="GET", body=None, headers=None,
-               postproc=None):
+               postproc=None, methodId=None):
+    """Constructor for an HttpRequest.
+
+    Only http and uri are required.
+
+    Args:
+      http: httplib2.Http, the transport object to use to make a request
+      uri: string, the absolute URI to send the request to
+      method: string, the HTTP method to use
+      body: string, the request body of the HTTP request
+      headers: dict, the HTTP request headers
+      postproc: callable, called on the HTTP response and content to transform
+                it into a data object before returning, or raising an exception
+                on an error.
+      methodId: string, a unique identifier for the API method being called.
+    """
     self.uri = uri
     self.method = method
     self.body = body
@@ -24,8 +47,17 @@
   def execute(self, http=None):
     """Execute the request.
 
-    If an http object is passed in it is used instead of the
-    httplib2.Http object that the request was constructed with.
+    Args:
+      http: httplib2.Http, an http object to be used in place of the
+            one the HttpRequest request object was constructed with.
+
+    Returns:
+      A deserialized object model of the response body as determined
+      by the postproc.
+
+    Raises:
+      apiclient.errors.HttpError if the response was not a 2xx.
+      httplib2.Error if a transport error has occured.
     """
     if http is None:
       http = self.http
@@ -33,3 +65,87 @@
                                       body=self.body,
                                       headers=self.headers)
     return self.postproc(resp, content)
+
+
+class HttpRequestMock(object):
+  """Mock of HttpRequest.
+
+  Do not construct directly, instead use RequestMockBuilder.
+  """
+
+  def __init__(self, resp, content, postproc):
+    """Constructor for HttpRequestMock
+
+    Args:
+      resp: httplib2.Response, the response to emulate coming from the request
+      content: string, the response body
+      postproc: callable, the post processing function usually supplied by
+                the model class. See model.JsonModel.response() as an example.
+    """
+    self.resp = resp
+    self.content = content
+    self.postproc = postproc
+    if resp is None:
+      self.resp = Response({'status': 200, 'reason': 'OK'})
+    if 'reason' in self.resp:
+      self.resp.reason = self.resp['reason']
+
+  def execute(self, http=None):
+    """Execute the request.
+
+    Same behavior as HttpRequest.execute(), but the response is
+    mocked and not really from an HTTP request/response.
+    """
+    return self.postproc(self.resp, self.content)
+
+
+class RequestMockBuilder(object):
+  """A simple mock of HttpRequest
+
+    Pass in a dictionary to the constructor that maps request methodIds to
+    tuples of (httplib2.Response, content) that should be returned when that
+    method is called. None may also be passed in for the httplib2.Response, in
+    which case a 200 OK response will be generated.
+
+    Example:
+      response = '{"data": {"id": "tag:google.c...'
+      requestBuilder = RequestMockBuilder(
+        {
+          'chili.activities.get': (None, response),
+        }
+      )
+      apiclient.discovery.build("buzz", "v1", requestBuilder=requestBuilder)
+
+    Methods that you do not supply a response for will return a
+    200 OK with an empty string as the response content. The methodId
+    is taken from the rpcName in the discovery document.
+
+    For more details see the project wiki.
+  """
+
+  def __init__(self, responses):
+    """Constructor for RequestMockBuilder
+
+    The constructed object should be a callable object
+    that can replace the class HttpResponse.
+
+    responses - A dictionary that maps methodIds into tuples
+                of (httplib2.Response, content). The methodId
+                comes from the 'rpcName' field in the discovery
+                document.
+    """
+    self.responses = responses
+
+  def __call__(self, http, uri, method="GET", body=None, headers=None,
+               postproc=None, methodId=None):
+    """Implements the callable interface that discovery.build() expects
+    of requestBuilder, which is to build an object compatible with
+    HttpRequest.execute(). See that method for the description of the
+    parameters and the expected response.
+    """
+    if methodId in self.responses:
+      resp, content = self.responses[methodId]
+      return HttpRequestMock(resp, content, postproc)
+    else:
+      model = JsonModel()
+      return HttpRequestMock(None, '{}', model.response)
diff --git a/apiclient/oauth.py b/apiclient/oauth.py
index 9907c46..9cc6e66 100644
--- a/apiclient/oauth.py
+++ b/apiclient/oauth.py
@@ -131,9 +131,9 @@
         headers = {}
       headers.update(req.to_header())
       if 'user-agent' in headers:
-        headers['user-agent'] =  self.user_agent + ' ' + headers['user-agent']
+        headers['user-agent'] = self.user_agent + ' ' + headers['user-agent']
       else:
-        headers['user-agent'] =  self.user_agent
+        headers['user-agent'] = self.user_agent
       return request_orig(uri, method, body, headers,
                           redirections, connection_type)