def search_for(search, reldate=None, mindate=None, maxdate=None,
               batchsize=100, delay=2, callback_fn=None,
               start_id=0, max_ids=None):
    """search_for(search[, reldate][, mindate][, maxdate]
    [, batchsize][, delay][, callback_fn][, start_id][, max_ids]) -> ids

    Search PubMed and return a list of the PMID's that match the
    criteria.  search is the search string used to search the
    database.  reldate is the number of dates prior to the current
    date to restrict the search.  mindate and maxdate are the dates to
    restrict the search, e.g. 2002/01/01.  batchsize specifies the
    number of ids to return at one time.  By default, it is set to
    10000, the maximum.  delay is the number of seconds to wait
    between queries (default 2).  callback_fn is an optional callback
    function that will be called as passed a PMID as results are
    retrieved.  start_id specifies the index of the first id to
    retrieve and max_ids specifies the maximum number of id's to
    retrieve.

    XXX The date parameters don't seem to be working with NCBI's
    script.  Please let me know if you can get it to work.
    
    """
    class ResultParser(sgmllib.SGMLParser):
        # Parse the ID's out of the XML-formatted page that PubMed
        # returns.  The format of the page is:
        # [...]
        #    <Id>...</Id>
        # [...]
        def __init__(self):
            sgmllib.SGMLParser.__init__(self)
            self.ids = []
            self.in_id = 0
        def start_id(self, attributes):
            self.in_id = 1
        def end_id(self):
            self.in_id = 0
        _not_pmid_re = re.compile(r'\D')
        def handle_data(self, data):
            if not self.in_id:
                return
            # If data is just whitespace, then ignore it.
            data = string.strip(data)
            if not data:
                return
            # Everything here should be a PMID.  Check and make sure
            # data really is one.  A PMID should be a string consisting
            # of only integers.  Should I check to make sure it
            # meets a certain minimum length?
            if self._not_pmid_re.search(data):
                raise ValueError, \
                      "I expected an ID, but %s doesn't look like one." % \
                      repr(data)
            self.ids.append(data)

    params = {
        'db' : 'pubmed',
        'term' : search,
        'reldate' : reldate,
        'mindate' : mindate,
        'maxdate' : maxdate
        }
    for k, v in params.items():
        if v is None:
            del params[k]

    limiter = RequestLimiter(delay)
    ids = []
    while max_ids is None or len(ids) < max_ids:
        parser = ResultParser()
        
        # Check to make sure enough time has passed before my
        # last search.  If not, then wait.
        limiter.wait()

        start = start_id + len(ids)
        max = batchsize
        if max_ids is not None and max > max_ids - len(ids):
            max = max_ids - len(ids)

        params['retstart'] = start
        params['retmax'] = max
        h = NCBI.esearch(**params)
        parser.feed(h.read())
        ids.extend(parser.ids)
        if callback_fn is not None:
            # Call the callback function with each of the new ID's.
            for id in parser.ids:
                callback_fn(id)
        if len(parser.ids) < max or not parser.ids:  # no more id's to read
            break
    return ids