extract cache into its own class
document when cache_dir is nil
extract metadata into its own class