Add a body to the request.

        When `body` is a:
            - string, it will be used as is. 
            - dict or list of (key, value) pairs, it will be form encoded
            - None, remove request body
            - anything else, a TypeError will be raised 
            
        If `body` is a dict or None you can also pass in keyword
        arguments to add to the body.

        ::
            >>> dolt.with_body(dict(key='val'), foo='bar')._body
            'foo=bar&key=val'

def with_body(self, body=None, **params):
        """
        Add a body to the request.

        When `body` is a:
            - string, it will be used as is. 
            - dict or list of (key, value) pairs, it will be form encoded
            - None, remove request body
            - anything else, a TypeError will be raised 
            
        If `body` is a dict or None you can also pass in keyword
        arguments to add to the body.

        ::
            >>> dolt.with_body(dict(key='val'), foo='bar')._body
            'foo=bar&key=val'
        """

        if isinstance(body, (tuple, list)):
            body = dict(body)

        if params:
            # Body must be None or able to be a dict
            if isinstance(body, dict):
                body.update(params)
            elif body is None:
                body = params
            else:
                raise ValueError('Body must be None or a dict if used with params, got: %r' % body)

        if isinstance(body, basestring):
            self._body = body
        elif isinstance(body, dict):
            self._body = urllib.urlencode(body)
        elif body is None:
            self._body = None
        else:
            raise TypeError('Invalid body type %r' % body)        
        

        return self