docs: def shorten(self, url, custom_url = None, log_stat = False):
          '''
              Shorten an URL using `is.gd - v.gd url shortener service <http://is.gd/developers.php>`_.
              
              :param url: URL that had to be shortened
              :type url: str.
              
              :param custom_url: if specified, the url generated will be http://is.gd/<custom_url> (or http://v.gd/<custom_url>).
              
                  Please note that if this custom url is unavailable (because it is already used, for example), a :class:`gdshortener.GDShortURLError` will be raised
              
              :type custom_url: str.
              :param log_stat: States if the generated url has statistical analisys attached.
                  If the stats are enabled, a special url will show the stats on this shortened url. This special url is returned as second parameters of this function.
                  
                  Please notice that a stat enabled shorten url counts double in .gd rate exceeding monitor system.
                  
                  More information on `.gd FAQ <http://is.gd/faq.php#stats>`_ and `.gd rate limit <http://is.gd/usagelimits.php>`_.
              :type log_stat: bool.
              :returns:  (str,str) -- Shortened URL obtained by .gd service and Stat URL if requested (otherwhise is ``None``).
              :raises: **IOError** when timeout with .gd service occurs
              
                  **ValueError** if .gd response is malformed
                  
                  :class:`gdshortener.GDMalformedURLError` if the URL provided for shortening is malformed
                  
                  :class:`gdshortener.GDShortURLError` if the custom URL requested is not available
                  
                  :class:`gdshortener.GDRateLimitError` if the request rate is exceeded for .gd service
                  
                  :class:`gdshortener.GDGenericError` in case of generic error from .gd service (mainteinance)
              
          ''' 
          if url is None or not isinstance(url, basestring) or len(url.strip()) == 0:
              raise GDMalformedURLError('The URL that had to be shorten must be a non empty string')
          # Build data to post
          data = {
                  'format':   'json',
                  'url':      url,
                  'logstats': 1 if log_stat else 0
                  }
          if custom_url is not None and isinstance(custom_url, basestring) and len(custom_url.strip()) > 0:
              data['shorturl'] = custom_url
          opener = urllib2.build_opener()
          headers = { 'User-Agent' : self._user_agent }
          req = urllib2.Request("{0}/create.php".format(self.shortener_url), urllib.urlencode(data), headers)
          f_desc = opener.open(req, timeout = self._timeout)
          response = json.loads(f_desc.read())
          if 'shorturl' in response:
              # Success!
              return (str(response['shorturl']), None if not log_stat else '{0}/stats.php?url={1}'.format(self.shortener_url, str(response['shorturl'])[str(response['shorturl']).rindex('/') + 1:]))
          else:
              # Error
              error_code = int(response['errorcode'])
              error_description = str(response['errormessage'])
              if error_code == 1:
                  raise GDMalformedURLError(error_description)
              if error_code == 2:
                  raise GDShortURLError(error_description)
              if error_code == 3:
                  raise GDRateLimitError(error_description)
              if error_code == 4:
                  raise GDGenericError(error_description)