diff --git a/oauth2/__init__.py b/oauth2/__init__.py
new file mode 100644
index 0000000..3adbd20
--- /dev/null
+++ b/oauth2/__init__.py
@@ -0,0 +1,735 @@
+"""
+The MIT License
+
+Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+import urllib
+import time
+import random
+import urlparse
+import hmac
+import binascii
+import httplib2
+
+try:
+    from urlparse import parse_qs, parse_qsl
+except ImportError:
+    from cgi import parse_qs, parse_qsl
+
+
+VERSION = '1.0'  # Hi Blaine!
+HTTP_METHOD = 'GET'
+SIGNATURE_METHOD = 'PLAINTEXT'
+
+
+class Error(RuntimeError):
+    """Generic exception class."""
+
+    def __init__(self, message='OAuth error occurred.'):
+        self._message = message
+
+    @property
+    def message(self):
+        """A hack to get around the deprecation errors in 2.6."""
+        return self._message
+
+    def __str__(self):
+        return self._message
+
+
+class MissingSignature(Error):
+    pass
+
+
+def build_authenticate_header(realm=''):
+    """Optional WWW-Authenticate header (401 error)"""
+    return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
+
+
+def build_xoauth_string(url, consumer, token=None):
+    """Build an XOAUTH string for use in SMTP/IMPA authentication."""
+    request = Request.from_consumer_and_token(consumer, token,
+        "GET", url)
+
+    signing_method = SignatureMethod_HMAC_SHA1()
+    request.sign_request(signing_method, consumer, token)
+
+    params = []
+    for k, v in sorted(request.iteritems()):
+        if v is not None:
+            params.append('%s="%s"' % (k, escape(v)))
+
+    return "%s %s %s" % ("GET", url, ','.join(params))
+
+
+def escape(s):
+    """Escape a URL including any /."""
+    return urllib.quote(s, safe='~')
+
+
+def generate_timestamp():
+    """Get seconds since epoch (UTC)."""
+    return int(time.time())
+
+
+def generate_nonce(length=8):
+    """Generate pseudorandom number."""
+    return ''.join([str(random.randint(0, 9)) for i in range(length)])
+
+
+def generate_verifier(length=8):
+    """Generate pseudorandom number."""
+    return ''.join([str(random.randint(0, 9)) for i in range(length)])
+
+
+class Consumer(object):
+    """A consumer of OAuth-protected services.
+ 
+    The OAuth consumer is a "third-party" service that wants to access
+    protected resources from an OAuth service provider on behalf of an end
+    user. It's kind of the OAuth client.
+ 
+    Usually a consumer must be registered with the service provider by the
+    developer of the consumer software. As part of that process, the service
+    provider gives the consumer a *key* and a *secret* with which the consumer
+    software can identify itself to the service. The consumer will include its
+    key in each request to identify itself, but will use its secret only when
+    signing requests, to prove that the request is from that particular
+    registered consumer.
+ 
+    Once registered, the consumer can then use its consumer credentials to ask
+    the service provider for a request token, kicking off the OAuth
+    authorization process.
+    """
+
+    key = None
+    secret = None
+
+    def __init__(self, key, secret):
+        self.key = key
+        self.secret = secret
+
+        if self.key is None or self.secret is None:
+            raise ValueError("Key and secret must be set.")
+
+    def __str__(self):
+        data = {'oauth_consumer_key': self.key,
+            'oauth_consumer_secret': self.secret}
+
+        return urllib.urlencode(data)
+
+
+class Token(object):
+    """An OAuth credential used to request authorization or a protected
+    resource.
+ 
+    Tokens in OAuth comprise a *key* and a *secret*. The key is included in
+    requests to identify the token being used, but the secret is used only in
+    the signature, to prove that the requester is who the server gave the
+    token to.
+ 
+    When first negotiating the authorization, the consumer asks for a *request
+    token* that the live user authorizes with the service provider. The
+    consumer then exchanges the request token for an *access token* that can
+    be used to access protected resources.
+    """
+
+    key = None
+    secret = None
+    callback = None
+    callback_confirmed = None
+    verifier = None
+
+    def __init__(self, key, secret):
+        self.key = key
+        self.secret = secret
+
+        if self.key is None or self.secret is None:
+            raise ValueError("Key and secret must be set.")
+
+    def set_callback(self, callback):
+        self.callback = callback
+        self.callback_confirmed = 'true'
+
+    def set_verifier(self, verifier=None):
+        if verifier is not None:
+            self.verifier = verifier
+        else:
+            self.verifier = generate_verifier()
+
+    def get_callback_url(self):
+        if self.callback and self.verifier:
+            # Append the oauth_verifier.
+            parts = urlparse.urlparse(self.callback)
+            scheme, netloc, path, params, query, fragment = parts[:6]
+            if query:
+                query = '%s&oauth_verifier=%s' % (query, self.verifier)
+            else:
+                query = 'oauth_verifier=%s' % self.verifier
+            return urlparse.urlunparse((scheme, netloc, path, params,
+                query, fragment))
+        return self.callback
+
+    def to_string(self):
+        """Returns this token as a plain string, suitable for storage.
+ 
+        The resulting string includes the token's secret, so you should never
+        send or store this string where a third party can read it.
+        """
+
+        data = {
+            'oauth_token': self.key,
+            'oauth_token_secret': self.secret,
+        }
+
+        if self.callback_confirmed is not None:
+            data['oauth_callback_confirmed'] = self.callback_confirmed
+        return urllib.urlencode(data)
+ 
+    @staticmethod
+    def from_string(s):
+        """Deserializes a token from a string like one returned by
+        `to_string()`."""
+
+        if not len(s):
+            raise ValueError("Invalid parameter string.")
+
+        params = parse_qs(s, keep_blank_values=False)
+        if not len(params):
+            raise ValueError("Invalid parameter string.")
+
+        try:
+            key = params['oauth_token'][0]
+        except Exception:
+            raise ValueError("'oauth_token' not found in OAuth request.")
+
+        try:
+            secret = params['oauth_token_secret'][0]
+        except Exception:
+            raise ValueError("'oauth_token_secret' not found in " 
+                "OAuth request.")
+
+        token = Token(key, secret)
+        try:
+            token.callback_confirmed = params['oauth_callback_confirmed'][0]
+        except KeyError:
+            pass  # 1.0, no callback confirmed.
+        return token
+
+    def __str__(self):
+        return self.to_string()
+
+
+def setter(attr):
+    name = attr.__name__
+ 
+    def getter(self):
+        try:
+            return self.__dict__[name]
+        except KeyError:
+            raise AttributeError(name)
+ 
+    def deleter(self):
+        del self.__dict__[name]
+ 
+    return property(getter, attr, deleter)
+
+
+class Request(dict):
+ 
+    """The parameters and information for an HTTP request, suitable for
+    authorizing with OAuth credentials.
+ 
+    When a consumer wants to access a service's protected resources, it does
+    so using a signed HTTP request identifying itself (the consumer) with its
+    key, and providing an access token authorized by the end user to access
+    those resources.
+ 
+    """
+ 
+    version = VERSION
+ 
+    def __init__(self, method=HTTP_METHOD, url=None, parameters=None):
+        self.method = method
+        self.url = url
+        if parameters is not None:
+            self.update(parameters)
+ 
+    @setter
+    def url(self, value):
+        self.__dict__['url'] = value
+        if value is not None:
+            scheme, netloc, path, params, query, fragment = urlparse.urlparse(value)
+
+            # Exclude default port numbers.
+            if scheme == 'http' and netloc[-3:] == ':80':
+                netloc = netloc[:-3]
+            elif scheme == 'https' and netloc[-4:] == ':443':
+                netloc = netloc[:-4]
+            if scheme not in ('http', 'https'):
+                raise ValueError("Unsupported URL %s (%s)." % (value, scheme))
+
+            # Normalized URL excludes params, query, and fragment.
+            self.normalized_url = urlparse.urlunparse((scheme, netloc, path, None, None, None))
+        else:
+            self.normalized_url = None
+            self.__dict__['url'] = None
+ 
+    @setter
+    def method(self, value):
+        self.__dict__['method'] = value.upper()
+ 
+    def _get_timestamp_nonce(self):
+        return self['oauth_timestamp'], self['oauth_nonce']
+ 
+    def get_nonoauth_parameters(self):
+        """Get any non-OAuth parameters."""
+        return dict([(k, v) for k, v in self.iteritems() 
+                    if not k.startswith('oauth_')])
+ 
+    def to_header(self, realm=''):
+        """Serialize as a header for an HTTPAuth request."""
+        oauth_params = ((k, v) for k, v in self.items() 
+                            if k.startswith('oauth_'))
+        stringy_params = ((k, escape(str(v))) for k, v in oauth_params)
+        header_params = ('%s="%s"' % (k, v) for k, v in stringy_params)
+        params_header = ', '.join(header_params)
+ 
+        auth_header = 'OAuth realm="%s"' % realm
+        if params_header:
+            auth_header = "%s, %s" % (auth_header, params_header)
+ 
+        return {'Authorization': auth_header}
+ 
+    def to_postdata(self):
+        """Serialize as post data for a POST request."""
+        # tell urlencode to deal with sequence values and map them correctly
+        # to resulting querystring. for example self["k"] = ["v1", "v2"] will
+        # result in 'k=v1&k=v2' and not k=%5B%27v1%27%2C+%27v2%27%5D
+        return urllib.urlencode(self, True)
+ 
+    def to_url(self):
+        """Serialize as a URL for a GET request."""
+        base_url = urlparse.urlparse(self.url)
+        query = parse_qs(base_url.query)
+        for k, v in self.items():
+            query.setdefault(k, []).append(v)
+        url = (base_url.scheme, base_url.netloc, base_url.path, base_url.params,
+               urllib.urlencode(query, True), base_url.fragment)
+        return urlparse.urlunparse(url)
+
+    def get_parameter(self, parameter):
+        ret = self.get(parameter)
+        if ret is None:
+            raise Error('Parameter not found: %s' % parameter)
+
+        return ret
+ 
+    def get_normalized_parameters(self):
+        """Return a string that contains the parameters that must be signed."""
+        items = []
+        for key, value in self.iteritems():
+            if key == 'oauth_signature':
+                continue
+            # 1.0a/9.1.1 states that kvp must be sorted by key, then by value,
+            # so we unpack sequence values into multiple items for sorting.
+            if hasattr(value, '__iter__'):
+                items.extend((key, item) for item in value)
+            else:
+                items.append((key, value))
+
+        # Include any query string parameters from the provided URL
+        query = urlparse.urlparse(self.url)[4]
+        items.extend(self._split_url_string(query).items())
+
+        encoded_str = urllib.urlencode(sorted(items))
+        # Encode signature parameters per Oauth Core 1.0 protocol
+        # spec draft 7, section 3.6
+        # (http://tools.ietf.org/html/draft-hammer-oauth-07#section-3.6)
+        # Spaces must be encoded with "%20" instead of "+"
+        return encoded_str.replace('+', '%20')
+ 
+    def sign_request(self, signature_method, consumer, token):
+        """Set the signature parameter to the result of sign."""
+
+        if 'oauth_consumer_key' not in self:
+            self['oauth_consumer_key'] = consumer.key
+
+        if token and 'oauth_token' not in self:
+            self['oauth_token'] = token.key
+
+        self['oauth_signature_method'] = signature_method.name
+        self['oauth_signature'] = signature_method.sign(self, consumer, token)
+ 
+    @classmethod
+    def make_timestamp(cls):
+        """Get seconds since epoch (UTC)."""
+        return str(int(time.time()))
+ 
+    @classmethod
+    def make_nonce(cls):
+        """Generate pseudorandom number."""
+        return str(random.randint(0, 100000000))
+ 
+    @classmethod
+    def from_request(cls, http_method, http_url, headers=None, parameters=None,
+            query_string=None):
+        """Combines multiple parameter sources."""
+        if parameters is None:
+            parameters = {}
+ 
+        # Headers
+        if headers and 'Authorization' in headers:
+            auth_header = headers['Authorization']
+            # Check that the authorization header is OAuth.
+            if auth_header[:6] == 'OAuth ':
+                auth_header = auth_header[6:]
+                try:
+                    # Get the parameters from the header.
+                    header_params = cls._split_header(auth_header)
+                    parameters.update(header_params)
+                except:
+                    raise Error('Unable to parse OAuth parameters from '
+                        'Authorization header.')
+ 
+        # GET or POST query string.
+        if query_string:
+            query_params = cls._split_url_string(query_string)
+            parameters.update(query_params)
+ 
+        # URL parameters.
+        param_str = urlparse.urlparse(http_url)[4] # query
+        url_params = cls._split_url_string(param_str)
+        parameters.update(url_params)
+ 
+        if parameters:
+            return cls(http_method, http_url, parameters)
+ 
+        return None
+ 
+    @classmethod
+    def from_consumer_and_token(cls, consumer, token=None,
+            http_method=HTTP_METHOD, http_url=None, parameters=None):
+        if not parameters:
+            parameters = {}
+ 
+        defaults = {
+            'oauth_consumer_key': consumer.key,
+            'oauth_timestamp': cls.make_timestamp(),
+            'oauth_nonce': cls.make_nonce(),
+            'oauth_version': cls.version,
+        }
+ 
+        defaults.update(parameters)
+        parameters = defaults
+ 
+        if token:
+            parameters['oauth_token'] = token.key
+            if token.verifier:
+                parameters['oauth_verifier'] = token.verifier
+ 
+        return Request(http_method, http_url, parameters)
+ 
+    @classmethod
+    def from_token_and_callback(cls, token, callback=None, 
+        http_method=HTTP_METHOD, http_url=None, parameters=None):
+
+        if not parameters:
+            parameters = {}
+ 
+        parameters['oauth_token'] = token.key
+ 
+        if callback:
+            parameters['oauth_callback'] = callback
+ 
+        return cls(http_method, http_url, parameters)
+ 
+    @staticmethod
+    def _split_header(header):
+        """Turn Authorization: header into parameters."""
+        params = {}
+        parts = header.split(',')
+        for param in parts:
+            # Ignore realm parameter.
+            if param.find('realm') > -1:
+                continue
+            # Remove whitespace.
+            param = param.strip()
+            # Split key-value.
+            param_parts = param.split('=', 1)
+            # Remove quotes and unescape the value.
+            params[param_parts[0]] = urllib.unquote(param_parts[1].strip('\"'))
+        return params
+ 
+    @staticmethod
+    def _split_url_string(param_str):
+        """Turn URL string into parameters."""
+        parameters = parse_qs(param_str, keep_blank_values=False)
+        for k, v in parameters.iteritems():
+            parameters[k] = urllib.unquote(v[0])
+        return parameters
+
+
+class Client(httplib2.Http):
+    """OAuthClient is a worker to attempt to execute a request."""
+
+    def __init__(self, consumer, token=None, cache=None, timeout=None,
+        proxy_info=None):
+
+        if consumer is not None and not isinstance(consumer, Consumer):
+            raise ValueError("Invalid consumer.")
+
+        if token is not None and not isinstance(token, Token):
+            raise ValueError("Invalid token.")
+
+        self.consumer = consumer
+        self.token = token
+        self.method = SignatureMethod_HMAC_SHA1()
+
+        httplib2.Http.__init__(self, cache=cache, timeout=timeout, 
+            proxy_info=proxy_info)
+
+    def set_signature_method(self, method):
+        if not isinstance(method, SignatureMethod):
+            raise ValueError("Invalid signature method.")
+
+        self.method = method
+
+    def request(self, uri, method="GET", body=None, headers=None, 
+        redirections=httplib2.DEFAULT_MAX_REDIRECTS, connection_type=None):
+        DEFAULT_CONTENT_TYPE = 'application/x-www-form-urlencoded'
+
+        if not isinstance(headers, dict):
+            headers = {}
+
+        is_multipart = method == 'POST' and headers.get('Content-Type', 
+            DEFAULT_CONTENT_TYPE) != DEFAULT_CONTENT_TYPE
+
+        if body and method == "POST" and not is_multipart:
+            parameters = dict(parse_qsl(body))
+        else:
+            parameters = None
+
+        req = Request.from_consumer_and_token(self.consumer, 
+            token=self.token, http_method=method, http_url=uri, 
+            parameters=parameters)
+
+        req.sign_request(self.method, self.consumer, self.token)
+
+        if method == "POST":
+            headers['Content-Type'] = headers.get('Content-Type', 
+                DEFAULT_CONTENT_TYPE)
+            if is_multipart:
+                headers.update(req.to_header())
+            else:
+                body = req.to_postdata()
+        elif method == "GET":
+            uri = req.to_url()
+        else:
+            headers.update(req.to_header())
+
+        return httplib2.Http.request(self, uri, method=method, body=body, 
+            headers=headers, redirections=redirections, 
+            connection_type=connection_type)
+
+
+class Server(object):
+    """A skeletal implementation of a service provider, providing protected
+    resources to requests from authorized consumers.
+ 
+    This class implements the logic to check requests for authorization. You
+    can use it with your web server or web framework to protect certain
+    resources with OAuth.
+    """
+
+    timestamp_threshold = 300 # In seconds, five minutes.
+    version = VERSION
+    signature_methods = None
+
+    def __init__(self, signature_methods=None):
+        self.signature_methods = signature_methods or {}
+
+    def add_signature_method(self, signature_method):
+        self.signature_methods[signature_method.name] = signature_method
+        return self.signature_methods
+
+    def verify_request(self, request, consumer, token):
+        """Verifies an api call and checks all the parameters."""
+
+        version = self._get_version(request)
+        self._check_signature(request, consumer, token)
+        parameters = request.get_nonoauth_parameters()
+        return parameters
+
+    def build_authenticate_header(self, realm=''):
+        """Optional support for the authenticate header."""
+        return {'WWW-Authenticate': 'OAuth realm="%s"' % realm}
+
+    def _get_version(self, request):
+        """Verify the correct version request for this server."""
+        try:
+            version = request.get_parameter('oauth_version')
+        except:
+            version = VERSION
+
+        if version and version != self.version:
+            raise Error('OAuth version %s not supported.' % str(version))
+
+        return version
+
+    def _get_signature_method(self, request):
+        """Figure out the signature with some defaults."""
+        try:
+            signature_method = request.get_parameter('oauth_signature_method')
+        except:
+            signature_method = SIGNATURE_METHOD
+
+        try:
+            # Get the signature method object.
+            signature_method = self.signature_methods[signature_method]
+        except:
+            signature_method_names = ', '.join(self.signature_methods.keys())
+            raise Error('Signature method %s not supported try one of the following: %s' % (signature_method, signature_method_names))
+
+        return signature_method
+
+    def _get_verifier(self, request):
+        return request.get_parameter('oauth_verifier')
+
+    def _check_signature(self, request, consumer, token):
+        timestamp, nonce = request._get_timestamp_nonce()
+        self._check_timestamp(timestamp)
+        signature_method = self._get_signature_method(request)
+
+        try:
+            signature = request.get_parameter('oauth_signature')
+        except:
+            raise MissingSignature('Missing oauth_signature.')
+
+        # Validate the signature.
+        valid = signature_method.check(request, consumer, token, signature)
+
+        if not valid:
+            key, base = signature_method.signing_base(request, consumer, token)
+
+            raise Error('Invalid signature. Expected signature base ' 
+                'string: %s' % base)
+
+        built = signature_method.sign(request, consumer, token)
+
+    def _check_timestamp(self, timestamp):
+        """Verify that timestamp is recentish."""
+        timestamp = int(timestamp)
+        now = int(time.time())
+        lapsed = now - timestamp
+        if lapsed > self.timestamp_threshold:
+            raise Error('Expired timestamp: given %d and now %s has a '
+                'greater difference than threshold %d' % (timestamp, now, 
+                    self.timestamp_threshold))
+
+
+class SignatureMethod(object):
+    """A way of signing requests.
+ 
+    The OAuth protocol lets consumers and service providers pick a way to sign
+    requests. This interface shows the methods expected by the other `oauth`
+    modules for signing requests. Subclass it and implement its methods to
+    provide a new way to sign requests.
+    """
+
+    def signing_base(self, request, consumer, token):
+        """Calculates the string that needs to be signed.
+
+        This method returns a 2-tuple containing the starting key for the
+        signing and the message to be signed. The latter may be used in error
+        messages to help clients debug their software.
+
+        """
+        raise NotImplementedError
+
+    def sign(self, request, consumer, token):
+        """Returns the signature for the given request, based on the consumer
+        and token also provided.
+
+        You should use your implementation of `signing_base()` to build the
+        message to sign. Otherwise it may be less useful for debugging.
+
+        """
+        raise NotImplementedError
+
+    def check(self, request, consumer, token, signature):
+        """Returns whether the given signature is the correct signature for
+        the given consumer and token signing the given request."""
+        built = self.sign(request, consumer, token)
+        return built == signature
+
+
+class SignatureMethod_HMAC_SHA1(SignatureMethod):
+    name = 'HMAC-SHA1'
+        
+    def signing_base(self, request, consumer, token):
+        if request.normalized_url is None:
+            raise ValueError("Base URL for request is not set.")
+
+        sig = (
+            escape(request.method),
+            escape(request.normalized_url),
+            escape(request.get_normalized_parameters()),
+        )
+
+        key = '%s&' % escape(consumer.secret)
+        if token:
+            key += escape(token.secret)
+        raw = '&'.join(sig)
+        return key, raw
+
+    def sign(self, request, consumer, token):
+        """Builds the base signature string."""
+        key, raw = self.signing_base(request, consumer, token)
+
+        # HMAC object.
+        try:
+            from hashlib import sha1 as sha
+        except ImportError:
+            import sha # Deprecated
+
+        hashed = hmac.new(key, raw, sha)
+
+        # Calculate the digest base 64.
+        return binascii.b2a_base64(hashed.digest())[:-1]
+
+
+class SignatureMethod_PLAINTEXT(SignatureMethod):
+
+    name = 'PLAINTEXT'
+
+    def signing_base(self, request, consumer, token):
+        """Concatenates the consumer key and secret with the token's
+        secret."""
+        sig = '%s&' % escape(consumer.secret)
+        if token:
+            sig = sig + escape(token.secret)
+        return sig, sig
+
+    def sign(self, request, consumer, token):
+        key, raw = self.signing_base(request, consumer, token)
+        return raw
diff --git a/oauth2/clients/__init__.py b/oauth2/clients/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/oauth2/clients/__init__.py
diff --git a/oauth2/clients/imap.py b/oauth2/clients/imap.py
new file mode 100644
index 0000000..68b7cd8
--- /dev/null
+++ b/oauth2/clients/imap.py
@@ -0,0 +1,40 @@
+"""
+The MIT License
+
+Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+import oauth2
+import imaplib
+
+
+class IMAP4_SSL(imaplib.IMAP4_SSL):
+    """IMAP wrapper for imaplib.IMAP4_SSL that implements XOAUTH."""
+
+    def authenticate(self, url, consumer, token):
+        if consumer is not None and not isinstance(consumer, oauth2.Consumer):
+            raise ValueError("Invalid consumer.")
+
+        if token is not None and not isinstance(token, oauth2.Token):
+            raise ValueError("Invalid token.")
+
+        imaplib.IMAP4_SSL.authenticate(self, 'XOAUTH',
+            lambda x: oauth2.build_xoauth_string(url, consumer, token))
diff --git a/oauth2/clients/smtp.py b/oauth2/clients/smtp.py
new file mode 100644
index 0000000..3e7bf0b
--- /dev/null
+++ b/oauth2/clients/smtp.py
@@ -0,0 +1,41 @@
+"""
+The MIT License
+
+Copyright (c) 2007-2010 Leah Culver, Joe Stump, Mark Paschal, Vic Fryzel
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
+THE SOFTWARE.
+"""
+
+import oauth2
+import smtplib
+import base64
+
+
+class SMTP(smtplib.SMTP):
+    """SMTP wrapper for smtplib.SMTP that implements XOAUTH."""
+
+    def authenticate(self, url, consumer, token):
+        if consumer is not None and not isinstance(consumer, oauth2.Consumer):
+            raise ValueError("Invalid consumer.")
+
+        if token is not None and not isinstance(token, oauth2.Token):
+            raise ValueError("Invalid token.")
+
+        self.docmd('AUTH', 'XOAUTH %s' % \
+            base64.b64encode(oauth2.build_xoauth_string(url, consumer, token)))
