Fix lack of top level methods from a service.
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index b39e1b2..b557b8b 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -91,6 +91,7 @@
   return build_from_document(content, discoveryServiceUrl, future,
       http, developerKey, model, requestBuilder)
 
+
 def build_from_document(
     service,
     base,
@@ -105,8 +106,8 @@
     base: string, base URI for all HTTP requests, usually the discovery URI
     future: string, discovery document with future capabilities
     auth_discovery: dict, information about the authentication the API supports
-    http: httplib2.Http, An instance of httplib2.Http or something that acts like
-      it that HTTP requests will be made through.
+    http: httplib2.Http, An instance of httplib2.Http or something that acts
+      like it that HTTP requests will be made through.
     developerKey: string, Key for controlling API usage, generated
       from the API Console.
     model: Model class instance that serializes and
@@ -116,45 +117,26 @@
 
   service = simplejson.loads(service)
   base = urlparse.urljoin(base, service['restBasePath'])
-  resources = service['resources']
   if future:
-    doc = simplejson.loads(future)
-    future = doc['resources']
-    auth_discovery = doc.get('auth', {})
+    future = simplejson.loads(future)
+    auth_discovery = future.get('auth', {})
   else:
     future = {}
     auth_discovery = {}
 
-  class Service(object):
-    """Top level interface for a service"""
+  resource = createResource(http, base, model, requestBuilder, developerKey,
+                       service, future)
 
-    def __init__(self, http=http):
-      self._http = http
-      self._baseUrl = base
-      self._model = model
-      self._developerKey = developerKey
-      self._requestBuilder = requestBuilder
+  def auth_method():
+    """Discovery information about the authentication the API uses."""
+    return auth_discovery
 
-    def auth_discovery(self):
-      return auth_discovery
+  setattr(resource, 'auth_discovery', auth_method)
 
-  def createMethod(theclass, methodName, methodDesc, futureDesc):
-
-    def method(self):
-      return createResource(self._http, self._baseUrl, self._model,
-                            self._requestBuilder, methodName,
-                            self._developerKey, methodDesc, futureDesc)
-
-    setattr(method, '__doc__', 'A description of how to use this function')
-    setattr(method, '__is_resource__', True)
-    setattr(theclass, methodName, method)
-
-  for methodName, methodDesc in resources.iteritems():
-    createMethod(Service, methodName, methodDesc, future.get(methodName, {}))
-  return Service()
+  return resource
 
 
-def createResource(http, baseUrl, model, requestBuilder, resourceName,
+def createResource(http, baseUrl, model, requestBuilder,
                    developerKey, resourceDesc, futureDesc):
 
   class Resource(object):
@@ -322,8 +304,8 @@
 
       def method(self):
         return createResource(self._http, self._baseUrl, self._model,
-                              self._requestBuilder, methodName,
-                              self._developerKey, methodDesc, futureDesc)
+                              self._requestBuilder, self._developerKey,
+                              methodDesc, futureDesc)
 
       setattr(method, '__doc__', 'A description of how to use this function')
       setattr(method, '__is_resource__', True)
@@ -335,10 +317,10 @@
       else:
         future = {}
       createMethod(Resource, methodName, methodDesc,
-                   future.get(methodName, {}))
+                   future)
 
   # Add <m>_next() methods to Resource
-  if futureDesc:
+  if futureDesc and 'methods' in futureDesc:
     for methodName, methodDesc in futureDesc['methods'].iteritems():
       if 'next' in methodDesc and methodName in resourceDesc['methods']:
         createNextMethod(Resource, methodName + "_next",
diff --git a/apiclient/oauth.py b/apiclient/oauth.py
index 469b6e0..68e4300 100644
--- a/apiclient/oauth.py
+++ b/apiclient/oauth.py
@@ -79,10 +79,12 @@
     """
     _abstract()
 
+
 class Flow(object):
   """Base class for all Flow objects."""
   pass
 
+
 class OAuthCredentials(Credentials):
   """Credentials object for OAuth 1.0a
   """
@@ -254,4 +256,3 @@
         oauth_params['oauth_token_secret'])
 
     return OAuthCredentials(consumer, token, self.user_agent)
-
diff --git a/samples/searchforshopping/crowding.py b/samples/searchforshopping/crowding.py
index bf1114e..2eea38f 100644
--- a/samples/searchforshopping/crowding.py
+++ b/samples/searchforshopping/crowding.py
@@ -15,12 +15,12 @@
 
 
 def main():
-  """Get and print a feed of public products in the United States mathing a text
-  search query for 'digital camera' and grouped by the 8 top brands.
+  """Get and print a feed of public products in the United States mathing a
+  text search query for 'digital camera' and grouped by the 8 top brands.
 
-  The list method of the resource should be called with the "crowdBy" parameter.
-  Each parameter should be designed as <attribute>:<occurence>, where
-  <occurrence> is the number of that <attribute> that will be used. For
+  The list method of the resource should be called with the "crowdBy"
+  parameter.  Each parameter should be designed as <attribute>:<occurence>,
+  where <occurrence> is the number of that <attribute> that will be used. For
   example, to crowd by the 5 top brands, the parameter would be "brand:5". The
   possible rules for crowding are currently:
 
diff --git a/samples/searchforshopping/fulltextsearch.py b/samples/searchforshopping/fulltextsearch.py
index 9a5fa5e..f838223 100644
--- a/samples/searchforshopping/fulltextsearch.py
+++ b/samples/searchforshopping/fulltextsearch.py
@@ -23,9 +23,10 @@
   The "|" operator can be used to search for alternative search terms, for
   example: q = 'banana|apple' will search for bananas or apples.
 
-  Search phrases such as those containing spaces can be specified by surrounding
-  them with double quotes, for example q='"mp3 player"'. This can be useful when
-  combining with the "|" operator such as q = '"mp3 player"|ipod'.
+  Search phrases such as those containing spaces can be specified by
+  surrounding them with double quotes, for example q='"mp3 player"'. This can
+  be useful when combining with the "|" operator such as q = '"mp3
+  player"|ipod'.
   """
   client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
   resource = client.products()
diff --git a/samples/searchforshopping/histograms.py b/samples/searchforshopping/histograms.py
index 6d198ff..6bd3a2f 100644
--- a/samples/searchforshopping/histograms.py
+++ b/samples/searchforshopping/histograms.py
@@ -16,16 +16,17 @@
   """Get and print a histogram of the top 15 brand distribution for a search
   query.
 
-  Histograms are created by using the "Facets" functionality of the API. A Facet
-  is a view of a certain property of products, containing a number of buckets,
-  one for each value of that property. Or concretely, for a parameter such as
-  "brand" of a product, the facets would include a facet for brand, which would
-  contain a number of buckets, one for each brand returned in the result.
+  Histograms are created by using the "Facets" functionality of the API. A
+  Facet is a view of a certain property of products, containing a number of
+  buckets, one for each value of that property. Or concretely, for a parameter
+  such as "brand" of a product, the facets would include a facet for brand,
+  which would contain a number of buckets, one for each brand returned in the
+  result.
 
   A bucket contains either a value and a count, or a value and a range. In the
   simple case of a value and a count for our example of the "brand" property,
-  the value would be the brand name, eg "sony" and the count would be the number
-  of results in the search.
+  the value would be the brand name, eg "sony" and the count would be the
+  number of results in the search.
   """
   client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
   resource = client.products()
diff --git a/samples/searchforshopping/ranking.py b/samples/searchforshopping/ranking.py
index bf6dc0f..86ad2ee 100644
--- a/samples/searchforshopping/ranking.py
+++ b/samples/searchforshopping/ranking.py
@@ -15,11 +15,12 @@
 
 
 def main():
-  """Get and print a feed of public products in the United States mathing a text
-  search query for 'digital camera' ranked by ascending price.
+  """Get and print a feed of public products in the United States mathing a
+  text search query for 'digital camera' ranked by ascending price.
 
-  The list method for the resource should be called with the "rankBy" parameter.
-  5 parameters to rankBy are currently supported by the API. They are:
+  The list method for the resource should be called with the "rankBy"
+  parameter.  5 parameters to rankBy are currently supported by the API. They
+  are:
 
   "relevancy"
   "modificationTime:ascending"
@@ -33,8 +34,8 @@
   """
   client = build('shopping', SHOPPING_API_VERSION, developerKey=DEVELOPER_KEY)
   resource = client.products()
-  # The rankBy parameter to the list method causes results to be ranked, in this
-  # case by ascending price.
+  # The rankBy parameter to the list method causes results to be ranked, in
+  # this case by ascending price.
   request = resource.list(source='public', country='US', q=u'digital camera',
                           rankBy='price:ascending')
   response = request.execute()
diff --git a/samples/searchforshopping/restricting.py b/samples/searchforshopping/restricting.py
index 07a4474..1d21c69 100644
--- a/samples/searchforshopping/restricting.py
+++ b/samples/searchforshopping/restricting.py
@@ -3,7 +3,8 @@
 #
 # Copyright 2010 Google Inc. All Rights Reserved.
 
-"""Query that is restricted by a parameter against the public shopping search API"""
+"""Query that is restricted by a parameter against the public shopping search
+API"""
 
 import pprint
 
diff --git a/tests/data/zoo.json b/tests/data/zoo.json
index f83e9dd..4f90c3d 100644
--- a/tests/data/zoo.json
+++ b/tests/data/zoo.json
@@ -4,6 +4,20 @@
  "description": "Zoo API used for testing",
  "restBasePath": "/zoo",
  "rpcPath": "/rpc",
+ "methods": {
+  "query": {
+   "restPath": "query",
+   "rpcMethod": "bigquery.query",
+   "httpMethod": "GET",
+   "parameters": {
+    "q": {
+     "restParameterType": "query",
+     "required": false,
+     "repeated": false
+    }
+   }
+  }
+ },
  "resources": {
   "my": {
    "resources": {
diff --git a/tests/test_discovery.py b/tests/test_discovery.py
index 0c64a09..541210c 100644
--- a/tests/test_discovery.py
+++ b/tests/test_discovery.py
@@ -113,6 +113,14 @@
     q = parse_qs(parsed[4])
     self.assertEqual(q['max-results'], ['5'])
 
+  def test_top_level_functions(self):
+    self.http = HttpMock('zoo.json', {'status': '200'})
+    zoo = build('zoo', 'v1', self.http)
+    self.assertTrue(getattr(zoo, 'query'))
+    request = zoo.query(q="foo")
+    parsed = urlparse.urlparse(request.uri)
+    q = parse_qs(parsed[4])
+    self.assertEqual(q['q'], ['foo'])
 
 
 class Next(unittest.TestCase):