Update a cache entry.  If something is wrong, return
    *None*. Return *True* if the cache was updated and *False* if not.  If
    *use_linecache_lines* is *True*, use an existing cache entry as source
    for the lines of the file.

def update_cache(filename, opts=default_opts, module_globals=None):
    """Update a cache entry.  If something is wrong, return
    *None*. Return *True* if the cache was updated and *False* if not.  If
    *use_linecache_lines* is *True*, use an existing cache entry as source
    for the lines of the file."""

    if not filename: return None

    orig_filename = filename
    filename = pyc2py(filename)
    if filename in file_cache: del file_cache[filename]
    path = os.path.abspath(filename)
    stat = None
    if get_option('use_linecache_lines', opts):
        fname_list = [filename]
        mapped_path = file2file_remap.get(path)
        if mapped_path:
            fname_list.append(mapped_path)
            for filename in fname_list:
                try:
                    stat = os.stat(filename)
                    plain_lines = linecache.getlines(filename)
                    trailing_nl = has_trailing_nl(plain_lines[-1])
                    lines = {
                        'plain'   : plain_lines,
                        }
                    file_cache[filename] = LineCacheInfo(stat, None, lines,
                                                         path, None)
                except:
                    pass
                pass
            if orig_filename != filename:
                file2file_remap[orig_filename] = filename
                file2file_remap[os.path.abspath(orig_filename)] = filename
                pass
            file2file_remap[path] = filename
            return filename
        pass
    pass

    if os.path.exists(path):
        stat = os.stat(path)
    elif module_globals and '__loader__' in module_globals:
        name = module_globals.get('__name__')
        loader = module_globals['__loader__']
        get_source = getattr(loader, 'get_source', None)
        if name and get_source:
            try:
                data = get_source(name)
            except (ImportError, IOError):
                pass
            else:
                if data is None:
                    # No luck, the PEP302 loader cannot find the source
                    # for this module.
                    return None
                # FIXME: DRY with code below
                lines = {'plain' : data.splitlines()}
                raw_string        = ''.join(lines['plain'])
                trailing_nl       = has_trailing_nl(raw_string)
                if 'style' in opts:
                    key = opts['style']
                    highlight_opts = {'style': key}
                else:
                    key = 'terminal'
                    highlight_opts = {}

                lines[key] = highlight_array(raw_string.split('\n'),
                                    trailing_nl, **highlight_opts)
                file_cache[filename] = \
                  LineCacheInfo(None, None, lines, filename, None)
                file2file_remap[path] = filename
                return True
            pass
        pass
    if not os.path.isabs(filename):
        # Try looking through the module search path, which is only useful
        # when handling a relative filename.
        stat = None
        for dirname in sys.path:
            path = os.path.join(dirname, filename)
            if os.path.exists(path):
                stat = os.stat(path)
                break
            pass
        if not stat: return False
        pass

    try:
        mode = 'r' if PYTHON3 else 'rU'
        with open(path, mode) as fp:
                lines = {'plain' : fp.readlines()}
                eols = fp.newlines
    except:
        return None

    # FIXME: DRY with code above
    raw_string        = ''.join(lines['plain'])
    trailing_nl       = has_trailing_nl(raw_string)
    if 'style' in opts:
        key = opts['style'] or 'default'
        highlight_opts = {'style': key}
    else:
        key = 'terminal'
        highlight_opts = {}

    lines[key] = highlight_array(raw_string.split('\n'),
                                 trailing_nl, **highlight_opts)
    if orig_filename != filename:
        file2file_remap[orig_filename] = filename
        file2file_remap[os.path.abspath(orig_filename)] = filename
        pass
    pass

    file_cache[filename] = LineCacheInfo(stat, None, lines, path, None, eols)
    file2file_remap[path] = filename
    return True