Merged my changes with upstream changes from Joe.
diff --git a/apiclient/contrib/moderator/future.json b/apiclient/contrib/moderator/future.json
index 7e3d978..87d525b 100644
--- a/apiclient/contrib/moderator/future.json
+++ b/apiclient/contrib/moderator/future.json
@@ -2,7 +2,7 @@
   "data": {
     "moderator": {
       "v1": {
-        "baseUrl": "https://www.googleapis.com/", 
+        "baseUrl": "https://www.googleapis.com/",
           "auth": {
             "request": {
               "url": "https://www.google.com/accounts/OAuthGetRequestToken",
diff --git a/apiclient/discovery.py b/apiclient/discovery.py
index 328d970..db17cea 100644
--- a/apiclient/discovery.py
+++ b/apiclient/discovery.py
@@ -45,13 +45,21 @@
     import json as simplejson
 
 
-class HttpError(Exception):
+class Error(Exception):
+  """Base error for this module."""
   pass
 
 
-class UnknownLinkType(Exception):
+class HttpError(Error):
+  """HTTP data was invalid or unexpected."""
   pass
 
+
+class UnknownLinkType(Error):
+  """Link type unknown or unexpected."""
+  pass
+
+
 DISCOVERY_URI = ('http://www.googleapis.com/discovery/0.1/describe'
   '{?api,apiVersion}')
 
@@ -86,12 +94,15 @@
     if body_value is None:
       return (headers, path_params, query, None)
     else:
-      model = {'data': body_value}
+      if len(body_value) == 1 and 'data' in body_value:
+        model = body_value
+      else:
+        model = {'data': body_value}
       headers['content-type'] = 'application/json'
       return (headers, path_params, query, simplejson.dumps(model))
 
   def build_query(self, params):
-    params.update({'alt': 'json', 'prettyprint': 'true'})
+    params.update({'alt': 'json'})
     astuples = []
     for key, value in params.iteritems():
       if getattr(value, 'encode', False) and callable(value.encode):
diff --git a/apiclient/oauth.py b/apiclient/oauth.py
index 8b827c6..de20336 100644
--- a/apiclient/oauth.py
+++ b/apiclient/oauth.py
@@ -21,7 +21,17 @@
     from cgi import parse_qs, parse_qsl
 
 
-class MissingParameter(Exception):
+class Error(Exception):
+  """Base error for this module."""
+  pass
+
+
+class RequestError(Error):
+  """Error occurred during request."""
+  pass
+
+
+class MissingParameter(Error):
   pass
 
 
@@ -120,8 +130,11 @@
       if headers == None:
         headers = {}
       headers.update(req.to_header())
-      if 'user-agent' not in headers:
-        headers['user-agent'] = self.user_agent
+      if 'user-agent' in headers:
+        headers['user-agent'] += ' '
+      else:
+        headers['user-agent'] = ''
+      headers['user-agent'] += self.user_agent
       return request_orig(uri, method, body, headers,
                           redirections, connection_type)
 
@@ -185,7 +198,7 @@
                                    body=body)
     if resp['status'] != '200':
       logging.error('Failed to retrieve temporary authorization: %s' % content)
-      raise Exception('Invalid response %s.' % resp['status'])
+      raise RequestError('Invalid response %s.' % resp['status'])
 
     self.request_token = dict(parse_qsl(content))
 
@@ -222,7 +235,7 @@
     resp, content = client.request(uri, 'POST', headers=headers)
     if resp['status'] != '200':
       logging.error('Failed to retrieve access token: %s' % content)
-      raise Exception('Invalid response %s.' % resp['status'])
+      raise RequestError('Invalid response %s.' % resp['status'])
 
     oauth_params = dict(parse_qsl(content))
     token = oauth.Token(
diff --git a/buzz_gae_client.py b/buzz_gae_client.py
index ffc74c3..f790e02 100644
--- a/buzz_gae_client.py
+++ b/buzz_gae_client.py
@@ -36,6 +36,17 @@
 AUTHORIZE_URL = 'https://www.google.com/buzz/api/auth/OAuthAuthorizeToken?domain=anonymous&scope=https://www.googleapis.com/auth/buzz'
 ACCESS_TOKEN_URL = 'https://www.google.com/accounts/OAuthGetAccessToken'
 
+
+class Error(Exception):
+  """Base error for this module."""
+  pass
+
+
+class RequestError(Error):
+  """Request returned failure or unexpected data."""
+  pass
+
+
 # TODO(ade) This class is really a BuzzGaeBuilder. Rename it.
 class BuzzGaeClient(object):
   def __init__(self, consumer_key='anonymous', consumer_secret='anonymous'):
@@ -49,7 +60,7 @@
 
     if resp['status'] != '200':
       logging.warn('Request: %s failed with status: %s. Content was: %s' % (url, resp['status'], content))
-      raise Exception('Invalid response %s.' % resp['status'])
+      raise RequestError('Invalid response %s.' % resp['status'])
     return resp, content
 
   def get_request_token(self, callback_url, display_name = None):
diff --git a/samples/buzz/buzz.py b/samples/buzz/buzz.py
new file mode 100644
index 0000000..14b5ea1
--- /dev/null
+++ b/samples/buzz/buzz.py
@@ -0,0 +1,66 @@
+#!/usr/bin/python2.4
+# -*- coding: utf-8 -*-
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+
+"""Simple command-line example for Buzz.
+
+Command-line application that retrieves the users
+latest content and then adds a new entry.
+"""
+
+__author__ = 'jcgregorio@google.com (Joe Gregorio)'
+
+from apiclient.discovery import build
+
+import httplib2
+import pickle
+import pprint
+
+# Uncomment the next line to get very detailed logging
+# httplib2.debuglevel = 4
+
+def main():
+  f = open("buzz.dat", "r")
+  credentials = pickle.loads(f.read())
+  f.close()
+
+  http = httplib2.Http()
+  http = credentials.authorize(http)
+
+  p = build("buzz", "v1", http=http)
+  activities = p.activities()
+
+  # Retrieve the first two activities
+  activitylist = activities.list(max_results='2', scope='@self', userId='@me').execute()
+  print "Retrieved the first two activities"
+
+  # Retrieve the next two activities
+  activitylist = activities.list_next(activitylist).execute()
+  print "Retrieved the next two activities"
+
+  # Add a new activity
+  new_activity_body = {
+      'title': 'Testing insert',
+      'object': {
+          'content': u'Just a short note to show that insert is working. ☄',
+          'type': 'note'}
+      }
+  activity = activities.insert(userId='@me', body=new_activity_body).execute()
+  print "Added a new activity"
+
+  activitylist = activities.list(max_results='2', scope='@self', userId='@me').execute()
+
+  # Add a comment to that activity
+  comment_body = {
+          "content": "This is a comment"
+      }
+  item = activitylist['items'][0]
+  comment = p.comments().insert(
+      userId=item['actor']['id'], postId=item['id'], body=comment_body
+      ).execute()
+  print 'Added a comment to the new activity'
+  pprint.pprint(comment)
+
+if __name__ == '__main__':
+  main()
diff --git a/samples/cmdline/three_legged_dance.py b/samples/buzz/three_legged_dance.py
similarity index 93%
rename from samples/cmdline/three_legged_dance.py
rename to samples/buzz/three_legged_dance.py
index ff1d657..9972455 100644
--- a/samples/cmdline/three_legged_dance.py
+++ b/samples/buzz/three_legged_dance.py
@@ -22,11 +22,6 @@
 
 __author__ = 'jcgregorio@google.com (Joe Gregorio)'
 
-# Enable this sample to be run from the top-level directory
-import os
-import sys
-sys.path.insert(0, os.getcwd())
-
 from apiclient.discovery import build
 from apiclient.oauth import FlowThreeLegged
 
diff --git a/samples/cmdline/buzz.py b/samples/cmdline/buzz.py
deleted file mode 100644
index f24c032..0000000
--- a/samples/cmdline/buzz.py
+++ /dev/null
@@ -1,53 +0,0 @@
-#!/usr/bin/python2.4
-# -*- coding: utf-8 -*-
-#
-# Copyright 2010 Google Inc. All Rights Reserved.
-
-"""Simple command-line example for Buzz.
-
-Command-line application that retrieves the users
-latest content and then adds a new entry.
-"""
-
-__author__ = 'jcgregorio@google.com (Joe Gregorio)'
-
-# Enable this sample to be run from the top-level directory
-import os
-import sys
-sys.path.insert(0, os.getcwd())
-
-from apiclient.discovery import build
-
-import httplib2
-# httplib2.debuglevel = 4
-import pickle
-import pprint
-
-def main():
-  f = open("buzz.dat", "r")
-  credentials = pickle.loads(f.read())
-  f.close()
-
-  http = httplib2.Http()
-  http = credentials.authorize(http)
-
-  p = build("buzz", "v1", http=http)
-  activities = p.activities()
-  activitylist = activities.list(max_results='2', scope='@self', userId='@me').execute()
-  print activitylist['items'][0]['title']
-  activitylist = activities.list_next(activitylist).execute()
-  print activitylist['items'][0]['title']
-
-  activity = activities.insert(userId='@me', body={
-    'title': 'Testing insert',
-    'object': {
-      'content': u'Just a short note to show that insert is working. ☄',
-      'type': 'note'}
-    }
-  ).execute()
-  pprint.pprint(activity)
-  print
-  print 'Just created: ', activity['links']['alternate'][0]['href']
-
-if __name__ == '__main__':
-  main()
diff --git a/samples/cmdline/moderator.py b/samples/cmdline/moderator.py
deleted file mode 100644
index 36f354a..0000000
--- a/samples/cmdline/moderator.py
+++ /dev/null
@@ -1,33 +0,0 @@
-#!/usr/bin/python2.4
-# -*- coding: utf-8 -*-
-#
-# Copyright 2010 Google Inc. All Rights Reserved.
-
-"""Simple command-line example for Buzz.
-
-Command-line application that retrieves the users
-latest content and then adds a new entry.
-"""
-
-__author__ = 'jcgregorio@google.com (Joe Gregorio)'
-
-
-from apiclient.discovery import build
-
-import httplib2
-import pickle
-
-
-def main():
-  f = open("moderator.dat", "r")
-  credentials = pickle.loads(f.read())
-  f.close()
-
-  http = httplib2.Http()
-  http = credentials.authorize(http)
-
-  p = build("moderator", "v1", http=http)
-  print p.submissions().list(seriesId="7035", topicId="64").execute()
-
-if __name__ == '__main__':
-  main()
diff --git a/samples/moderator/moderator.py b/samples/moderator/moderator.py
new file mode 100644
index 0000000..3d742e8
--- /dev/null
+++ b/samples/moderator/moderator.py
@@ -0,0 +1,75 @@
+#!/usr/bin/python2.4
+# -*- coding: utf-8 -*-
+#
+# Copyright 2010 Google Inc. All Rights Reserved.
+
+"""Simple command-line example for Buzz.
+
+Command-line application that retrieves the users
+latest content and then adds a new entry.
+"""
+
+__author__ = 'jcgregorio@google.com (Joe Gregorio)'
+
+
+from apiclient.discovery import build
+
+import httplib2
+import pickle
+
+# Uncomment to get detailed logging
+# httplib2.debuglevel = 4
+
+def main():
+  f = open("moderator.dat", "r")
+  credentials = pickle.loads(f.read())
+  f.close()
+
+  http = httplib2.Http()
+  http = credentials.authorize(http)
+
+  p = build("moderator", "v1", http=http)
+
+  series_body = {
+        "description": "Share and rank tips for eating healthily on the cheaps!",
+        "name": "Eating Healthy & Cheap",
+        "videoSubmissionAllowed": False
+      }
+  series = p.series().insert(body=series_body).execute()
+  print "Created a new series"
+
+  topic_body = {
+      "data": {
+        "description": "Share your ideas on eating healthy!",
+        "name": "Ideas",
+        "presenter": "liz"
+        }
+      }
+  topic = p.topics().insert(seriesId=series['id']['seriesId'], body=topic_body).execute()
+  print "Created a new topic"
+
+  submission_body = {
+      "data": {
+        "attachmentUrl": "http://www.youtube.com/watch?v=1a1wyc5Xxpg",
+        "attribution": {
+          "displayName": "Bashan",
+          "location": "Bainbridge Island, WA"
+          },
+        "text": "Charlie Ayers @ Google"
+        }
+      }
+  submission = p.submissions().insert(seriesId=topic['id']['seriesId'],
+      topicId=topic['id']['topicId'], body=submission_body).execute()
+  print "Inserted a new submisson on the topic"
+
+  vote_body = {
+      "data": {
+        "vote": "PLUS"
+        }
+      }
+  p.votes().insert(seriesId=topic['id']['seriesId'], submissionId=submission['id']['submissionId'], body=vote_body)
+  print "Voted on the submission"
+
+
+if __name__ == '__main__':
+  main()
diff --git a/samples/cmdline/three_legged_dance_moderator.py b/samples/moderator/three_legged_dance.py
similarity index 95%
rename from samples/cmdline/three_legged_dance_moderator.py
rename to samples/moderator/three_legged_dance.py
index f09410d..fbc90ec 100644
--- a/samples/cmdline/three_legged_dance_moderator.py
+++ b/samples/moderator/three_legged_dance.py
@@ -35,6 +35,7 @@
                        user_agent='google-api-client-python-mdrtr-cmdline/1.0',
                        domain='anonymous',
                        scope='https://www.googleapis.com/auth/moderator',
+                       #scope='tag:google.com,2010:auth/moderator',
                        xoauth_displayname='Google API Client Example App')
 
 authorize_url = flow.step1_get_authorize_url()
diff --git a/upload-diffs.py b/upload-diffs.py
index 1b5daac..c3ff6b9 100644
--- a/upload-diffs.py
+++ b/upload-diffs.py
@@ -487,7 +487,7 @@
                  help="Base revision/branch/tree to diff against. Use "
                       "rev1:rev2 range to review already committed changeset.")
 group.add_option("--send_mail", action="store_true",
-                 dest="send_mail", default=False,
+                 dest="send_mail", default=True,
                  help="Send notification email to reviewers.")
 group.add_option("--vcs", action="store", dest="vcs",
                  metavar="VCS", default=None,