encapsulates urllib retrieval for fetching JSON results from
        Google's Custom Search API.  Returns a deserialized result set.

def web_search(self, query, start=0, limit=100, max_tries=3):
        '''
        encapsulates urllib retrieval for fetching JSON results from
        Google's Custom Search API.  Returns a deserialized result set.
        '''
        tries = 0
        if isinstance(query, unicode):
            query = query.encode('utf8')
        url = self.url % dict(key=self.api_key,
                              query=urllib.quote(query.strip()),
                              num=min(10, limit - start),
                              start=start)
        logger.info("fetching: %s" % url)
        while 1:
            try:
                request = urllib2.Request(url)
                request.add_header('Accept-encoding', 'gzip')
                # We do we set this?  Remnant from pre-API version?
                request.add_header('User-Agent', USER_AGENT)
                opener = urllib2.build_opener()

                fh = opener.open(request, timeout=60)
                data = fh.read()
                if fh.headers.get('Content-Encoding') == 'gzip':
                    compressedstream = StringIO.StringIO(data)
                    fh = gzip.GzipFile(fileobj=compressedstream)
                    data = fh.read()
                return json.loads(data)
            except Exception, exc:
                logger.info(traceback.format_exc(exc))
                if tries >= max_tries:
                    sys.exit("failed %d times to fetch %s" % (max_tries, url))
                else:
                    logger.info("failed to fetch\n\t%s\nwill try "
                                "%d more times" % (url, max_tries - tries))
                    tries += 1
                    time.sleep(2 ** tries)