'(Re-)read all files new or changed since last update.  Returns a
summary, the total count of documents to reread and an iterator that
yields docnames as it processes them.  Store all environment docnames in
the canonical format (ie using SEP as a separator in place of
os.path.sep).'

def update(self, config, srcdir, doctreedir, app=None):

    config_changed = False
    if (self.config is None):
        msg = '[new    config]    '
        config_changed = True
    else:
        for (key, descr) in config.values.iteritems():
            if (descr[1] != 'env'):
                continue
            if (self.config[key] != config[key]):
                msg = '[config    changed]    '
                config_changed = True
                break
        else:
            msg = ''
        if (self.config.extensions != config.extensions):
            msg = '[extensions    changed]    '
            config_changed = True
    self.srcdir = srcdir
    self.doctreedir = doctreedir
    self.find_files(config)
    self.config = config
    (added, changed, removed) = self.get_outdated_files(config_changed)
    if (added or removed):
        changed.update(self.glob_toctrees)
    msg += ('%s    added,    %s    changed,    %s    removed' % (len(added), len(changed), len(removed)))
    def update_generator():
        self.app = app
        for docname in removed:
            if app:
                app.emit('env-purge-doc', self, docname)
            self.clear_doc(docname)
        to_read = (added | changed)
        for docname in sorted(to_read):
            (yield docname)
            self.read_doc(docname, app=app)
        if (config.master_doc not in self.all_docs):
            self.warn(None, ('master    file    %s    not    found' % self.doc2path(config.master_doc)))
        self.app = None
        if app:
            app.emit('env-updated', self)
    return (msg, len((added | changed)), update_generator())
