[med-svn] [r-cran-r.cache] 01/02: Imported Upstream version 0.12.0

Michael Crusoe misterc-guest at moszumanska.debian.org
Sat Jun 25 21:47:23 UTC 2016


This is an automated email from the git hooks/post-receive script.

misterc-guest pushed a commit to branch master
in repository r-cran-r.cache.

commit e33758aa105add878a1ef0445e1810062afc0a96
Author: Michael R. Crusoe <crusoe at ucdavis.edu>
Date:   Sat Jun 25 14:11:41 2016 -0700

    Imported Upstream version 0.12.0
---
 .Rbuildignore                      |  36 +++
 .covr.R                            |  26 ++
 .gitignore                         |   9 +
 .make/Makefile                     | 475 +++++++++++++++++++++++++++++++++++++
 .travis.yml                        |  87 +++++++
 DESCRIPTION                        |  21 ++
 Makefile                           |   1 +
 NAMESPACE                          |  78 ++++++
 NEWS                               | 311 ++++++++++++++++++++++++
 R/000.R                            |   4 +
 R/006.fixVarArgs.R                 |  10 +
 R/999.NonDocumentedObjects.R       |  34 +++
 R/999.package.R                    |  65 +++++
 R/Object.getChecksum.R             |  16 ++
 R/addMemoization.R                 |  81 +++++++
 R/addREADME.R                      |  17 ++
 R/clearCache.R                     | 160 +++++++++++++
 R/evalWithMemoization.R            |  80 +++++++
 R/findCache.R                      |  66 ++++++
 R/generateCache.R                  |  73 ++++++
 R/getCachePath.R                   |  83 +++++++
 R/getCacheRootPath.R               |  79 ++++++
 R/getChecksum.R                    |  63 +++++
 R/loadCache.R                      | 178 ++++++++++++++
 R/memoizedCall.R                   |  76 ++++++
 R/private.assertDigest.R           |  61 +++++
 R/private.baseLoad.R               | 102 ++++++++
 R/readCacheHeader.R                | 120 ++++++++++
 R/saveCache.R                      | 139 +++++++++++
 R/setCachePath.R                   |  48 ++++
 R/setCacheRootPath.R               |  65 +++++
 R/setupCacheRootPath.R             |  82 +++++++
 R/textPrompt.R                     |  74 ++++++
 R/zzz.R                            |  24 ++
 README.md                          |  19 ++
 appveyor.yml                       |  62 +++++
 cran-comments.md                   |  32 +++
 incl/BengtssonH_2003.bib.Rdoc      |   1 +
 incl/evalWithMemoization.Rex       |  77 ++++++
 incl/loadCache.Rex                 |  26 ++
 incl/readCacheHeader.Rex           |  11 +
 inst/_Rcache/README.txt            |   7 +
 man/000.baseLoad.Rd                |  57 +++++
 man/Non-documented_objects.Rd      |  38 +++
 man/R.cache-package.Rd             |  86 +++++++
 man/addMemoization.Rd              |  53 +++++
 man/clearCache.Rd                  |  51 ++++
 man/evalWithMemoization.Rd         | 127 ++++++++++
 man/findCache.Rd                   |  46 ++++
 man/generateCache.Rd               |  48 ++++
 man/getCachePath.Rd                |  49 ++++
 man/getCacheRootPath.Rd            |  47 ++++
 man/getChecksum.Rd                 |  61 +++++
 man/loadCache.Rd                   |  96 ++++++++
 man/memoizedCall.Rd                |  56 +++++
 man/readCacheHeader.Rd             |  61 +++++
 man/saveCache.Rd                   |  69 ++++++
 man/setCachePath.Rd                |  46 ++++
 man/setCacheRootPath.Rd            |  42 ++++
 man/setupCacheRootPath.Rd          |  55 +++++
 tests/Object.getChecksum.R         |   5 +
 tests/StaticMethodsAndNamespaces.R |   1 +
 tests/addMemoization.R             |  55 +++++
 tests/assertDigest.R               |   4 +
 tests/clearCache.R                 |  16 ++
 tests/evalWithMemoization.R        |  46 ++++
 tests/getCachePath.R               |  10 +
 tests/getCacheRootPath.R           |  43 ++++
 tests/loadCache.R                  |  37 +++
 tests/memoizedCall.R               |  40 ++++
 tests/readCacheHeader.R            |  24 ++
 tests/setCachePath.R               |  12 +
 tests/setCacheRootPath.R           |   9 +
 tests/textPrompt.R                 |  15 ++
 74 files changed, 4484 insertions(+)

diff --git a/.Rbuildignore b/.Rbuildignore
new file mode 100644
index 0000000..238aee9
--- /dev/null
+++ b/.Rbuildignore
@@ -0,0 +1,36 @@
+#----------------------------
+# Git and SVN related
+#----------------------------
+^.svn
+^.git
+^.make
+INSTALL[.]md
+OVERVIEW[.]md
+
+#----------------------------
+# Travis-CI et al.
+#----------------------------
+^[.]travis[.]yml$
+^travis-tool[.]sh$
+^pkg-build[.]sh$
+^appveyor[.]yml$
+^covr-utils.R$
+^[.]covr[.]R$
+
+#----------------------------
+# R related
+#----------------------------
+^cran-comments[.].*$
+^vignettes/.*[.](pdf|PDF)$
+^vignettes/.*[.](r|R)$
+^vignettes/[.]install_extras$
+^Makefile$
+^incl
+^NAMESPACE,.*[.]txt$
+^nohup.*$
+^[.]R
+^[.]benchmark
+^[.]devel
+^[.]test
+^[.]check
+^.*[.]tar[.]gz$
diff --git a/.covr.R b/.covr.R
new file mode 100644
index 0000000..0025697
--- /dev/null
+++ b/.covr.R
@@ -0,0 +1,26 @@
+#################################################################
+# Test coverage
+#
+# * covr-utils: https://github.com/HenrikBengtsson/covr-utils
+# * covr: https://github.com/jimhester/covr
+# * Coveralls: https://coveralls.io/
+#
+# Henrik Bengtsson
+#################################################################
+if (!file_test("-f", "covr-utils.R")) {
+  source("http://callr.org/install#R.utils[u]")
+  R.utils::downloadFile("https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/covr-utils.R")
+}
+
+source("covr-utils.R")
+
+# Exclusion rules
+excl <- exclusions(
+  filter(r_files(), covr_lines), # Apply 'covr:' rules in source code
+  filter(r_files(), stop_lines)  # Skip lines with stop().
+)
+str(excl)
+
+# Run through tests, record source code coverage, and
+# publish to Coveralls
+covr <- covr_package(exclusions=excl, quiet=FALSE)
diff --git a/.gitignore b/.gitignore
new file mode 100644
index 0000000..84662ea
--- /dev/null
+++ b/.gitignore
@@ -0,0 +1,9 @@
+.Rhistory
+*~
+**/*~
+.R
+.benchmark
+.check
+.test
+.o
+.dll
diff --git a/.make/Makefile b/.make/Makefile
new file mode 100644
index 0000000..ce331ea
--- /dev/null
+++ b/.make/Makefile
@@ -0,0 +1,475 @@
+# Makefile for R packages
+
+# CORE MACROS
+ifeq ($(OS), Windows_NT)
+CD=cd
+CURDIR=$(subst \,/,$(shell cmd.exe /C cd))
+FSEP=;
+else
+CD=cd -P "$(CURDIR)"; cd   # This handles the case when CURDIR is a softlink
+FSEP=:
+endif
+CP=cp
+MAKE=make
+MV=mv
+RM=rm -f
+MKDIR=mkdir -p
+RMDIR=$(RM) -r
+GIT=git
+
+# PACKAGE MACROS
+PKG_VERSION := $(shell grep -i ^version DESCRIPTION | cut -d : -d \  -f 2)
+PKG_NAME    := $(shell grep -i ^package DESCRIPTION | cut -d : -d \  -f 2)
+PKG_DIR     := $(shell basename "$(CURDIR)")
+PKG_DIR     := $(CURDIR)
+PKG_TARBALL := $(PKG_NAME)_$(PKG_VERSION).tar.gz
+PKG_ZIP     := $(PKG_NAME)_$(PKG_VERSION).zip
+PKG_TGZ     := $(PKG_NAME)_$(PKG_VERSION).tgz
+
+# FILE MACROS
+FILES_R := $(wildcard R/*.R)
+FILES_DATA := $(wildcard data/*)
+FILES_MAN := $(wildcard man/*.Rd)
+FILES_INCL := $(wildcard incl/*)
+FILES_INST := $(wildcard inst/* inst/*/* inst/*/*/* inst/*/*/*/*)
+FILES_VIGNETTES := $(wildcard vignettes/* vignettes/.install_extras)
+FILES_SRC := $(wildcard src/* src/*/* src/*/*/* src/*/*/*/* src/*/*/*/*/* src/*/*/*/*/*/* src/*/*/*/*/*/*/* src/*/*/*/*/*/*/*/*)
+FILES_SRC_C := $(wildcard src/*.c)
+FILES_SRC_H := $(wildcard src/*.h)
+FILES_TESTS := $(wildcard tests/*.R)
+FILES_NEWS := $(wildcard NEWS inst/NEWS)
+FILES_MISC := $(wildcard README.md)
+FILES_ROOT := DESCRIPTION NAMESPACE $(wildcard .Rbuildignore .Rinstignore)
+PKG_FILES := $(FILES_ROOT) $(FILES_NEWS) $(FILES_R) $(FILES_DATA) $(FILES_MAN) $(FILES_INST) $(FILES_VIGNETTES) $(FILES_SRC) $(FILES_TESTS) $(FILES_MISC)
+FILES_MAKEFILE := $(wildcard ../../Makefile)
+
+# Has vignettes in 'vignettes/' or 'inst/doc/'?
+DIR_VIGNS := $(wildcard vignettes inst/doc)
+
+# R MACROS
+R = R
+R_SCRIPT = Rscript
+R_HOME := $(shell $(R_SCRIPT) -e "cat(R.home())")
+
+## R_USE_CRAN := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('R_USE_CRAN', 'FALSE'))")
+R_NO_INIT := --no-init-file
+R_VERSION_STATUS := $(shell $(R_SCRIPT) -e "status <- tolower(R.version[['status']]); if (regexpr('unstable', status) != -1L) status <- 'devel'; cat(status)")
+R_VERSION_X_Y := $(shell $(R_SCRIPT) -e "cat(gsub('[.][0-9]+$$', '', getRversion()))")
+R_VERSION := $(shell $(R_SCRIPT) -e "cat(as.character(getRversion()))")
+R_VERSION_FULL := $(R_VERSION)$(R_VERSION_STATUS)
+R_LIBS_USER_X := $(shell $(R_SCRIPT) -e "cat(.libPaths()[1])")
+R_INCLUDE := $(shell $(R_SCRIPT) -e "cat(R.home('include'))")
+R_OUTDIR := ../_R-$(R_VERSION_FULL)
+## R_BUILD_OPTS :=
+## R_BUILD_OPTS := $(R_BUILD_OPTS) --no-build-vignettes
+R_CHECK_OUTDIR := $(R_OUTDIR)/$(PKG_NAME).Rcheck
+_R_CHECK_CRAN_INCOMING_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_CRAN_INCOMING_', 'FALSE'))")
+_R_CHECK_XREFS_REPOSITORIES_ = $(shell if test "$(_R_CHECK_CRAN_INCOMING_)" = "TRUE"; then echo ""; else echo "invalidURL"; fi)
+_R_CHECK_FULL_ = $(shell $(R_SCRIPT) -e "cat(Sys.getenv('_R_CHECK_FULL_', ''))")
+R_CHECK_OPTS = --as-cran --timings $(shell if test "$(_R_CHECK_USE_VALGRIND_)" = "TRUE"; then echo "--use-valgrind"; fi)
+R_RD4PDF = $(shell $(R_SCRIPT) -e "if (getRversion() < 3) cat('times,hyper')")
+R_CRAN_OUTDIR := $(R_OUTDIR)/$(PKG_NAME)_$(PKG_VERSION).CRAN
+
+HAS_ASPELL := $(shell $(R_SCRIPT) -e "cat(Sys.getenv('HAS_ASPELL', !inherits(try(aspell('DESCRIPTION', control=c('--master=en_US', '--add-extra-dicts=en_GB'), dictionaries='en_stats', program='aspell'), silent=TRUE), 'try-error')))")
+
+## Git related
+GIT_BRANCH := $(shell $(GIT) symbolic-ref --short HEAD)
+GIT_BRANCH := $(subst /,-,$(GIT_BRANCH))
+GIT_COMMIT := $(shell $(GIT) log -1 --format="%h")
+R_LIBS_BRANCH := $(CURDIR)/.R/$(GIT_BRANCH)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Main
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+all: build install check
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Displays macros
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+debug:
+	@echo CURDIR=\'$(CURDIR)\'
+	@echo R_HOME=\'$(R_HOME)\'
+	@echo
+	@echo PKG_DIR=\'$(PKG_DIR)\'
+	@echo PKG_NAME=\'$(PKG_NAME)\'
+	@echo PKG_VERSION=\'$(PKG_VERSION)\'
+	@echo PKG_TARBALL=\'$(PKG_TARBALL)\'
+	@echo
+	@echo HAS_ASPELL=\'$(HAS_ASPELL)\'
+	@echo
+	@echo R=\'$(R)\'
+##	@echo R_USE_CRAN=\'$(R_USE_CRAN)\'
+	@echo R_NO_INIT=\'$(R_NO_INIT)\'
+	@echo R_SCRIPT=\'$(R_SCRIPT)\'
+	@echo R_VERSION_X_Y=\'$(R_VERSION_X_Y)\'
+	@echo R_VERSION=\'$(R_VERSION)\'
+	@echo R_VERSION_STATUS=\'$(R_VERSION_STATUS)\'
+	@echo R_VERSION_FULL=\'$(R_VERSION_FULL)\'
+	@echo R_LIBS_USER_X=\'$(R_LIBS_USER_X)\'
+	@echo R_INCLUDE=\'$(R_INCLUDE)\'
+	@echo R_OUTDIR=\'$(R_OUTDIR)\'
+	@echo
+	@echo "Default packages:" $(shell $(R) --slave -e "cat(paste(getOption('defaultPackages'), collapse=', '))")
+	@echo
+	@echo R_BUILD_OPTS=\'$(R_BUILD_OPTS)\'
+	@echo
+	@echo R_CHECK_OUTDIR=\'$(R_CHECK_OUTDIR)\'
+	@echo _R_CHECK_CRAN_INCOMING_=\'$(_R_CHECK_CRAN_INCOMING_)\'
+	@echo _R_CHECK_XREFS_REPOSITORIES_=\'$(_R_CHECK_XREFS_REPOSITORIES_)\'
+	@echo _R_CHECK_FULL_=\'$(_R_CHECK_FULL_)\'
+	@echo R_CHECK_OPTS=\'$(R_CHECK_OPTS)\'
+	@echo R_RD4PDF=\'$(R_RD4PDF)\'
+	@echo
+	@echo R_CRAN_OUTDIR=\'$(R_CRAN_OUTDIR)\'
+	@echo
+
+
+debug_full: debug
+	@echo
+	@echo FILES_ROOT=\'$(FILES_ROOT)\'
+	@echo FILES_R=\'$(FILES_R)\'
+	@echo FILES_DATA=\'$(FILES_DATA)\'
+	@echo FILES_MAN=\'$(FILES_MAN)\'
+	@echo FILES_INST=\'$(FILES_INST)\'
+	@echo FILES_VIGNETTES=\'$(FILES_VIGNETTES)\'
+	@echo FILES_SRC=\'$(FILES_SRC)\'
+	@echo FILES_TESTS=\'$(FILES_TESTS)\'
+	@echo FILES_INCL=\'$(FILES_INCL)\'
+	@echo FILES_MISC=\'$(FILES_MISC)\'
+	@echo
+	@echo DIR_VIGNS=\'$(DIR_VIGNS)\'
+	@echo dirname\(DIR_VIGNS\)=\'$(shell dirname $(DIR_VIGNS))\'
+	@echo
+	@echo GIT_BRANCH=\'$(GIT_BRANCH)\'
+	@echo GIT_COMMIT=\'$(GIT_COMMIT)\'
+	@echo R_LIBS_BRANCH=\'$(R_LIBS_BRANCH)\'
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Update / install
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Update existing packages
+update:
+	$(R_SCRIPT) -e "try(update.packages(ask=FALSE)); source('http://bioconductor.org/biocLite.R'); biocLite(ask=FALSE);"
+
+# Install missing dependencies
+deps: DESCRIPTION
+	$(MAKE) update
+	$(R_SCRIPT) -e "x <- unlist(strsplit(read.dcf('DESCRIPTION',fields=c('Depends', 'Imports', 'Suggests')),',')); x <- gsub('([[:space:]]*|[(].*[)])', '', x); libs <- .libPaths()[file.access(.libPaths(), mode=2) == 0]; x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); if (length(x) > 0) { try(install.packages(x)); x <- unique(setdiff(x, c('R', rownames(installed.packages(lib.loc=libs))))); source('http://bioconductor.org/biocLite.R'); biocLite(x); }"
+
+setup:	update deps
+	$(R_SCRIPT) -e "source('http://aroma-project.org/hbLite.R'); hbLite('R.oo')"
+
+ns:
+	$(R_SCRIPT) -e "library('$(PKG_NAME)'); source('X:/devtools/NAMESPACE.R'); writeNamespaceSection('$(PKG_NAME)'); writeNamespaceImports('$(PKG_NAME)');"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build source tarball
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/$(PKG_TARBALL): $(PKG_FILES)
+	$(MKDIR) $(R_OUTDIR)
+	$(RM) $@
+	$(CD) $(R_OUTDIR);\
+	$(R) $(R_NO_INIT) CMD build $(R_BUILD_OPTS) $(PKG_DIR)
+
+build: $(R_OUTDIR)/$(PKG_TARBALL)
+
+build_force:
+	$(RM) $(R_OUTDIR)/$(PKG_TARBALL)
+	$(MAKE) install
+
+# Make sure the tarball is readable
+build_fix: $(R_OUTDIR)/$(PKG_TARBALL)
+ifeq ($(OS), Windows_NT)
+  ifeq ($(USERNAME), hb)
+	$(MKDIR) X:/tmp/$(R_VERSION_FULL)
+	$(CP) -f $< X:/tmp/$(R_VERSION_FULL)/
+	$(RM) $<
+	$(MV) X:/tmp/$(R_VERSION_FULL)/$(<F) $<
+  endif
+endif
+
+build_fast: $(PKG_FILES)
+	$(MKDIR) $(R_OUTDIR)
+	$(RM) $@
+	$(CD) $(R_OUTDIR);\
+	$(R) $(R_NO_INIT) CMD build --keep-empty-dirs --no-build-vignettes --no-manual --no-resave-data --compact-vignettes="no" $(R_BUILD_OPTS) $(PKG_DIR)
+
+build: $(R_OUTDIR)/$(PKG_TARBALL)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Install on current system
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL $(PKG_TARBALL)
+
+install: $(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION
+
+install_force:
+	$(RM) $(R_LIBS_USER_X)/$(PKG_NAME)/DESCRIPTION
+	$(MAKE) install
+
+install_fast:
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL --no-docs --no-multiarch --no-byte-compile --no-test-load $(PKG_TARBALL)
+
+
+$(R_LIBS_BRANCH)/$(PKG_NAME)/DESCRIPTION: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(MKDIR) $(R_LIBS_BRANCH);\
+	$(R) --no-init-file CMD INSTALL --library=$(R_LIBS_BRANCH) $(PKG_TARBALL)
+
+install_branch: $(R_LIBS_BRANCH)/$(PKG_NAME)/DESCRIPTION
+
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Check source tarball
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_CHECK_OUTDIR)/.check.complete: $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(RM) -r $(PKG_NAME).Rcheck;\
+	export _R_CHECK_CRAN_INCOMING_=$(_R_CHECK_CRAN_INCOMING_);\
+	export _R_CHECK_CRAN_INCOMING_USE_ASPELL_=$(HAS_ASPELL);\
+	export _R_CHECK_XREFS_REPOSITORIES_=$(_R_CHECK_XREFS_REPOSITORIES_);\
+	export _R_CHECK_DOT_INTERNAL_=1;\
+	export _R_CHECK_USE_CODETOOLS_=1;\
+	export _R_CHECK_FORCE_SUGGESTS_=0;\
+	export R_RD4PDF=$(R_RD4PDF);\
+	export _R_CHECK_FULL_=$(_R_CHECK_FULL_);\
+	$(R) --no-init-file CMD check $(R_CHECK_OPTS) $(PKG_TARBALL);\
+	echo done > $(PKG_NAME).Rcheck/.check.complete
+
+check: $(R_CHECK_OUTDIR)/.check.complete
+
+check_force:
+	$(RM) -r $(R_CHECK_OUTDIR)
+	$(MAKE) check
+
+clang:
+	clang -c -pedantic -Wall -I$(R_INCLUDE) src/*.c
+	$(RM) *.o
+
+clang-ubsan:
+	clang -fsanitize=undefined -I$(R_INCLUDE) -c src/*.c
+	$(RM) *.o
+
+valgrind_scan:
+	grep -E "^==.*==[ ]+(at|by) 0x" $(R_CHECK_OUTDIR)/tests*/*.Rout | cat
+	grep "^==.* ERROR SUMMARY:" $(R_CHECK_OUTDIR)/tests*/*.Rout | grep -v -F "ERROR SUMMARY: 0 errors" | cat
+
+valgrind:
+	export _R_CHECK_USE_VALGRIND_=TRUE;\
+	$(MAKE) check_force
+	$(MAKE) valgrind_scan
+
+# Check the line width of incl/*.(R|Rex) files [max 100 chars in R devel]
+check_Rex:
+	$(R_SCRIPT) -e "if (!file.exists('incl')) quit(status=0); setwd('incl/'); fs <- dir(pattern='[.](R|Rex)$$'); ns <- sapply(fs, function(f) max(nchar(readLines(f)))); ns <- ns[ns > 100]; print(ns); if (length(ns) > 0L) quit(status=1)"
+
+
+covr:
+	$(R_SCRIPT) -e "source('.covr.R'); covr::shine(covr)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Install and build binaries
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/$(PKG_ZIP): $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(CD) $(R_OUTDIR);\
+	$(R) --no-init-file CMD INSTALL --build --merge-multiarch $(PKG_TARBALL)
+
+binary: $(R_OUTDIR)/$(PKG_ZIP)
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build Rd help files from Rdoc comments
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+rox:
+	$(R_SCRIPT) -e "roxygen2::roxygenize()"
+
+Rd: check_Rex
+	$(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)')"
+
+%.Rd:
+	$(R_SCRIPT) -e "setwd('..'); Sys.setlocale(locale='C'); R.oo::compileRdoc('$(PKG_NAME)', path='$(PKG_DIR)', '$*.R')"
+
+missing_Rd:
+	$(R_SCRIPT) -e "x <- readLines('$(R_CHECK_OUTDIR)/00check.log'); from <- grep('Undocumented code objects:', x)+1; if (length(from) > 0L) { to <- grep('All user-level objects', x)-1; x <- x[from:to]; x <- gsub('^[ ]*', '', x); x <- gsub('[\']', '', x); cat(x, sep='\n', file='999.missingdocs.txt'); }"
+
+spell_Rd:
+	$(R_SCRIPT) -e "f <- list.files('man', pattern='[.]Rd$$', full.names=TRUE); utils::aspell(f, filter='Rd')"
+
+
+spell_NEWS:
+	$(R_SCRIPT) -e "utils::aspell('$(FILES_NEWS)')"
+
+spell:
+	$(R_SCRIPT) -e "utils::aspell('DESCRIPTION', filter='dcf')"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Build package vignettes
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/vigns: install
+	$(MKDIR) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS))
+	$(CP) DESCRIPTION $(R_OUTDIR)/vigns/
+	$(CP) -r $(DIR_VIGNS) $(R_OUTDIR)/vigns/$(shell dirname $(DIR_VIGNS))
+	$(CD) $(R_OUTDIR)/vigns;\
+	$(R_SCRIPT) -e "v <- tools::buildVignettes(dir='.'); file.path(getwd(), v[['outputs']])"
+
+vignettes: $(R_OUTDIR)/vigns
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Run package tests
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_OUTDIR)/tests/%.R: $(FILES_TESTS)
+	$(RMDIR) $(R_OUTDIR)/tests
+	$(MKDIR) $(R_OUTDIR)/tests
+	$(CP) $? $(R_OUTDIR)/tests
+
+test_files: $(R_OUTDIR)/tests/*.R
+
+test: $(R_OUTDIR)/tests/%.R
+	$(CD) $(R_OUTDIR)/tests;\
+	$(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }"
+
+test_full: $(R_OUTDIR)/tests/%.R
+	$(CD) $(R_OUTDIR)/tests;\
+	export _R_CHECK_FULL_=TRUE;\
+	$(R_SCRIPT) -e "for (f in list.files(pattern='[.]R$$')) { print(f); source(f, echo=TRUE) }"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Benchmarking
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+R_branch:
+	R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R)
+
+benchmark:
+	$(MKDIR) .benchmark/$(PKG_VERSION);\
+	$(CD) .benchmark/$(PKG_VERSION);\
+	$(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')"
+
+benchmark_branch:
+	$(MKDIR) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\
+	$(CD) .benchmark/$(PKG_VERSION)_$(GIT_BRANCH)_$(GIT_COMMIT);\
+	R_LIBS="$(R_LIBS_USER_X)$(FSEP)$(R_LIBS)" R_LIBS_USER="$(R_LIBS_BRANCH)" $(R_SCRIPT) -e "$(PKG_NAME):::benchmark('index')"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Miscellaneous development tools
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+## Fully expanded src/*.c files
+.devel/src/%: src/% $(FILES_SRC)
+	$(MKDIR) .devel/src/;\
+	gcc -I$(R_INCLUDE) -E $< | sed -e '/./b' -e :n -e 'N;s/\n$$//;tn' > .devel/$<
+
+.devel/src/all: $(FILES_SRC)
+	for f in $(FILES_SRC_C); do\
+	  echo $$f;\
+	  $(MAKE) .devel/$$f;\
+	done
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Run extensive CRAN submission checks
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+$(R_CRAN_OUTDIR)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) build_fix
+	$(MKDIR) $(R_CRAN_OUTDIR)
+	$(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(R_CRAN_OUTDIR)
+
+$(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt: $(R_CRAN_OUTDIR)/$(PKG_TARBALL)
+	$(CD) $(R_CRAN_OUTDIR);\
+	$(R_SCRIPT) -e "RCmdCheckTools::testPkgsToSubmit(delta=2/3)"
+
+cran_setup: $(R_CRAN_OUTDIR)/$(PKG_TARBALL)
+	$(R_SCRIPT) -e "if (!nzchar(system.file(package='RCmdCheckTools'))) { source('http://aroma-project.org/hbLite.R'); hbLite('RCmdCheckTools', devel=TRUE); }"
+
+cran: cran_setup $(R_CRAN_OUTDIR)/$(PKG_NAME),EmailToCRAN.txt
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Send to win-builder server
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+WIN_BUILDER = win-builder.r-project.org
+win-builder-devel: $(R_OUTDIR)/$(PKG_TARBALL)
+	curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-devel/
+
+win-builder-release: $(R_OUTDIR)/$(PKG_TARBALL)
+	curl -v -T $? ftp://anonymous@$(WIN_BUILDER)/R-release/
+
+win-builder: win-builder-devel win-builder-release
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Local repositories
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+ifeq ($(OS), Windows_NT)
+REPOS_PATH = T:/My\ Repositories/braju.com/R
+else
+REPOS_PATH = /tmp/hb/repositories/braju.com/R
+endif
+REPOS_SRC := $(REPOS_PATH)/src/contrib
+
+$(REPOS_SRC):
+	$(MKDIR) "$@"
+
+$(REPOS_SRC)/$(PKG_TARBALL): $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC)
+	$(CP) $(R_OUTDIR)/$(PKG_TARBALL) $(REPOS_SRC)
+
+repos: $(REPOS_SRC)/$(PKG_TARBALL)
+
+Makefile: $(FILES_MAKEFILE)
+	$(R_SCRIPT) -e "d <- 'Makefile'; s <- '../../Makefile'; if (file_test('-nt', s, d) && (regexpr('Makefile for R packages', readLines(s, n=1L)) != -1L)) file.copy(s, d, overwrite=TRUE)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Refresh
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+.make/Makefile:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/')"
+
+.make/.travis.yml.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/.travis.yml.rsp', path='.make/')"
+
+.make/appveyor.yml.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/appveyor.yml.rsp', path='.make/')"
+
+.make/README.md.rsp:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/README.md.rsp', path='.make/')"
+
+.covr.R:
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/.covr.R')"
+
+clean:
+	$(RM) .make/.travis.yml.rsp .make/appveyor.yml.rsp .make/README.md.rsp .covr.R
+	$(RM) covr-utils.R
+
+refresh: clean
+	$(MAKE) --silent .make/.travis.yml.rsp
+	$(MAKE) --silent .make/appveyor.yml.rsp
+	$(MAKE) --silent .make/README.md.rsp
+	$(MAKE) --silent .covr.R
+	$(R_SCRIPT) -e "R.utils::downloadFile('https://raw.githubusercontent.com/HenrikBengtsson/r-package-files/master/.make/Makefile', path='.make/', skip=FALSE)"
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# GitHub, Travis CI, ...
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+README.md: .make/README.md.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+.travis.yml: .make/.travis.yml.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+appveyor.yml: .make/appveyor.yml.rsp
+	$(R_SCRIPT) -e "R.rsp::rfile('$<', postprocess=FALSE)"
+
+config: .travis.yml appveyor.yml README.md
diff --git a/.travis.yml b/.travis.yml
new file mode 100644
index 0000000..1587355
--- /dev/null
+++ b/.travis.yml
@@ -0,0 +1,87 @@
+#----------------------------------------------------------------
+# Travis-CI configuration for R packages
+#
+# REFERENCES:
+# * Travis CI: https://travis-ci.org/
+# * r-builder: https://github.com/metacran/r-builder
+# * covr: https://github.com/jimhester/covr
+#
+# Validate your .travis.yml file at http://lint.travis-ci.org/
+#----------------------------------------------------------------
+language: c
+
+env:
+  global:
+    - RENV="./pkg-build.sh"    # r-builder
+    - R_BUILD_ARGS="--no-manual"
+    - R_CHECK_ARGS="--no-manual --as-cran"
+    - _R_CHECK_CRAN_INCOMING_=TRUE
+    - _R_CHECK_FORCE_SUGGESTS_=false
+    # Need LaTeX? (very time consuming!)
+    - BOOTSTRAP_LATEX=""
+    # Skip building vignettes, which iff LaTeX-based are very
+    # time consuming because LaTeX needs to be installed
+#    - R_BUILD_ARGS="--no-build-vignettes ${R_BUILD_ARGS}"
+#    - R_CHECK_ARGS="--no-build-vignettes ${R_CHECK_ARGS}"
+
+  # R versions r-builder should test on (ignored by r-travis)
+  matrix:
+    - RVERSION=3.1.3
+    - RVERSION=3.2.2
+    - RVERSION=devel _R_COVR_=TRUE _R_CHECK_FULL_=TRUE
+
+
+before_install:
+  - echo RENV=$RENV
+  - curl -OL https://raw.githubusercontent.com/HenrikBengtsson/r-builder/master/pkg-build.sh;
+  - chmod 755 $RENV
+  - $RENV bootstrap
+  - if [ "BOOTSTRAP_LATEX" == "true" ]; then
+      (cd /tmp && curl -OL http://mirrors.ctan.org/macros/latex/contrib/xcolor.zip && cd /usr/share/texmf/tex/latex && sudo unzip /tmp/xcolor.zip && cd xcolor && sudo latex xcolor.ins && sudo texhash);
+    else
+      export R_RSP_COMPILELATEX_FALLBACK="copy-force";
+    fi
+  - if [[ "$_R_CHECK_USE_VALGRIND_" == "TRUE" ]]; then
+      export R_BUILD_ARGS="--no-manual --no-build-vignettes";
+      export R_CHECK_ARGS="--no-manual --no-build-vignettes --no-codoc --no-examples --use-valgrind";
+      export _R_CHECK_TIMINGS_=10;
+      sudo apt-get install valgrind;
+      valgrind --version;
+    fi
+
+install:
+
+
+
+
+
+ - $RENV install_r digest R.methodsS3 R.oo R.utils
+
+
+
+script:
+  - $RENV run_build
+  - $RENV run_check
+
+after_success:
+  - $RENV dump_logs_by_extension out
+  - if [[ "$_R_COVR_" == "TRUE" && -f ".covr.R" ]]; then
+      $RENV install_devtools;
+      $RENV install_github jimhester/covr;
+      curl -OL https://raw.githubusercontent.com/HenrikBengtsson/covr-utils/master/covr-utils.R;
+    fi
+  - if [[ "$_R_COVR_" == "TRUE" && -f ".covr.R" ]]; then
+      $RENV run_script .covr.R;
+    fi
+
+after_failure:
+  - $RENV dump_logs
+
+notifications:
+  email:
+    on_success: change
+    on_failure: change
+
+branches:
+  except:
+   - /-expt$/
diff --git a/DESCRIPTION b/DESCRIPTION
new file mode 100755
index 0000000..3893b66
--- /dev/null
+++ b/DESCRIPTION
@@ -0,0 +1,21 @@
+Package: R.cache
+Version: 0.12.0
+Depends:
+  R (>= 2.5.0)
+Imports:
+  utils,
+  R.methodsS3 (>= 1.7.0),
+  R.oo (>= 1.19.0),
+  R.utils (>= 2.1.0),
+  digest (>= 0.6.8)
+Date: 2015-11-12
+Title: Fast and Light-Weight Caching (Memoization) of Objects and Results to Speed Up Computations
+Authors at R: c(person("Henrik", "Bengtsson", role=c("aut", "cre", "cph"),
+                                          email = "henrikb at braju.com"))
+Author: Henrik Bengtsson [aut, cre, cph]
+Maintainer: Henrik Bengtsson <henrikb at braju.com>
+Description: Memoization can be used to speed up repetitive and computational expensive function calls.  The first time a function that implements memoization is called the results are stored in a cache memory.  The next time the function is called with the same set of parameters, the results are momentarily retrieved from the cache avoiding repeating the calculations.  With this package, any R object can be cached in a key-value storage where the key can be an arbitrary set of R objects [...]
+License: LGPL (>= 2.1)
+LazyLoad: TRUE
+URL: https://github.com/HenrikBengtsson/R.cache
+BugReports: https://github.com/HenrikBengtsson/R.cache/issues
diff --git a/Makefile b/Makefile
new file mode 100644
index 0000000..c6e7a04
--- /dev/null
+++ b/Makefile
@@ -0,0 +1 @@
+include .make/Makefile
diff --git a/NAMESPACE b/NAMESPACE
new file mode 100644
index 0000000..37dd7ad
--- /dev/null
+++ b/NAMESPACE
@@ -0,0 +1,78 @@
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# IMPORTS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+importFrom("R.methodsS3", "setMethodS3")
+importFrom("R.methodsS3", "throw")
+
+## Importing Class:es
+importFrom("R.oo", "Package")
+
+## Importing generics
+importFrom("R.oo", "clearCache")
+
+## Importing functions
+importFrom("R.oo", "attachLocally")
+importFrom("R.oo", "startupMessage")
+importFrom("R.oo", "trim")
+importFrom("R.utils", "cat") ## Multi-sources: R.utils, base
+importFrom("R.utils", "isAbsolutePath")
+importFrom("R.utils", "isDirectory")
+importFrom("R.utils", "isFile")
+importFrom("R.utils", "listDirectory")
+importFrom("R.utils", "mkdirs")
+importFrom("R.utils", "removeDirectory")
+importFrom("R.utils", "touchFile")
+importFrom("utils", "compareVersion")
+importFrom("utils", "packageVersion")
+importFrom("digest", "digest")
+
+## Manually adjusted
+## Cannot import explicitly from 'base';
+## importFrom("base", "getOption") ## Multi-sources: R.utils, base
+
+## Manual imports
+importFrom("R.utils", "Arguments")
+
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# EXPORTS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Export all public methods, that is, those without a preceeding dot
+# in their names.
+export("R.cache")
+export("evalWithMemoization")
+export("addMemoization")
+export("memoizedCall")
+export("getCacheRootPath")
+export("setCacheRootPath")
+export("getCachePath")
+export("findCache")
+export("readCacheHeader")
+export("loadCache")
+export("saveCache")
+export("getChecksum")
+export("clearCache")  # Imported from R.oo
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# S3 METHOD DECLARATIONS
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# default
+S3method("addMemoization", "default")
+S3method("clearCache", "default")
+S3method("findCache", "default")
+S3method("generateCache", "default")
+S3method("getCachePath", "default")
+S3method("getCacheRootPath", "default")
+S3method("getChecksum", "default")
+S3method("loadCache", "default")
+S3method("memoizedCall", "default")
+S3method("readCacheHeader", "default")
+S3method("saveCache", "default")
+S3method("setCachePath", "default")
+S3method("setCacheRootPath", "default")
+S3method("setupCacheRootPath", "default")
+
+# Object
+S3method("getChecksum", "Object")
diff --git a/NEWS b/NEWS
new file mode 100755
index 0000000..d70642e
--- /dev/null
+++ b/NEWS
@@ -0,0 +1,311 @@
+
+Package: R.cache
+================
+
+Version: 0.12.0 [2015-11-12]
+o SPEEDUP: Now memoizedCall() generates cache pathname only once.
+o Now all prompt and verbose messages are send to the standard
+  error (instead of the standard output).
+o ROBUSTNESS: Increased test coverage from 64% to 86%.
+o CLEANUP: Dropped argument 'verbose' from memoizedCall().
+
+
+Version: 0.11.1 [2014-09-10]
+o ROBUSTNESS:  Added package system tests for memoizeCall()
+  and addMemoization().
+o DOCUMENTATION: Clarified in help that function calls that
+  returns ("has value") NULL will not be cached.
+o BUG FIX: addMemoization() will no longer memoize an already
+  memoized function.
+
+
+Version: 0.11.0 [2014-09-05]
+o Now package imports rather than suggests the 'digest' package.
+  This simplifies installation/usage of the package.
+o Bumped package dependencies.
+
+
+Version: 0.10.0 [2014-06-10]
+o Bumped package dependencies.
+
+
+Version: 0.9.5 [2014-05-01]
+o ROBUSTNESS: The textual prompt used to ask new R.cache users for
+  approval on creating a persistent cache directory is now using
+  the standard error (stderr) rather than the standard output
+  (stdout).  This lowers the risk for issues with report generators.
+
+
+Version: 0.9.4 [2014-04-26]
+o CLEANUP: Minimize use of '::'.
+
+
+Version: 0.9.3 [2014-01-30]
+o Bumped package dependencies.
+
+
+Version: 0.9.2 [2014-01-13]
+o All call to internal generateCache() with key=NULL would give a
+  hard-to-understand error message.  Now it's more informative.
+o Bumped package dependencies.
+
+
+Version: 0.9.1 [2013-12-21]
+o Added arguments 'path' and 'rootPath' to getCachePath().
+o Added argument 'pathname' to saveCache().
+
+
+Version: 0.9.0 [2013-10-17]
+o BUG FIX: If the package was only loaded but not attached, the cache
+  root path would default to ~/.Rcache/, which in turn could cause
+  that path to be create without asking the user.  For instance,
+  R.cache::loadCache(list()) would do.  Thanks to Kurt Hornik at
+  Vienna University of Economics and Business for reporting on this.
+
+
+Version: 0.8.4 [2013-10-14]
+o Adjusted package dependencies and NAMESPACE to work with the
+  package versions available on CRAN.
+o Now DESCRIPTION's 'Authors' field matches 'Authors at R'.
+
+
+Version: 0.8.3 [2013-10-03]
+o Bumped package dependencies.
+
+
+Version: 0.8.2 [2013-09-28]
+o Now the 'R.cache' Package object is also available when the
+  package is only loaded (but not attached).
+
+
+Version: 0.8.1 [2013-09-15]
+o CLEANUP: Now only importing a minimal set of functions needed
+  from the 'R.oo' and the 'R.utils' packages.
+o Bumped package dependencies.
+
+
+Version: 0.8.0 [2013-08-21]
+o Now R.utils is no longer attached ("loaded") - only imported.
+o Added system tests.
+
+
+Version: 0.7.4 [2013-08-20]
+o Now explicitly importing one function from 'utils' in NAMESPACE.
+
+
+Version: 0.7.3 [2013-08-18]
+o Now clearCache() is exported (re-exported from R.oo).
+
+
+Version: 0.7.2 [2013-08-03]
+o Bumped package dependencies.
+o BUG FIX: R.cache:::.assertDigest() called from within another package
+  would give an error that packageVersion() of 'utils' was not found.
+
+
+Version: 0.7.1 [2013-07-11]
+o Updated the title and the description of the package.
+
+
+Version: 0.7.0 [2013-07-03]
+o Now getChecksum() passes '...' to digest(), e.g. argument 'algo'.
+o Bumped package dependencies.
+
+
+Version: 0.6.10 [2013-05-25]
+o Minor speedup of loadCache() - replaced an rm() call with NULL assignment.
+
+
+Version: 0.6.9 [2013-05-20]
+o CRAN POLICY: Now all Rd \usage{} lines are at most 90 characters long.
+o Bumped package dependencies.
+
+
+Version: 0.6.8 [2012-12-19]
+o Utilizing new startupMessage() of R.oo.
+
+
+Version: 0.6.7 [2012-11-28]
+o Added support for clearCache(..., recursive=TRUE).
+
+
+Version: 0.6.6 [2012-11-27]
+o BUG FIX: clearCache() would give error "object 'dirs' not found".
+
+
+Version: 0.6.5 [2012-11-18]
+o ROBUSTNESS: Now package declares S3 methods in the namespace.
+o CLEANUP: Now package exports a smaller set of the methods.
+o CLEANUP: Package now only imports R.methodsS3 and R.oo, no long
+  depends (loads) them.  It still needs to load R.utils.
+o Added internal .assertDigest(), which originates from aroma.core.
+
+
+Version: 0.6.4 [2012-10-16]
+o ROBUSTNESS/BUG FIX: No longer passing '...' to NextMethod(), cf.
+  R-devel thread 'Do *not* pass '...' to NextMethod() - it'll do it
+  for you; missing documentation, a bug or just me?' on Oct 16, 2012.
+o Package now imports R.methodsS3 and R.oo.
+
+
+Version: 0.6.3 [2012-09-12]
+o Renamed the installed .Rcache/ directory to _Rcache/ to avoid
+  R CMD check NOTEs.
+o CRAN POLICY: Removed one last call to .Internal() for loading
+  saved data.  This could be done in a backward-compatible way
+  using readRDS().
+
+
+Version: 0.6.2 [2012-03-20]
+o CRAN POLICY: Dropped an explicit call to an .Internal() function.
+
+
+Version: 0.6.1 [2012-01-22]
+o Updated the README that is copied to the .Rcache directory.
+o Updated package dependencies.
+
+
+Version: 0.6.0 [2011-12-30]
+o As before, the cache root path defaults to ~/.Rcache/. However,
+  if it does not exists, then it is created when the package is loaded,
+  but only after approval by the user (via a textual prompt). If not
+  approved, or it is not possible to prompt the user (e.g. in a
+  non-interactive session), then a session-specific temporary directory
+  is used.
+
+
+Version: 0.5.3 [2011-12-29]
+o Now getCachePath() and setCacheRootPath() add a README.txt file to
+  the root path, iff missing. It explains why the directory structure
+  exists, what created it, and that it is safe to delete.
+
+
+Version: 0.5.2 [2011-10-05]
+o BUG FIX (for R v2.13.0 only): Applying the same fix that was done
+  for R v2.12.2 and before in R.cache v0.5.1.
+
+
+Version: 0.5.1 [2011-08-31]
+o BUG FIX (for R v2.12.2 and before): After adding support for
+  compressed files in R.cache v0.5.0, we would get the 'Error in
+  seek.connection(con, origin = "current", where = -5) : whence = "end"
+  is not implemented for gzfile connections' in readCacheHeader()
+  iff running R v2.12.2 or before.  Thanks to Uwe Ligges (R core)
+  for reporting on this.
+
+
+Version: 0.5.0 [2011-08-16]
+o Added support for saving and loading compressed cache files.
+o ROBUSTNESS: Now findCache() asserts that any identified cache
+  file is really a file.
+o CLEANUP: Now package uses packageStartupMessage() instead of cat().
+
+
+Version: 0.4.3 [2011-07-21]
+o DOCUMENTATION: Clarified how argument 'dirs' (in methods using it)
+  specifies the subdirectory of the cache root directory.
+
+
+Version: 0.4.2 [2011-05-19]
+o Added a help page to clearCache().
+o Now argument 'prompt' for clearCache() defaults to TRUE
+  iff interactive() is TRUE, otherwise FALSE.
+
+
+Version: 0.4.1 [2011-04-02]
+o Now generateCache() utilizes a generic function getChecksum()
+  to obtain the checksum.  This makes it possible to customize
+  how checksums are calculated for different classes of objects.
+o Added a default getChecksum() which utilizes digest::digest().
+o Added getChecksum() for the Object, which first clears the
+  cache of the object and the calls the default ditto.
+o Added trial version of evalWithMemoization().
+o BUG FIX: clearCache() would also report on subdirectories.
+
+
+Version: 0.4.0 [2011-02-14]
+o Added trial versions of memoizedCall() and addMemoization().
+
+
+Version: 0.3.0 [2010-03-13]
+o Added a NAMESPACE.
+
+
+Version: 0.2.0 [2009-10-16]
+o BUG FIX: In R v2.10.0 and newer, we would get an error reporting that
+  internal function loadFromConn() does not exists.
+
+
+Version: 0.1.9 [2009-09-11]
+o Added argument 'onError' to loadCache(), to specify the action when
+  an error occurs.  The default used to be to print the error message
+  (onError="print"), but now the default is to generate a warning
+  ("warning").  The other alternatives are do silently ignore it, or
+  to throw the error ("error").  Except for onError="error", loadCache()
+  always returns NULL if an error occurs.
+
+
+Version: 0.1.8 [2009-08-11]
+o ROBUSTNESS: Added sanity check to readCacheHeader() testing
+  that the read header identifier is non-empty.  This results
+  in a clearer error message that before.
+o Now readCacheHeader() reports the "pathname" in error/warnings
+  messages, if argument 'file' refers to a file and the
+  "description" if it refers to a connection.
+o CLEAN UP: Renamed the HISTORY file to NEWS.
+
+
+Version: 0.1.7 [2008-02-27]
+o Added option to updated the "last-modified" timestamp of cache
+  files whenever they are loaded via loadCache(). This will help
+  identified what cache files have not been used for a long time.
+  To turn this on, use options("R.cache::touchOnLoad"=TRUE).
+o Now error messages specifies the pathname, if available.
+o BUG FIX: The throw() for invalid identifiers was trying to put
+  the connection object in the output and not the identifier.
+
+
+Version: 0.1.6 [2007-07-02]
+o Now environments, in addition to lists, may be used as keys
+  for generating cache names.
+o Package passes R CMD check on R v2.6.0 devel.  Minor mods.
+
+
+Version: 0.1.5 [2007-03-11]
+o Added getCacheRootPath() to the help index page.
+o Package passes R CMD check on R v2.5.0.
+
+
+Version: 0.1.4 [2007-03-07]
+o Added getCacheRootPath() and setCacheRootPath() to specify
+  where the root of the file path is located.
+
+
+Version: 0.1.3 [2007-01-24]
+o Now saveCache() and loadCache() takes optional argument 'dirs' for
+  caching data to subdirectories of the root cache directory.
+o Added setCacheRootPath() to set the root cache directory.
+
+
+Version: 0.1.2 [2006-05-25]
+o Added argument 'pathname' to loadCache() in order to load
+  "unknown" cache files for which the key is unknown.
+o BUG FIX: Work around for not saving "promises" (non-evaluated arguments)
+  in base::save(), which otherwise includes all of the surrounding
+  environment if 'sources' is not evaluated/missing.  For more details
+  see code and my email to r-devel on 2006-05-25.  Thanks to Brian Ripley
+  for explaining what was going on.
+
+
+Version: 0.1.1 [2006-05-22]
+o Added header comment for file format > v0.1.
+o Added detection of file format version.
+o Added readCacheHeader().
+
+
+Version: 0.1.0 [2005-12-16]
+o Using a special binary file format now.  It allows you to
+  check if cache is up-to-date to a source file.  If not,
+  the rest of the cache binary file is not loaded.
+o Added loadCache() and saveCache() methods.
+o Created.
diff --git a/R/000.R b/R/000.R
new file mode 100755
index 0000000..3e773a2
--- /dev/null
+++ b/R/000.R
@@ -0,0 +1,4 @@
+## Look for existing generic functions also in imported namespaces.
+## This will affect whether setGenericS3() creates a generic function
+## or not.
+options("R.methodsS3:checkImports:setGenericS3"=TRUE)
diff --git a/R/006.fixVarArgs.R b/R/006.fixVarArgs.R
new file mode 100755
index 0000000..3b60d3a
--- /dev/null
+++ b/R/006.fixVarArgs.R
@@ -0,0 +1,10 @@
+# Added '...' to some base functions. These will later be
+# turned into default functions by setMethodS3().
+
+
+
+############################################################################
+# HISTORY:
+# 2005-12-06
+# o Created to please R CMD check.
+############################################################################
diff --git a/R/999.NonDocumentedObjects.R b/R/999.NonDocumentedObjects.R
new file mode 100755
index 0000000..0583736
--- /dev/null
+++ b/R/999.NonDocumentedObjects.R
@@ -0,0 +1,34 @@
+###########################################################################/**
+# @RdocDocumentation "Non-documented objects"
+#
+# % File cache
+#
+# % Class Object
+# @alias getChecksum.Object
+#
+# % Misc.
+# @alias .textPrompt
+#
+# \description{
+#   This page contains aliases for all "non-documented" objects that 
+#   \code{R CMD check} detects in this package. 
+#
+#   Almost all of them are \emph{generic} functions that have specific 
+#   document for the corresponding method coupled to a specific class. 
+#   Other functions are re-defined by \code{setMethodS3()} to 
+#   \emph{default} methods. Neither of these two classes are non-documented
+#   in reality.
+#   The rest are deprecated methods.
+# }
+#
+# @author
+#
+# @keyword internal
+#*/###########################################################################
+
+############################################################################
+# HISTORY:
+# 2005-05-26
+# o Created to please R CMD check.
+############################################################################
+
diff --git a/R/999.package.R b/R/999.package.R
new file mode 100755
index 0000000..70bab06
--- /dev/null
+++ b/R/999.package.R
@@ -0,0 +1,65 @@
+#########################################################################/**
+# @RdocPackage R.cache
+#
+# \description{
+#   @eval "getDescription(R.cache)"
+# }
+#
+# \section{Installation and updates}{
+#   To install this package and all of its dependent packages, do:
+#   \code{install.packages("R.cache")}
+# }
+#
+# \section{To get started}{
+#   \itemize{
+#    \item{\link{loadCache}, \link{saveCache}}{
+#      Methods for loading and saving objects from and to the cache.
+#    }
+#    \item{\link{getCacheRootPath}, \link{setCacheRootPath}}{
+#      Methods for getting and setting the directory where cache
+#      files are stored.
+#    }
+#   }
+# }
+#
+# \section{How to cite this package}{
+#   Whenever using this package, please cite [1] as
+#
+#   @howtocite "R.oo"
+# }
+#
+# \section{Wishlist}{
+#  Here is a list of features that would be useful, but which I have
+#  too little time to add myself. Contributions are appreciated.
+#  \itemize{
+#    \item Add a functionality to identify cache files that are
+#       no longer of use.  For now, there is an extra header field
+#       for arbitrary comments which can be used, but maybe more
+#       formal fields are useful, e.g. keywords, user, etc?
+#  }
+#
+#  If you consider implement some of the above, make sure it is not
+#  already implemented by downloading the latest "devel" version!
+# }
+#
+# \section{Related work}{
+#  See also the \pkg{filehash} package, and the \code{cache()} function
+#  in the \pkg{Biobase} package of Bioconductor.
+# }
+#
+# @author
+#
+# \section{License}{
+#   The releases of this package is licensed under
+#   LGPL version 2.1 or newer.
+#
+#   The development code of the packages is under a private licence
+#   (where applicable) and patches sent to the author fall under the
+#   latter license, but will be, if incorporated, released under the
+#   "release" license above.
+# }
+#
+# \section{References}{
+# [1] @include "../incl/BengtssonH_2003.bib.Rdoc" \cr
+# }
+#*/#########################################################################
diff --git a/R/Object.getChecksum.R b/R/Object.getChecksum.R
new file mode 100644
index 0000000..7e91eed
--- /dev/null
+++ b/R/Object.getChecksum.R
@@ -0,0 +1,16 @@
+setMethodS3("getChecksum", "Object", function(object, ...) {
+  object <- clearCache(object);
+  NextMethod("getChecksum", object=object);
+}, export=FALSE)
+
+
+############################################################################
+# HISTORY:
+# 2014-02-03
+# o ROBUSTNESS, now passing the first/dispatch argument (named 'object')
+#   to argument 'object' of NextMethod() as a named argument, which just
+#   happens to be of the same names.
+# 2011-04-02
+# o Added getChecksum() for the Object class.
+# o Created.
+############################################################################
diff --git a/R/addMemoization.R b/R/addMemoization.R
new file mode 100644
index 0000000..4b9397d
--- /dev/null
+++ b/R/addMemoization.R
@@ -0,0 +1,81 @@
+#########################################################################/**
+# @RdocDefault addMemoization
+#
+# @title "Creates a copy of an existing function such that its results are memoized"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{fcn}{A @function (or the name of a function) that should be
+#     copied and have memoization added.}
+#   \item{envir}{The @environment from where to look for the function.}
+#   \item{...}{Additional arguments for controlling the memoization,
+#     i.e. all arguments of @see "memoizedCall" that are not passed
+#     to @see "base::do.call".}
+# }
+#
+# \value{
+#   Returns a @function.
+# }
+#
+# \details{
+#  The new function is setup such that the the memoized call is done
+#  in the environment of the caller (the parent frame of the function).
+#
+#   If the @function returns @NULL, that particular function call is
+#   \emph{not} memoized.
+# }
+#
+# @author
+#
+# \seealso{
+#  The returned function utilized @see "memoizedCall" internally.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################
+setMethodS3("addMemoization", "default", function(fcn, envir=parent.frame(), ...) {
+  # Argument 'fcn':
+  if (is.character(fcn)) {
+    if (!exists(fcn, mode="function", envir=envir, inherits=TRUE)) {
+      throw("Argument 'fcn' is not an existing function: ", fcn);
+    }
+    fcn <- get(fcn, mode="function", envir=envir, inherits=TRUE);
+  }
+
+  if (!is.function(fcn)) {
+    throw("Argument 'fcn' is not a function: ", mode(fcn));
+  }
+
+  # Already memoized?
+  if (inherits(fcn, "MemoizedFunction")) {
+    return(fcn)
+  }
+
+  # Record the argument specific to memoizedCall().
+  memArgs <- list(...);
+
+  res <- function(..., envir=parent.frame()) {
+    args <- list(fcn, ..., envir=envir);
+    args <- c(args, memArgs);
+    do.call("memoizedCall", args=args);
+  }
+  class(res) <- c("MemoizedFunction", class(res))
+
+  res
+}) # addMemoization()
+
+
+#######################################################################
+# HISTORY:
+# 2014-09-10
+# o ROBUSTNESS: addMemoization() will no longer memoize an already
+#   memoized function.
+# 2011-02-14
+# o Added addMemoization().
+#######################################################################
diff --git a/R/addREADME.R b/R/addREADME.R
new file mode 100644
index 0000000..382ea5c
--- /dev/null
+++ b/R/addREADME.R
@@ -0,0 +1,17 @@
+.addREADME <- function(to=getCacheRootPath(), ...) {
+  # Add a README.txt to cache root (expaining what the directory is)
+  filename <- "README.txt";
+  pathnameD <- file.path(to, filename);
+  if (!isFile(pathnameD)) {
+    pathnameS <- system.file("_Rcache", filename, package="R.cache");
+    file.copy(pathnameS, pathnameD);
+  }
+} # .addREADME()
+ 
+
+############################################################################
+# HISTORY:
+# 2012-11-28
+# o Added internal .addREADME().
+# o Created.
+############################################################################
diff --git a/R/clearCache.R b/R/clearCache.R
new file mode 100755
index 0000000..09b579b
--- /dev/null
+++ b/R/clearCache.R
@@ -0,0 +1,160 @@
+#########################################################################/**
+# @RdocDefault clearCache
+#
+# @title "Removes all files in a cache file directory"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{path}{A @character string specifying the directory to be cleared.
+#     By default, the path is what is returned by @see "getCachePath"
+#     which arguments \code{...} are also passed.}
+#   \item{...}{Arguments passed to @see "getCachePath", especially
+#     argument \code{dirs} to specify subdirectories.}
+#   \item{recursive}{If @TRUE, subdirectories are also removed, otherwise
+#     just the files in the specified directory.}
+#   \item{prompt}{If @TRUE, the user will be prompted to confirm that
+#     the directory will cleared before files are removed.}
+# }
+#
+# \value{
+#   Returns (invisibly) a @character @vector of pathnames of the
+#   files removed.  If no files were removed, @NULL is returned.
+# }
+#
+# @author
+#
+# \details{
+#   If the specified directory does not exists, an exception is thrown.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("clearCache", "default", function(path=getCachePath(...), ..., recursive=FALSE, prompt=TRUE && interactive()) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Validate arguments
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Argument 'recursive':
+  recursive <- Arguments$getLogical(recursive);
+
+  # Argument 'path':
+  path <- Arguments$getReadablePath(path, mustExist=TRUE);
+
+  # Argument 'prompt':
+  prompt <- Arguments$getLogical(prompt);
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Find files to be removed
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  allFiles <- listDirectory(path, allNames=TRUE, fullNames=TRUE, recursive=recursive);
+
+  # Exclude '.' and '..' (just in case; listDirectory() shouldn't return them)
+  excl <- grep("[.][.]*$", allFiles);
+  if (length(excl) > 0L) allFiles <- allFiles[-excl];
+
+  # Exclude 'README.txt'
+  excl <- grep("README.txt$", allFiles);
+  if (length(excl) > 0L) allFiles <- allFiles[-excl];
+
+  nbrOfFiles <- length(allFiles);
+  if (nbrOfFiles == 0L) {
+    if (prompt) {
+      message("Nothing to clear. Cache directory is empty: ", path, "\n", sep="");
+    }
+    return(invisible(NULL));
+  }
+
+  # Identify files and directories
+  isdir <- file.info(allFiles)$isdir;
+  dirs <- allFiles[isdir];
+  files <- allFiles[!isdir];
+
+  # Remove subdirectories before parent ones.
+  o <- order(nchar(dirs), decreasing=TRUE);
+  dirs <- dirs[o];
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Prompt user?
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (prompt) {
+    answer <- ".";
+    while (!(answer %in% c("y", "n", ""))) {
+      message(sprintf("Are you really sure you want to delete the %d files and %d directories in '%s'? [y/N]: ", length(files), length(dirs), path));
+      answer <- tolower(readline());
+    }
+    if (answer != "y") {
+      return(invisible(NULL));
+    }
+  }
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Remove files and directories
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # (a) Remove files
+  removed <- file.remove(files);
+  filesR <- files[!removed];
+
+  # (b) Remove subdirectories
+  # Here we could use unlink(..., recursive=TRUE), but it is
+  # SUPER-DUPER DANGEROUS to do that, because it may spawn off a
+  # recursive deletion in a different place (in case there is a
+  # bug or an inconsistency in list.files() etc), but also if we
+  # forget to drop '.' and '..' from list.files(). /HB 2012-11-28
+  removed <- sapply(dirs, FUN=function(dir) {
+    filesT <- list.files(path=dir, all.files=TRUE);
+    filesT <- setdiff(filesT, c(".", ".."));
+    # Remove only empty directories
+    if (length(filesT) > 0L) return(FALSE);
+    removeDirectory(dir);
+  });
+  dirsR <- dirs[!removed];
+
+
+  # Files and directories removed
+  files <- sort(setdiff(files, filesR));
+  dirs <- sort(setdiff(dirs, dirsR));
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Report results?
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (prompt) {
+    msg <- sprintf("Cache cleared. Removed %d files and %d directories", length(files), length(dirs));
+    if (length(filesR) + length(dirsR) > 0L) {
+      msg <- sprintf("%s, but failed to remove another %d files and another %d directories", msg, length(filesR), length(dirsR));
+    }
+    message(sprintf("%s.\n", msg));
+  }
+
+  # Add a README.txt file, if missing.
+  .addREADME();
+
+  invisible(c(dirs, files));
+})
+
+
+############################################################################
+# HISTORY:
+# 2012-11-28
+# o GENERALIZATION: Now clearCache(..., recursive=TRUE) removes all
+#   cache files in subdirectories too.  The actual subdirectories are
+#   not removed.
+# 2012-11-27
+# o BUG FIX: clearCache() would give error "object 'dirs' not found".
+# 2011-05-19
+# o Added Rdoc comments.
+# 2011-04-02
+# o BUG FIX: clearCache() would also report on subdirectories.
+# 2005-12-09
+# o BUG FIX: 'prompt=FALSE' would not clear cache.
+# 2005-12-07
+# o Created.
+############################################################################
diff --git a/R/evalWithMemoization.R b/R/evalWithMemoization.R
new file mode 100644
index 0000000..d0a5fa1
--- /dev/null
+++ b/R/evalWithMemoization.R
@@ -0,0 +1,80 @@
+#########################################################################/**
+# @RdocFunction evalWithMemoization
+#
+# @title "Evaluates an R expression with memoization"
+#
+# \description{
+#  @get "title" such that the same objects are assigned to the
+#  current environment and the same result is returned, if any.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{expr}{The @expression to be evaluated.}
+#   \item{key}{Additional objects to uniquely identify the evaluation.}
+#   \item{...}{Additional arguments passed to @see "loadCache" 
+#     and @see "saveCache".}
+#   \item{envir}{The @environment in which the expression should
+#     be evaluated.}
+#   \item{force}{If @TRUE, existing cached results are ignored.}
+# }
+#
+# \value{
+#   Returns the value of the evaluated \code{expr} @expression, if any.
+# }
+#
+# @examples "../incl/evalWithMemoization.Rex"
+#
+# @author
+#
+# \seealso{
+#  Internally, @see "base::eval" is used to evaluate the expression.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################  
+evalWithMemoization <- function(expr, key=NULL, ..., envir=parent.frame(), force=FALSE) {
+  expr <- substitute(expr);
+
+  # Setup a unique list of keys
+  key <- c(list(expr=expr), key);
+
+  # Look for cached results
+  resList <- loadCache(key=key, ...);
+  if (!force && !is.null(resList)) {
+    # Attach all objects memoized during the evaluation
+    attachLocally(resList$envir, envir=envir);
+    # Return the results of the memoized evaluation
+    return(resList$result);
+  }
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Evaluate expression
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Evaluate the expression in a temporary environment, so that
+  # we memoize all objects created along with the results.
+  env <- new.env(parent=envir);
+  res <- eval(expr, envir=env);
+
+  # NOTE: For some unknown reason does attachLocally() set 
+  # the fields inside 'env' to NULL.  /HB 2011-04-02
+  fields <- ls(envir=env, all.names=TRUE);
+  for (field in fields) {
+    assign(field, get(field, envir=env), envir=envir);
+  }
+
+  # Cache results
+  resList <- list(envir=env, results=res);
+  saveCache(resList, key=key, ...);
+
+  res;
+} # evalWithMemoization()
+
+
+#######################################################################
+# HISTORY:
+# 2011-04-01
+# o Added evalWithMemoization().
+#######################################################################
diff --git a/R/findCache.R b/R/findCache.R
new file mode 100755
index 0000000..c50edca
--- /dev/null
+++ b/R/findCache.R
@@ -0,0 +1,66 @@
+#########################################################################/**
+# @RdocDefault findCache
+#
+# @title "Locates a cache file"
+#
+# \description{
+#  @get "title" from a key object.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{key}{An optional object from which a hexadecimal hash
+#     code will be generated and appended to the filename.}
+#   \item{...}{Additional argument passed to @see "generateCache".}
+# }
+#
+# \value{
+#   Returns the pathname as a @character, or @NULL if the no cached
+#   data exists.
+# }
+#
+# @author
+#
+# \seealso{
+#  @see "generateCache".
+#  @see "loadCache".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("findCache", "default", function(key=NULL, ...) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Generate cache name from basename and hash object.
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  pathname <- generateCache(key=key, ...);
+
+  if (file.exists(pathname) && !file.info(pathname)$isdir) {
+    return(pathname);
+  }
+
+  pathnameT <- sprintf("%s.gz", pathname);
+  if (file.exists(pathnameT) && !file.info(pathnameT)$isdir) {
+    return(pathnameT);
+  }
+
+  return(NULL);
+})
+
+
+############################################################################
+# HISTORY:
+# 2011-08-16
+# o ROBUSTNESS: Now findCache() asserts that any identified cache 
+#   file is really a file.
+# o Now findCache() detects also *.gz files.
+# 2007-01-24
+# o Added Rdoc comments.
+# o Removed non-used argument 'commentPattern'.
+# 2005-12-09
+# o Removed 'file' argument.
+# 2005-12-06
+# o Created.
+############################################################################
diff --git a/R/generateCache.R b/R/generateCache.R
new file mode 100755
index 0000000..2ea622f
--- /dev/null
+++ b/R/generateCache.R
@@ -0,0 +1,73 @@
+#########################################################################/**
+# @RdocDefault generateCache
+#
+# @title "Generates a cache pathname from a key object"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{key}{A @list or an @environment from which a @character string
+#     checksum will be calculated and that will constitute the name part
+#     of the cache filename.}
+#   \item{suffix}{A @character string to be appended to the end of the
+#     filename.}
+#   \item{...}{Arguments passed to @see "getCachePath".}
+# }
+#
+# \value{
+#   Returns the pathname as a @character string.
+# }
+#
+# @author
+#
+# \seealso{
+#   Internally, the generic function @see "getChecksum" is used to
+#   calculate the checksum of argument \code{key}.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("generateCache", "default", function(key, suffix=".Rcache", ...) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Validate arguments
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Argument 'key':
+  if (!is.list(key) && !is.environment(key)) {
+    throw("Argument 'key' must be a list, an environment: ", class(key)[1L]);
+  }
+
+  # Generate cache name from hash code of key object
+  cacheName <- getChecksum(key);
+
+  # Add cache directory or pathname
+  path <- getCachePath(...);
+  cacheName <- file.path(path, cacheName);
+
+  # Add suffix
+  cacheName <- paste(cacheName, suffix, sep="");
+
+  cacheName;
+}, export=FALSE)
+
+
+############################################################################
+# HISTORY:
+# 2014-01-13
+# o BUG FIX: generateCache(key=NULL) would generate "Error in
+#   file.path(path, cacheName) : object 'cacheName' not found".
+# 2011-04-01
+# o Now generateCache() utilizes a generic function getChecksum()
+#   to obtain the checksum.
+# 2007-07-02
+# o Added support for argument 'key' is an environment.
+# 2005-12-09
+# o Removed 'file' argument.
+# 2005-12-06
+# o Created.
+############################################################################
diff --git a/R/getCachePath.R b/R/getCachePath.R
new file mode 100755
index 0000000..eb9ca06
--- /dev/null
+++ b/R/getCachePath.R
@@ -0,0 +1,83 @@
+#########################################################################/**
+# @RdocDefault getCachePath
+#
+# @title "Gets the path to the file cache directory"
+#
+# \description{
+#  @get "title".
+#  If missing, the directory is created.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{dirs}{A @character @vector constituting the path to the
+#      cache subdirectory (of the \emph{cache root directory}
+#      as returned by @see "getCacheRootPath") to be used.
+#      If @NULL, the path will be the cache root path.}
+#   \item{path, rootPath}{(Advanced) @character strings specifying the
+#      explicit/default cache path and root cache path.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns the path as a @character string.
+# }
+#
+# @author
+#
+# \seealso{
+#   @see "setCachePath".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("getCachePath", "default", function(dirs=NULL, path=NULL, rootPath=getCacheRootPath(), ...) {
+  # Get path where to store cache file
+  if (is.null(path)) {
+    # (1) Get/make default path
+    # (a) Get path from options
+    subname <- paste(dirs, collapse="/");
+    name <- paste("R.cache:cachePath", subname, sep=":");
+    path <- getOption(name);
+
+    # (b) If not availble, make on
+    path <- paste(c(rootPath, dirs), collapse=.Platform$file.sep);
+  } else if (!isAbsolutePath(path)) {
+    # (2) Get/make default path
+    path <- file.path(rootPath, path);
+  }
+
+  # Create missing directory?
+  if (!isDirectory(path)) {
+    mkdirs(path);
+    if (!isDirectory(path)) {
+      throw("Could not create cache directory: ", path);
+    }
+
+    # Add a README.txt file, if missing.
+    .addREADME(to=rootPath);
+  }
+
+  path;
+}) # getCachePath()
+
+
+
+
+############################################################################
+# HISTORY:
+# 2013-12-21
+# o Added argument 'path' and 'rootPath' to getCachePath().
+# 2012-09-10
+# o Renamed the installed .Rcache/ directory to _Rcache/ to avoid
+#   R CMD check NOTEs.
+# 2011-12-29
+# o Now getCachePath() adds a README.txt file to the root path, iff
+#   missing. It explains why the directory structure exists and what
+#   created it.
+# 2007-01-24
+# o Created.
+############################################################################
diff --git a/R/getCacheRootPath.R b/R/getCacheRootPath.R
new file mode 100644
index 0000000..6828ff7
--- /dev/null
+++ b/R/getCacheRootPath.R
@@ -0,0 +1,79 @@
+#########################################################################/**
+# @RdocDefault getCacheRootPath
+#
+# @title "Gets the root path to the file cache directory"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{defaultPath}{The default path, if no user-specified directory
+#     has been given.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns the path as a @character string.
+# }
+#
+# \examples{
+#   print(getCacheRootPath())
+# }
+#
+# @author
+#
+# \seealso{
+#  Too set the directory where cache files are stored,
+#  see @see "setCacheRootPath".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################
+setMethodS3("getCacheRootPath", "default", function(defaultPath="~/.Rcache", ...) {
+  # Check for option settings
+  path <- getOption("R.cache::rootPath");
+
+  # Backward compatibility
+  if (is.null(path)) {
+    if (is.null(path))
+      path <- getOption("R.cache.path");
+
+    # Check for system environment settings
+    if (is.null(path)) {
+      path <- Sys.getenv("R_CACHE_PATH");
+    }
+
+    if (nchar(path) == 0L) {
+      path <- NULL;
+    }
+
+    if (!is.null(path)) {
+      warning("Use setCacheRootPath() to set the cache path in R.cache.");
+    }
+  }
+
+  # Otherwise, use argument 'path'.
+  if (is.null(path)) {
+    path <- defaultPath;
+  }
+
+  path;
+})
+
+
+############################################################################
+# HISTORY:
+# 2011-12-30
+# o Add example(getCacheRootPath).
+# 2007-03-07
+# o Made the root path settings internal.  Use setCacheRootPath() instead.
+# 2007-01-24
+# o Renamed argument 'create' to 'mkdirs'.
+# o Added Rdoc comments.
+# 2005-12-06
+# o Created.
+############################################################################
diff --git a/R/getChecksum.R b/R/getChecksum.R
new file mode 100644
index 0000000..70cfa15
--- /dev/null
+++ b/R/getChecksum.R
@@ -0,0 +1,63 @@
+#########################################################################/**
+# @RdocDefault getChecksum
+#
+# @title "Generates a deterministic checksum for an R object"
+#
+# \description{
+#  @get "title" such that (i) if the same object is used again, then
+#  the same checksum is obtained, and (ii) if another object is used,
+#  then a different checksum is obtained with extremely high probability.
+#  In other words, it is highly unlikely that two different objects
+#  have the same checksum.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{object}{The object for which a checksum should be calculated.}
+#   \item{...}{Additional arguments passed to @see "digest::digest".}
+# }
+#
+# \value{
+#   Returns checksum represented as a @character string.
+# }
+#
+# \details{
+#   Because \code{getChecksum()} is a generic function,
+#   it is possible to provide custom methods for specific
+#   classes of objects.  This means that, if a certain class
+#   specifies fields that carry auxillary data, then these
+#   can be excluded from the checksum calculation.
+#   For instance, assume that all objects of class 'TimestampedObject'
+#   contain timestamps specifying when each object was created.
+#   Then a custom \code{getChecksum()} method for this class can
+#   first drop the timestamp and then call the default
+#   \code{getChecksum()} function.
+# }
+#
+# @author
+#
+# \seealso{
+#   Internally, the @see "digest::digest" method is used to calculate
+#   the checksum.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("getChecksum", "default", function(object, ...) {
+  digest(object, ...);
+})
+
+
+############################################################################
+# HISTORY:
+# 2013-07-03
+# o Now getChecksum() passes '...' to digest(), e.g. argument 'algo'.
+# 2012-11-17
+# o CLEANUP: Removed a require("digest") to avoid loaded the package,
+#   and instead call digest::digest().
+# 2011-04-01
+# o Created.
+############################################################################
diff --git a/R/loadCache.R b/R/loadCache.R
new file mode 100755
index 0000000..585f3d8
--- /dev/null
+++ b/R/loadCache.R
@@ -0,0 +1,178 @@
+#########################################################################/**
+# @RdocDefault loadCache
+#
+# @title "Loads data from file cache"
+#
+# \description{
+#  @get "title", which is unique for an optional key object.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{key}{An optional object from which a hexadecimal hash
+#     code will be generated and appended to the filename.}
+#   \item{sources}{Optional source objects.  If the cache object has a
+#     timestamp older than one of the source objects, it will be ignored
+#     and removed.}
+#   \item{suffix}{A @character string to be appended to the end of the
+#     filename.}
+#   \item{removeOldCache}{If @TRUE and the cache is older than the
+#     \code{sources}, the cache file is removed, otherwise not.}
+#   \item{pathname}{The pathname to the cache file.  If specified,
+#     arguments \code{key} and \code{suffix} are ignored.  Note that
+#     this is only needed in order to read a cache file for which
+#     the key is unknown, for instance, in order to investigate
+#     an unknown cache file.}
+#   \item{dirs}{A @character @vector constituting the path to the
+#      cache subdirectory (of the \emph{cache root directory}
+#      as returned by @see "getCacheRootPath") to be used.
+#      If @NULL, the path will be the cache root path.}
+#   \item{...}{Not used.}
+#   \item{onError}{A @character string specifying what the action is
+#      if an exception is thrown.}
+# }
+#
+# \value{
+#   Returns an \R object or @NULL, if cache does not exist.
+# }
+#
+# \details{
+#   The hash code calculated from the \code{key} object is a
+#   32 characters long hexadecimal MD5 hash code.
+#   For more details, see @see "getChecksum".
+# }
+#
+# @author
+#
+# @examples "../incl/loadCache.Rex"
+#
+# \seealso{
+#  @see "saveCache".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################
+setMethodS3("loadCache", "default", function(key=NULL, sources=NULL, suffix=".Rcache", removeOldCache=TRUE, pathname=NULL, dirs=NULL, ..., onError=c("warning", "print", "quiet", "error")) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Validate arguments
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Argument 'onError':
+  onError <- match.arg(onError);
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Find cached file
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (is.null(pathname))
+    pathname <- findCache(key=key, suffix=suffix, dirs=dirs);
+  if (is.null(pathname))
+    return(NULL);
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Try to load cached object from file connection
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (!isFile(pathname))
+    return(NULL);
+
+  fh <- gzfile(pathname, open="rb");
+  on.exit({
+    if (!is.null(fh))
+      close(fh);
+  });
+
+  tryCatch({
+    header <- readCacheHeader(fh);
+    if (!is.null(sources))
+      header$sources <- sources;
+
+    timestamp <- NULL;
+    attachLocally(header);  # Attaches 'timestamp' (and 'sources')
+
+    if (!is.null(timestamp) && !is.null(sources)) {
+      for (sourcePathname in sources) {
+        if (!is.character(sources)) {
+          warning("No timestamp check of cache was performed. Unsupported type of cache source: ", class(sources)[1]);
+          break;
+        }
+
+        if (!file.exists(sourcePathname)) {
+          warning("No timestamp check of cache was performed. Source file not found: ", sourcePathname);
+          break;
+        }
+
+        # Is source file newer than cache?
+        lastModified <- file.info(sourcePathname)$mtime;
+        if (lastModified > timestamp) {
+          # Remove out-of-date cache file?
+          if (removeOldCache) {
+            close(fh); fh <- NULL;
+            file.remove(pathname);
+          }
+          return(NULL);
+        }
+      } # for (sourcePathname in sources)
+    }
+
+    # 4. Load cached object:
+    res <- .baseLoad(con=fh, ...);
+    object <- res$object;
+    res <- NULL; # Not needed anymore
+
+    # 5. Update the "last-modified" timestamp of the cache file?
+    touch <- getOption("R.cache::touchOnLoad");
+    touch <- identical(touch, TRUE);
+    if (touch) {
+      touchFile(pathname);
+    }
+
+    # 6. Return cached object
+    return(object);
+  }, error = function(ex) {
+     if (onError == "print") {
+       print(ex);
+     } else if (onError == "warning") {
+       warning(ex);
+     } else if (onError == "error") {
+       stop(ex);
+     }
+  })
+
+  NULL;
+})
+
+
+############################################################################
+# HISTORY:
+# 2012-09-10
+# o Updated readCacheHeader() to utilize updated .baseLoad().
+# 2011-08-16
+# o Added support for loading gzip compressed cache files.
+# 2009-10-16
+# o Now calling an internal .baseLoad() function of the package.
+# 2009-09-11
+# o Added argument 'onError' to loadCache(), to specify the action when
+#   an error occurs.  The default used to be to print the error message
+#   (onError="print"), but now the default is to generate a warning
+#   ("warning").  The other alternatives are do silently ignore it, or
+#   to throw the error ("error").  Except for onError="error", loadCache()
+#   always returns NULL if an error occurs.
+# 2008-02-27
+# o Added option to updated the "last-modified" timestamp of cache files
+#   whenever they are loaded via loadCache().
+# 2008-02-14
+# o Now errors reports the pathname, if available.
+# 2006-08-09
+# o Added link to cache() in Biobase.
+# 2006-05-25
+# o Added argument 'pathname' to make it possible to load a cache file
+#   explicitly.
+# 2006-04-04
+# o Added header comment for file format > v0.1.
+# o Added detection of file format version.
+# 2005-12-09
+# o Added support for internal 'cache' and 'timestamp' objects.
+# 2005-12-06
+# o Created.
+############################################################################
diff --git a/R/memoizedCall.R b/R/memoizedCall.R
new file mode 100644
index 0000000..4074559
--- /dev/null
+++ b/R/memoizedCall.R
@@ -0,0 +1,76 @@
+#########################################################################/**
+# @RdocDefault memoizedCall
+#
+# @title "Calls a function with memoization"
+#
+# \description{
+#  @get "title", that is, caches the results to be retrieved if
+#  the function is called again with the exact same arguments.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{what}{The @function to be called, or a @character string
+#     specifying the name of the function to be called,
+#     cf. @see "base::do.call".}
+#   \item{...}{Arguments passed to the function.}
+#   \item{envir}{The @environment in which the function is evaluated.}
+#   \item{force}{If @TRUE, any cached results are ignored, otherwise not.}
+#   \item{sources, dirs}{Optional arguments passed to
+#     @see "loadCache" and @see "saveCache".}
+# }
+#
+# \value{
+#   Returns the result of the function call.
+# }
+#
+# \details{
+#   If the @function returns @NULL, that particular function call is
+#   \emph{not} memoized.
+# }
+#
+# @author
+#
+# \seealso{
+#  Internally, @see "loadCache" is used to load memoized results,
+#  if available.  If not available, then @see "do.call" is used to
+#  evaluate the function call,
+#  and @see "saveCache" is used to save the results to cache.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################
+setMethodS3("memoizedCall", "default", function(what, ..., envir=parent.frame(), force=FALSE, sources=NULL, dirs=NULL) {
+  # 1. Generate cache file
+  key <- list(what=what, ...);
+  pathnameC <- generateCache(key=key, dirs=dirs);
+
+  # 1. Look for memoized results
+  if (!force) {
+    res <- loadCache(pathname=pathnameC, sources=sources);
+    if (!is.null(res)) return(res)
+  }
+
+  # 2. Otherwise, call method with arguments
+  res <- do.call(what, args=list(...), quote=FALSE, envir=envir);
+
+  # 3. Memoize results
+  saveCache(res, pathname=pathnameC, sources=sources);
+
+  # 4. Return results
+  res;
+}) # memoizedCall()
+
+
+
+#######################################################################
+# HISTORY:
+# 2015-02-27
+# o SPEEDUP: Now memoizedCall() generates cache pathname only once.
+# 2011-02-14
+# o Added argument 'sources' to memoizedCall().
+# 2011-02-13
+# o Created.
+#######################################################################
diff --git a/R/private.assertDigest.R b/R/private.assertDigest.R
new file mode 100644
index 0000000..6e6d905
--- /dev/null
+++ b/R/private.assertDigest.R
@@ -0,0 +1,61 @@
+.assertDigest <- function(onDiff=c("error", "warning", "message"), ...) {
+  # Argument 'onDiff':
+  onDiff <- match.arg(onDiff);
+
+  # Value to validate against
+  d1 <- digest(0);
+  # Get the "truth"
+  ver <- packageVersion("digest");
+  if (ver <= "0.2.3") {
+    d0 <- "78a10a7e5929f8c605f71823203c0dc5";
+  } else if (ver >= "0.3.0") {
+    d0 <- "908d1fd10b357ed0ceaaec823abf81bc";
+  } else {
+    msg <- sprintf("No assertion rule available for digest v%s. Names of cache files might differ between R version and platforms.", ver);
+    warning(msg);
+    return();
+  }
+
+  # Assert that we get the above results on the current machine.
+  if (!identical(d1, d0)) {
+    msg <- sprintf("Assertion failed: Detected inconsistency in digest::digest(0) (%s != %s) using digest v%s. The effect of this is that the generated cache files will be named differently on this platform/R version than in another.", d1, d0, ver);
+    if (onDiff == "error") {
+      throw(msg);
+    } else if (onDiff == "warning") {
+      warning(msg);
+    } else {
+      message(msg);
+    }
+  }
+} # .assertDigest()
+
+
+############################################################################
+# HISTORY:
+# 2013-08-03
+# o BUG FIX: R.cache:::.assertDigest() called from within another package
+#   would give an error that packageVersion() of 'utils' was not found.
+# 2012-11-17
+# o Moved .assertDigest() from aroma.core to R.cache and tidied it up.
+# 2007-04-04
+# o BUG FIX: The test for version of digest and the assignment of the
+#   conditional patch must be done in .First.lib() and not here.  Anything
+#   put there such as if() statements will be evaluated during the build
+#   of the package.
+# 2007-03-08
+# o Prepared the digest() patch and .assertDigest() for the upcoming
+#   digest v0.3.0.  This will make the package work with both digest
+#   v0.2.3 and v0.3.0, which is needed until everyone upgrade.
+# o Thanks to Luke Tierney's reply on my r-devel question of the serialize
+#   header, we now look for the 4th newline, which is more robust to do
+#   when serializing to ASCII.
+# 2007-03-07
+# o Added .assertDigest().
+# o BUG FIX: serialize() gives different results depending on R version.
+#   The difference seems to be in raw bytes 8, 9 and 10.  In other words,
+#   if those are excluded before passing the stream on to the "digester"
+#   we get the same results.  From testing with "random" object we also
+#   know that there are at most 18 bytes in the header.
+# 2007-01-06
+# o Created.
+############################################################################
diff --git a/R/private.baseLoad.R b/R/private.baseLoad.R
new file mode 100644
index 0000000..933a723
--- /dev/null
+++ b/R/private.baseLoad.R
@@ -0,0 +1,102 @@
+###########################################################################/** 
+# @eval "{.baseLoad <<- R.cache:::.baseLoad; ''}"
+# @RdocFunction ".baseLoad"
+#
+# @title "Loads an object from a file connection"
+#
+# \description{
+#   @get "title" similar to @see "base::load", but without resetting 
+#   file connections (to position zero).
+#
+#   \emph{WARNING: This is an internal function that should not be
+#   called by anything but the internal code of the \pkg{R.cache} package.}
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{con}{A @connection.}
+#   \item{envir}{An @environment where the loaded object will be stored.}
+# }
+#
+# \value{
+#  Returns (invisible) a @character @vector of the names of objects
+#  loaded.
+# }
+#
+# \details{
+#  The reason why it is not possible to use @see "base::load" is that
+#  that resets the file position of the connection before trying to
+#  load the object.
+#  The reason why that happens is because when you pass a regular file
+#  connection to @see "base::load" it gets coerced via @see "base::gzcon",
+#  which is the function that resets the file position.
+# 
+#  The workaround is to creat a local copy of \code{base::load()} and
+#  modify it by dropping the \code{gzcon()} coersion.  This is possible
+#  because this function, that is \code{.baseLoad()}, is always called
+#  with a \code{gzfile()} @connection.
+# }
+#
+# \seealso{
+#   This function is used by @see "loadCache" and @see "readCacheHeader".
+# }
+#
+# @keyword internal
+#*/###########################################################################
+.baseLoad <- function(con, envir=parent.frame()) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Assert correctness of connection
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  magic <- readChar(con, nchars=5, useBytes=TRUE);
+  if (regexpr("RD[AX]2\n", magic) == -1L) {
+    if (regexpr("RD[ABX][12]\r", magic) == 1L) {
+      stop("input has been corrupted, with LF replaced by CR");
+    } else {
+      stop(gettextf("file '%s' has magic number '%s'\n   Use of save versions prior to 2 is deprecated", summary(file)$description, gsub("[\n\r]*", "", magic)));
+    }
+  }
+  
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Load object from connection
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  res <- readRDS(con);
+} # .baseLoad()
+
+
+
+############################################################################
+# HISTORY:
+# 2012-09-10
+# o CRAN POLICY: Updated internal .baseLoad() to utilize readRDS() instead
+#   of .Internal(loadFromConn2(...)) such that it still reads the same
+#   file format.
+# 2012-03-20
+# o Added an Rdoc comment explaining the .baseLoad() function.
+# o CRAN POLICY: Previously .baseLoad() called .Internal(loadFromConn2(...))
+#   which is no longer allowed for CRAN packages.  However, there is
+#   still the problem of base::load(con) coercing a file connection via
+#   gzcon() and while doing that it also resets the file position, which
+#   we do not want.  The workaround is not to do dynamic code computation
+#   on base::load() code and create an adjusted just-in-time local version
+#   that avoids the gzcon() coercion.
+# 2011-10-05
+# o BUG FIX: Same bug fix as on 2011-08-31 but now also for R v2.13.0.
+# 2011-08-31
+# o BUG FIX (for R v2.12.2 and before): After adding support for 
+#   compressed files in R.cache v0.5.0, we would get the 'Error in
+#   seek.connection(con, origin = "current", where = -5) : whence = "end"
+#   is not implemented for gzfile connections' in readCacheHeader()
+#   iff running R v2.12.2 or before.
+# 2009-10-16
+# o BUG FIX: In R v2.10.0 and newer, we would get an error reporting that
+#   internal function loadFromConn() does not exists.  That function was
+#   used because it would read the stream from the position after the magic
+#   string in the connection.  We now use loadFromConn2() which tries to
+#   read and validate the magic string.  So, we have to make sure that the
+#   connection is positioned where the magic string is.  We do this using
+#   seek().  We also note that we could have used loadFromConn2() already
+#   since R v2.3.0.  Since this package requires R v2.3.0, we simply drop
+#   the old implementation and use this new one.
+# o Created.
+############################################################################
diff --git a/R/readCacheHeader.R b/R/readCacheHeader.R
new file mode 100755
index 0000000..b0909d4
--- /dev/null
+++ b/R/readCacheHeader.R
@@ -0,0 +1,120 @@
+#########################################################################/**
+# @RdocDefault readCacheHeader
+#
+# @title "Loads data from file cache"
+#
+# \description{
+#  @get "title", which is unique for an optional key object.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{file}{A filename or a @connection.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns a named @list structure with element \code{identifier},
+#   \code{version}, \code{comment} (optional), \code{sources} (optional),
+#   and \code{timestamp}.
+# }
+#
+# @author
+#
+# @examples "../incl/readCacheHeader.Rex"
+#
+# \seealso{
+#  @see "findCache".
+#  @see "loadCache".
+#  @see "saveCache".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("readCacheHeader", "default", function(file, ...) {
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Validate arguments
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Argument 'file':
+  if (inherits(file, "connection")) {
+    pathname <- sprintf("'%s' [description of the opened connection]", summary(file)$description);
+  } else {
+    pathname <- as.character(file);
+    if (!isFile(pathname))
+      throw("Argument 'file' is not an existing file: ", pathname);
+
+    file <- gzfile(pathname, open="rb");
+    on.exit({
+      if (!is.null(file))
+        close(file);
+    });
+  }
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Try to load cached object from file connection
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  header <- list();
+
+  # 1a. Load identifier:
+  id <- readChar(con=file, nchars=64L);
+  if (length(id) == 0L) {
+    throw("Rcache file format error. Read empty header identifier: ", pathname);
+  }
+  pattern <- "^Rcache v([0-9][0-9]*[.][0-9][0-9]*([.][0-9][0-9]*)*).*";
+  if (regexpr(pattern, id) == -1L) {
+    throw("Rcache file format error ('", pathname, "'). Invalid identifier: ", id);
+  }
+  header$identifier <- id;
+
+  # 1b. Get version
+  header$version <- gsub(pattern, "\\1", id);
+
+  # 1c. Read trailing '\0'.
+  dummy <- readBin(con=file, what=integer(), size=1, n=1);
+
+  # 2a. Load comment
+  if (compareVersion(header$version, "0.1") > 0L) {
+    nchars <- readBin(con=file, what=integer(), size=4L, n=1L);
+    header$comment <- readChar(con=file, nchars=nchars);
+  }
+
+  # 2b. Read trailing '\0'.
+  dummy <- readBin(con=file, what=integer(), size=1L, n=1L);
+
+  # 3. Load sources:
+  sources <- NULL;  # To please 'codetools' in R v2.6.0
+  res <- .baseLoad(con=file, ...);
+  header$sources <- res$sources;
+
+  # 4. Load timestamp:
+  res <- .baseLoad(con=file, ...);
+  header$timestamp <- res$timestamp;
+
+  header;
+})
+
+
+############################################################################
+# HISTORY:
+# 2012-09-10
+# o Updated readCacheHeader() to utilize updated .baseLoad().
+# 2011-08-16
+# o Added support for reading gzip compressed cache files.
+# 2009-10-16
+# o Now calling an internal .baseLoad() function of the package.
+# 2009-08-11
+# o Now readCacheHeader() reports the "pathname" in error/warnings messages,
+#   if argument 'file' refers to a file and the "description" if it refers
+#   to a connection.
+# 2009-07-29
+# o ROBUSTNESS: Added sanity check to readCacheHeader() testing that the
+#   read header identifier is non-empty.
+# 2008-02-14
+# o BUG FIX: The throw() for invalid identifiers was trying to put the
+#   connection object is the out and not the identifier.
+# 2006-04-04
+# o Created.
+############################################################################
diff --git a/R/saveCache.R b/R/saveCache.R
new file mode 100755
index 0000000..9a016ca
--- /dev/null
+++ b/R/saveCache.R
@@ -0,0 +1,139 @@
+#########################################################################/**
+# @RdocDefault saveCache
+#
+# @title "Saves data to file cache"
+#
+# \description{
+#  @get "title", which is unique for an optional key object.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{object}{The object to be saved to file.}
+#   \item{key}{An optional object from which a hexadecimal hash
+#     code will be generated and appended to the filename.}
+#   \item{sources}{Source objects used for comparison of timestamps when
+#     cache is loaded later.}
+#   \item{suffix}{A @character string to be appended to the end of the
+#     filename.}
+#   \item{comment}{An optional @character string written in ASCII at the
+#     beginning of the file.}
+#   \item{pathname}{(Advanced) An optional @character string specifying
+#     the pathname to the cache file.  If not specified (default), a unique
+#     one is automatically generated from arguments \code{key} and
+#     \code{suffix} among other things.}
+#   \item{dirs}{A @character @vector constituting the path to the
+#      cache subdirectory (of the \emph{cache root directory}
+#      as returned by @see "getCacheRootPath") to be used.
+#      If @NULL, the path will be the cache root path.}
+#   \item{compress}{If @TRUE, the cache file will be saved using
+#      gzip compression, otherwise not.}
+#   \item{...}{Additional argument passed to @see "base::save".}
+# }
+#
+# \value{
+#   Returns (invisible) the pathname of the cache file.
+# }
+#
+# \section{Compression}{
+#  The \code{saveCache()} method saves a compressed cache file
+#  (with filename extension *.gz) if argument \code{compress} is @TRUE.
+#  The @see "loadCache" method locates (via @see "findCache") and
+#  loads such cache files as well.
+# }
+#
+# @author
+#
+# \examples{\dontrun{For an example, see ?loadCache}}
+#
+# \seealso{
+#  For more details on how the hash code is generated etc, @see "loadCache".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/#########################################################################
+setMethodS3("saveCache", "default", function(object, key=NULL, sources=NULL, suffix=".Rcache", comment=NULL, pathname=NULL, dirs=NULL, compress=getOption("R.cache::compress", FALSE), ...) {
+  # Argument 'compress':
+  if (!isTRUE(compress)) compress <- FALSE
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Cache file
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (is.null(pathname)) {
+    # Generate cache name from basename and hash object.
+    pathname <- generateCache(key=key, suffix=suffix, dirs=dirs);
+  }
+
+
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  # Save to file connection
+  # - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+  if (compress) {
+    pathname <- sprintf("%s.gz", pathname);
+    fh <- gzfile(pathname, open="wb");
+  } else {
+    fh <- file(pathname, open="wb");
+  }
+  on.exit(close(fh));
+
+  # Save 'identifier'
+  identifier <- "Rcache v0.1.7 (R package R.cache by Henrik Bengtsson)";
+  if (nchar(identifier) > 64L)
+    throw("Internal error. Identifier is too long: ", identifier);
+  tail <- paste(rep(" ", times=64L-nchar(identifier)), collapse="");
+  identifier <- paste(identifier, tail, sep="");
+  writeChar(con=fh, identifier, nchars=64L);
+
+  # Save 'comment'
+  if (is.null(comment))
+    comment <- "";
+  writeBin(con=fh, nchar(comment), size=4L);
+  writeChar(comment, con=fh, nchars=nchar(comment));
+
+  # Save 'sources'
+
+  # Look up base::save() once; '::' is expensive
+  base_save <- base::save;
+
+  # If 'sources' is not evaluated, it is a so called promise, which will
+  # make all of its calling environments to be save too.
+  dummy <- is.null(sources);
+  base_save(file=fh, sources, compress=compress, ...);
+
+  # Save 'timestamp'
+  timestamp <- Sys.time();
+  base_save(file=fh, timestamp, compress=compress, ...);
+
+  # Save 'object'
+  base_save(file=fh, object, compress=compress, ...);
+
+  invisible(pathname);
+})
+
+
+############################################################################
+# HISTORY:
+# 2013-12-21
+# o Added argument 'pathname' to saveCache().
+# 2011-08-16
+# o Added support for gzip compressed cache files.
+# 2007-01-24
+# o Now saveCache() returns the pathname to the cache file.
+# 2006-05-25
+# o BUG FIX: Work around for not saving "promises" (non-evaluated arguments)
+#   in base::save(), which otherwise includes all of the surrounding
+#   environment if 'sources' is not evaluated/missing.  For more details
+#   see code and my email to r-devel on 2006-05-25.  Thanks to Brian Ripley
+#   for explaining what was going on.
+# 2006-04-04
+# o Added header comment.
+# 2005-12-09
+# o Object save to file is now a structure containing the object to be
+#   cached, a timestamp specifying the it was cached, and a source object.
+# o Replaced argument 'file' with 'source'.
+# 2005-12-06
+# o Created.
+############################################################################
diff --git a/R/setCachePath.R b/R/setCachePath.R
new file mode 100755
index 0000000..51f279b
--- /dev/null
+++ b/R/setCachePath.R
@@ -0,0 +1,48 @@
+#########################################################################/**
+# @RdocDefault setCachePath
+#
+# @title "Sets the path to the file cache directory"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{dirs}{A @character @vector constituting the path to the
+#      cache subdirectory of interest.}
+#   \item{path}{The path to override the path according to the 
+#      \code{dirs} argument.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns nothing.
+# }
+#
+# @author
+#
+# \seealso{
+#   @see "getCachePath".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/######################################################################### 
+setMethodS3("setCachePath", "default", function(dirs=NULL, path=NULL, ...) {
+  subname <- paste(dirs, collapse="/");
+  name <- paste("R.cache:cachePath", subname, sep=":");
+  opts <- list(path);
+  names(opts) <- name;
+  ovalue <- options(opts);
+  invisible(ovalue);
+}, export=FALSE)
+
+
+############################################################################
+# HISTORY:
+# 2007-01-24
+# o Created.
+############################################################################
diff --git a/R/setCacheRootPath.R b/R/setCacheRootPath.R
new file mode 100644
index 0000000..462fb61
--- /dev/null
+++ b/R/setCacheRootPath.R
@@ -0,0 +1,65 @@
+#########################################################################/**
+# @RdocDefault setCacheRootPath
+#
+# @title "Sets the root path to the file cache directory"
+#
+# \description{
+#  @get "title".
+#  By default, this function will set it to \code{~/.Rcache/}.
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{path}{The path.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns (invisibly) the old root path.
+# }
+#
+# @author
+#
+# \seealso{
+#  @see "getCacheRootPath".
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+#*/######################################################################### 
+setMethodS3("setCacheRootPath", "default", function(path="~/.Rcache", ...) {
+  path <- as.character(path);
+
+  if (!isDirectory(path)) {
+    mkdirs(path);
+    if (!isDirectory(path)) {
+      throw("Could not create cache directory: ", path);
+    }
+  }
+
+  # Add a README.txt file, if missing.
+  .addREADME(to=path);
+
+  ovalue <- options("R.cache::rootPath"=path);
+
+  invisible(ovalue);
+}) # setCacheRootPath()
+
+
+############################################################################
+# HISTORY:
+# 2012-09-10
+# o Renamed the installed .Rcache/ directory to _Rcache/ to avoid
+#   R CMD check NOTEs.
+# 2011-12-29
+# o Now setCacheRootPath() adds a README.txt file to the root path, iff
+#   missing. It explains why the directory structure exists and what
+#   created it.
+# 2007-03-07
+# o Changed the default root path to ~/.Rcache/
+# 2007-01-24
+# o Renamed from setCachePath().
+# 2005-12-07
+# o Created.
+############################################################################
diff --git a/R/setupCacheRootPath.R b/R/setupCacheRootPath.R
new file mode 100644
index 0000000..7fd44e6
--- /dev/null
+++ b/R/setupCacheRootPath.R
@@ -0,0 +1,82 @@
+#########################################################################/**
+# @RdocDefault setupCacheRootPath
+#
+# @title "Interactively offers the user to set up the default root path"
+#
+# \description{
+#  @get "title".
+# }
+#
+# @synopsis
+#
+# \arguments{
+#   \item{defaultPath}{Default root path to set.}
+#   \item{...}{Not used.}
+# }
+#
+# \value{
+#   Returns (invisibly) the root path,
+#   or @NULL if running a non-interactive session.
+# }
+#
+# \details{
+#   If the cache root path is already set, it is used and nothing is done.
+#   If the "default" root path (\code{defaultPath}) exists, it is used,
+#   otherwise, if running interactively, the user is asked to approve
+#   the usage (and creation) of the default root path.
+#   In all other cases, the cache root path is set to a session-specific
+#   temporary directory.
+# }
+#
+# @author
+#
+# \seealso{
+#  Internally, @see "setCacheRootPath" is used to set the cache root path.
+#  The @see "base::interactive" function is used to test whether \R is
+#  running interactively or not.
+# }
+#
+# @keyword "programming"
+# @keyword "IO"
+# @keyword "internal"
+#*/#########################################################################
+setMethodS3("setupCacheRootPath", "default", function(defaultPath="~/.Rcache/", ...) {
+  rootPath <- getCacheRootPath(NULL);
+
+  # If already set, nothing to do.
+  if (!is.null(rootPath)) {
+    return(invisible(rootPath));
+  }
+
+  # Use a temporary root path...
+  rootPath <- file.path(tempdir(), ".Rcache");
+
+  # unless the default directory exists, ...
+  if (isDirectory(defaultPath)) {
+    rootPath <- defaultPath;
+  } else if (interactive()) {
+    # or we cn ask the user to confirm the default path...
+    prompt <- "The R.cache package needs to create a directory that will hold cache files.";
+    if (identical(defaultPath, "~/.Rcache/")) {
+      prompt <- c(prompt, "It is convenient to use one in the user's home directory, because it remains also after restarting R.");
+    }
+    prompt <- c(prompt, sprintf("Do you wish to create the '%s' directory? If not, a temporary directory (%s) that is specific to this R session will be used.", defaultPath, rootPath));
+    prompt <- paste(prompt, collapse=" ");
+    tryCatch({
+      ans <- .textPrompt(prompt=prompt, options=c("Y"="yes", "n"="no"));
+      if (ans == "yes") rootPath <- defaultPath;
+    }, condition=function(ex) {});
+  }
+
+  setCacheRootPath(rootPath);
+  rootPath <- getCacheRootPath();
+
+  invisible(rootPath);
+}) # setupCacheRootPath()
+
+
+############################################################################
+# HISTORY:
+# 2011-12-29
+# o Added setupCacheRootPath().
+############################################################################
diff --git a/R/textPrompt.R b/R/textPrompt.R
new file mode 100644
index 0000000..da1e5e1
--- /dev/null
+++ b/R/textPrompt.R
@@ -0,0 +1,74 @@
+.textPrompt <- function(prompt, options=c("Y"="yes", "n"="no"), caseSensitive=FALSE, maxTries=Inf, type=c("message", "output"), onSink=c("error", "ignore"), ...) {
+  # Argument 'maxTries':
+  maxTries <- Arguments$getNumeric(maxTries, range=c(1,Inf));
+
+  # Argument 'onSink':
+  onSink <- match.arg(onSink);
+
+  # Argument 'type':
+  type <- match.arg(type);
+
+  # Check if standard output is redirected.
+  # NOTE: There always *2* sinks for type="message", cf. help("sink").
+  minSink <- switch(type, message=2L, 0L);
+  hasSink <- (sink.number(type=type) > minSink);
+  if (hasSink) {
+    if (onSink == "error") {
+      throw("Cannot prompt user via the standard ", type, ", because it is currently redirected and (most likely) not visible to the user.");
+    }
+  }
+
+  # How to present the options to the user
+  keys <- names(options);
+  if (is.null(keys)) {
+    keys <- options;
+  }
+  promptF <- sprintf("%s [%s]: ", prompt, paste(keys, collapse="/"));
+  promptR <- gettext("Unknown reply.\n");
+
+  # Where to prompt
+  if (type == "output") {
+    con <- stdout();
+  } else {
+    con <- stderr();
+  }
+
+  count <- 0L;
+  while (count < maxTries) {
+    cat(file=con, promptF);
+    ans <- readline();
+
+    count <- count + 1L;
+
+    ans <- trim(ans);
+    if (ans == "") {
+      idx <- 1L;
+    } else {
+      if (caseSensitive) {
+        idx <- pmatch(ans, options);
+      } else {
+        idx <- pmatch(tolower(ans), tolower(options));
+      }
+    }
+
+    if (is.finite(idx)) {
+      ans <- options[idx];
+      break;
+    }
+
+    cat(file=con, promptR);
+  } # while(...)
+
+  attributes(ans) <- NULL;
+
+  ans;
+} # .textPrompt()
+
+
+############################################################################
+# HISTORY:
+# 2014-05-01
+# o Now argument 'type' defaults to c("message", "output").
+# 2011-12-30
+# o Added textPrompt().
+############################################################################
diff --git a/R/zzz.R b/R/zzz.R
new file mode 100755
index 0000000..6494287
--- /dev/null
+++ b/R/zzz.R
@@ -0,0 +1,24 @@
+## covr: skip=all
+
+.onLoad <- function(libname, pkgname) {
+  ns <- getNamespace(pkgname);
+  pkg <- Package(pkgname);
+  assign(pkgname, pkg, envir=ns);
+
+  # Setup the cache root path, possibly by prompting the user.
+  setupCacheRootPath();
+}
+
+.onAttach <- function(libname, pkgname) {
+  pkg <- get(pkgname, envir=getNamespace(pkgname));
+  startupMessage(pkg);
+}
+
+
+############################################################################
+# HISTORY:
+# 2013-10-17
+# o CLEANUP: autoload("print.Object", package="R.oo") is no longer needed.
+# 2005-12-09
+# o Created.
+############################################################################
diff --git a/README.md b/README.md
new file mode 100644
index 0000000..0b2bf41
--- /dev/null
+++ b/README.md
@@ -0,0 +1,19 @@
+# R.cache: Fast and Light-weight Caching (Memoization) of Objects and Results to Speed Up Computations
+
+
+## Installation
+R package R.cache is available on [CRAN](http://cran.r-project.org/package=R.cache) and can be installed in R as:
+```r
+install.packages('R.cache')
+```
+
+
+
+
+## Software status
+
+| Resource:     | CRAN        | Travis CI     | Appveyor         |
+| ------------- | ------------------- | ------------- | ---------------- |
+| _Platforms:_  | _Multiple_          | _Linux_       | _Windows_        |
+| R CMD check   | <a href="http://cran.r-project.org/web/checks/check_results_R.cache.html"><img border="0" src="http://www.r-pkg.org/badges/version/R.cache" alt="CRAN version"></a> | <a href="https://travis-ci.org/HenrikBengtsson/R.cache"><img src="https://travis-ci.org/HenrikBengtsson/R.cache.svg" alt="Build status"></a> | <a href="https://ci.appveyor.com/project/HenrikBengtsson/r-cache"><img src="https://ci.appveyor.com/api/projects/status/github/HenrikBengtsson/R.cache?svg=true" alt= [...]
+| Test coverage |                     | <a href="https://coveralls.io/r/HenrikBengtsson/R.cache"><img src="https://coveralls.io/repos/HenrikBengtsson/R.cache/badge.svg?branch=develop" alt="Coverage Status"/></a>   |                  |
diff --git a/appveyor.yml b/appveyor.yml
new file mode 100644
index 0000000..087d4f9
--- /dev/null
+++ b/appveyor.yml
@@ -0,0 +1,62 @@
+#----------------------------------------------------------------
+# AppVeyor configuration for R packages
+#
+# REFERENCES:
+# * AppVeyor CI: https://ci.appveyor.com/
+# * r-travis: https://github.com/craigcitro/r-travis
+#
+# Validate your .appveyor.yml file at
+# https://ci.appveyor.com/tools/validate-yaml 
+#----------------------------------------------------------------
+environment:
+  _R_CHECK_FORCE_SUGGESTS_: false
+
+# DO NOT CHANGE the "init" and "install" sections below
+
+# Download script file from GitHub
+init:
+  ps: |
+        $ErrorActionPreference = "Stop"
+        Invoke-WebRequest http://raw.github.com/HenrikBengtsson/r-appveyor/master/scripts/appveyor-tool.ps1 -OutFile "..\appveyor-tool.ps1"
+        Import-Module '..\appveyor-tool.ps1'
+install:
+  ps: Bootstrap
+
+# Adapt as necessary starting from here
+
+build_script:
+  - echo Current directory=%CD%
+
+
+
+
+
+  - travis-tool.sh install_r digest R.methodsS3 R.oo R.utils
+
+
+
+test_script:
+  - travis-tool.sh run_tests
+
+after_test:
+  - 7z a all-Rout.zip *.Rcheck\**\*.Rout *.Rcheck\**\*.fail
+
+artifacts:
+  - path: '*.Rcheck\**\*.log'
+    name: Logs
+
+  - path: '*.Rcheck\**\*.out'
+    name: Logs
+
+  - path: all-Rout.zip
+    name: AllRout
+
+  - path: '\*_*.tar.gz'
+    name: Bits
+
+  - path: '\*_*.zip'
+    name: Bits
+
+on_failure:
+  - 7z a failure.zip *.Rcheck\*
+  - appveyor PushArtifact failure.zip
diff --git a/cran-comments.md b/cran-comments.md
new file mode 100644
index 0000000..030d8c4
--- /dev/null
+++ b/cran-comments.md
@@ -0,0 +1,32 @@
+# CRAN submission R.cache 0.12.0
+on 2015-11-11
+
+Thanks in advance
+
+
+## Notes not sent to CRAN
+The package has been verified using `R CMD check --as-cran` on:
+
+* Platform x86_64-pc-linux-gnu (64-bit):
+  - R version 3.0.3 (2014-03-06)
+  - R version 3.1.3 (2015-03-09)
+  - R version 3.2.2 (2015-08-14)
+  - R version 3.2.2 Patched (2015-11-06 r69615)
+  - R Under development (unstable) (2015-11-10 r69617)
+
+* Platform: x86_64-apple-darwin13.4.0 (64-bit):
+  - R version 3.2.2 Patched (2015-10-22 r69556)
+
+* Platform x86_64-w64-mingw32/x64 (64-bit):
+  - R version 3.1.3 (2015-03-09)
+  - R version 3.2.2 Patched (2015-11-05 r69602)
+  - R Under development (unstable) (2015-11-09 r69615)
+
+It has also verified using the <http://win-builder.r-project.org/> service.
+
+Moreover, the updates cause no issues for any of the following
+11 reverse dependency on CRAN and Bioconductor, which have been
+tested with `R CMD check --as-cran`: aroma.affymetrix 2.14.0,
+aroma.cn 1.6.1, aroma.core 2.14.0, fulltext 0.1.4, MSnID 1.5.0,
+PSCBS 0.50.0, QDNAseq 1.7.0, R.filesets 2.9.0, R.rsp 0.20.0,
+repmis 0.4.4 and scholar 0.1.3.
diff --git a/incl/BengtssonH_2003.bib.Rdoc b/incl/BengtssonH_2003.bib.Rdoc
new file mode 100755
index 0000000..6ed8976
--- /dev/null
+++ b/incl/BengtssonH_2003.bib.Rdoc
@@ -0,0 +1 @@
+H. Bengtsson, \emph{The R.oo package - Object-Oriented Programming with References Using Standard R Code}, In Kurt Hornik, Friedrich Leisch and Achim Zeileis, editors, Proceedings of the 3rd International Workshop on Distributed Statistical Computing (DSC 2003), March 20-22, Vienna, Austria. \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/}
\ No newline at end of file
diff --git a/incl/evalWithMemoization.Rex b/incl/evalWithMemoization.Rex
new file mode 100644
index 0000000..d0352f7
--- /dev/null
+++ b/incl/evalWithMemoization.Rex
@@ -0,0 +1,77 @@
+for (kk in 1:5) {
+  cat(sprintf("Iteration #%d:\n", kk))
+  res <- evalWithMemoization({
+    cat("Evaluating expression...")
+    a <- 1
+    b <- 2
+    c <- 4
+    Sys.sleep(1)
+    cat("done\n")
+    b
+  })
+  print(res)
+
+  # Sanity checks
+  stopifnot(a == 1 && b == 2 && c == 4)
+
+  # Clean up
+  rm(a, b, c)
+} # for (kk ...)
+
+
+## OUTPUTS:
+## Iteration #1:
+## Evaluating expression...done
+## [1] 2
+## Iteration #2:
+## [1] 2
+## Iteration #3:
+## [1] 2
+## Iteration #4:
+## [1] 2
+## Iteration #5:
+## [1] 2
+
+
+############################################################
+# WARNING
+############################################################
+# If the expression being evaluated depends on 
+# "input" objects, then these must be be specified
+# explicitly as "key" objects.
+for (ii in 1:2) {
+  for (kk in 1:3) {
+    cat(sprintf("Iteration #%d:\n", kk))
+    res <- evalWithMemoization({
+      cat("Evaluating expression...")
+      a <- kk
+      Sys.sleep(1)
+      cat("done\n")
+      a
+    }, key=list(kk=kk))
+    print(res)
+
+    # Sanity checks
+    stopifnot(a == kk)
+
+    # Clean up
+    rm(a)
+  } # for (kk ...)
+} # for (ii ...)
+
+## OUTPUTS:
+## Iteration #1:
+## Evaluating expression...done
+## [1] 1
+## Iteration #2:
+## Evaluating expression...done
+## [1] 2
+## Iteration #3:
+## Evaluating expression...done
+## [1] 3
+## Iteration #1:
+## [1] 1
+## Iteration #2:
+## [1] 2
+## Iteration #3:
+## [1] 3
diff --git a/incl/loadCache.Rex b/incl/loadCache.Rex
new file mode 100755
index 0000000..2fdcd6c
--- /dev/null
+++ b/incl/loadCache.Rex
@@ -0,0 +1,26 @@
+simulate <- function(mean, sd) {
+  # 1. Try to load cached data, if already generated
+  key <- list(mean, sd)
+  data <- loadCache(key)
+  if (!is.null(data)) {
+    cat("Loaded cached data\n")
+    return(data);
+  }
+
+  # 2. If not available, generate it.
+  cat("Generating data from scratch...")
+  data <- rnorm(1000, mean=mean, sd=sd)
+  Sys.sleep(1)             # Emulate slow algorithm
+  cat("ok\n")
+  saveCache(data, key=key, comment="simulate()")
+
+  data;
+}
+
+data <- simulate(2.3, 3.0)
+data <- simulate(2.3, 3.5)
+data <- simulate(2.3, 3.0) # Will load cached data
+
+# Clean up
+file.remove(findCache(key=list(2.3,3.0)))
+file.remove(findCache(key=list(2.3,3.5)))
diff --git a/incl/readCacheHeader.Rex b/incl/readCacheHeader.Rex
new file mode 100755
index 0000000..67e22d6
--- /dev/null
+++ b/incl/readCacheHeader.Rex
@@ -0,0 +1,11 @@
+
+data <- 1:120
+key <- list(some=1, vari=2, ables=3)
+
+saveCache(key=key, data, comment="A simple example of a cached object.")
+
+header <- readCacheHeader(findCache(key=key))
+print(header)
+
+# Clean up
+file.remove(findCache(key=key))
diff --git a/inst/_Rcache/README.txt b/inst/_Rcache/README.txt
new file mode 100644
index 0000000..d30135b
--- /dev/null
+++ b/inst/_Rcache/README.txt
@@ -0,0 +1,7 @@
+This directory structure was created by the R package 'R.cache'
+available on CRAN [http://cran.r-project.org/package=R.cache].
+It holds cache files containing results memoized by various
+R packages that utilize the R.cache package.  It is safe to
+delete all or part of these files at any time.  By definition,
+if memoized results are missing, they are recalculated by the
+R package who needs them/created them in the first place.
diff --git a/man/000.baseLoad.Rd b/man/000.baseLoad.Rd
new file mode 100644
index 0000000..7d01f4a
--- /dev/null
+++ b/man/000.baseLoad.Rd
@@ -0,0 +1,57 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  private.baseLoad.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+
+ \name{.baseLoad}
+\alias{.baseLoad}
+
+
+ \title{Loads an object from a file connection}
+
+ \description{
+   Loads an object from a file connection similar to \code{\link[base]{load}}(), but without resetting
+   file connections (to position zero).
+
+   \emph{WARNING: This is an internal function that should not be
+   called by anything but the internal code of the \pkg{R.cache} package.}
+ }
+
+ \usage{
+.baseLoad(con, envir=parent.frame())
+}
+
+ \arguments{
+   \item{con}{A \code{\link[base:connections]{connection}}.}
+   \item{envir}{An \code{\link[base]{environment}} where the loaded object will be stored.}
+ }
+
+ \value{
+  Returns (invisible) a \code{\link[base]{character}} \code{\link[base]{vector}} of the names of objects
+  loaded.
+ }
+
+ \details{
+  The reason why it is not possible to use \code{\link[base]{load}}() is that
+  that resets the file position of the connection before trying to
+  load the object.
+  The reason why that happens is because when you pass a regular file
+  connection to \code{\link[base]{load}}() it gets coerced via \code{\link[base]{gzcon}}(),
+  which is the function that resets the file position.
+
+  The workaround is to creat a local copy of \code{base::load()} and
+  modify it by dropping the \code{gzcon()} coersion.  This is possible
+  because this function, that is \code{.baseLoad()}, is always called
+  with a \code{gzfile()} \code{\link[base:connections]{connection}}.
+ }
+
+ \seealso{
+   This function is used by \code{\link{loadCache}}() and \code{\link{readCacheHeader}}().
+ }
+
+
+\keyword{internal}
diff --git a/man/Non-documented_objects.Rd b/man/Non-documented_objects.Rd
new file mode 100755
index 0000000..4fdeea6
--- /dev/null
+++ b/man/Non-documented_objects.Rd
@@ -0,0 +1,38 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  999.NonDocumentedObjects.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{Non-documented objects}
+\alias{Non-documented objects}
+\title{Non-documented objects}
+
+
+% File cache
+
+% Class Object
+\alias{getChecksum.Object}
+
+% Misc.
+\alias{.textPrompt}
+
+\description{
+  This page contains aliases for all "non-documented" objects that
+  \code{R CMD check} detects in this package.
+
+  Almost all of them are \emph{generic} functions that have specific
+  document for the corresponding method coupled to a specific class.
+  Other functions are re-defined by \code{setMethodS3()} to
+  \emph{default} methods. Neither of these two classes are non-documented
+  in reality.
+  The rest are deprecated methods.
+}
+
+\author{Henrik Bengtsson}
+
+
+\keyword{documentation}
+\keyword{internal}
diff --git a/man/R.cache-package.Rd b/man/R.cache-package.Rd
new file mode 100755
index 0000000..c7ea1cb
--- /dev/null
+++ b/man/R.cache-package.Rd
@@ -0,0 +1,86 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  999.package.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{R.cache-package}
+\alias{R.cache-package}
+\alias{R.cache}
+\docType{package}
+
+\title{Package R.cache}
+
+
+\description{
+  Memoization can be used to speed up repetitive and computational expensive function calls.  The first time a function that implements memoization is called the results are stored in a cache memory.  The next time the function is called with the same set of parameters, the results are momentarily retrieved from the cache avoiding repeating the calculations.  With this package, any R object can be cached in a key-value storage where the key can be an arbitrary set of R objects.  The cach [...]
+}
+
+\section{Installation and updates}{
+  To install this package and all of its dependent packages, do:
+  \code{install.packages("R.cache")}
+}
+
+\section{To get started}{
+  \itemize{
+   \item{\link{loadCache}, \link{saveCache}}{
+     Methods for loading and saving objects from and to the cache.
+   }
+   \item{\link{getCacheRootPath}, \link{setCacheRootPath}}{
+     Methods for getting and setting the directory where cache
+     files are stored.
+   }
+  }
+}
+
+\section{How to cite this package}{
+  Whenever using this package, please cite [1] as
+
+  \preformatted{
+Bengtsson, H. The R.oo package - Object-Oriented Programming with References Using
+Standard R Code, Proceedings of the 3rd International Workshop on Distributed
+Statistical Computing (DSC 2003), ISSN 1609-395X, Hornik, K.; Leisch, F. & Zeileis,
+A. (ed.), 2003
+}
+\emph{}
+
+}
+
+\section{Wishlist}{
+ Here is a list of features that would be useful, but which I have
+ too little time to add myself. Contributions are appreciated.
+ \itemize{
+   \item Add a functionality to identify cache files that are
+      no longer of use.  For now, there is an extra header field
+      for arbitrary comments which can be used, but maybe more
+      formal fields are useful, e.g. keywords, user, etc?
+ }
+
+ If you consider implement some of the above, make sure it is not
+ already implemented by downloading the latest "devel" version!
+}
+
+\section{Related work}{
+ See also the \pkg{filehash} package, and the \code{cache()} function
+ in the \pkg{Biobase} package of Bioconductor.
+}
+
+\author{Henrik Bengtsson}
+
+\section{License}{
+  The releases of this package is licensed under
+  LGPL version 2.1 or newer.
+
+  The development code of the packages is under a private licence
+  (where applicable) and patches sent to the author fall under the
+  latter license, but will be, if incorporated, released under the
+  "release" license above.
+}
+
+\section{References}{
+[1] H. Bengtsson, \emph{The R.oo package - Object-Oriented Programming with References Using Standard R Code}, In Kurt Hornik, Friedrich Leisch and Achim Zeileis, editors, Proceedings of the 3rd International Workshop on Distributed Statistical Computing (DSC 2003), March 20-22, Vienna, Austria. \url{http://www.ci.tuwien.ac.at/Conferences/DSC-2003/Proceedings/}
+ \cr
+}
+\keyword{package}
diff --git a/man/addMemoization.Rd b/man/addMemoization.Rd
new file mode 100644
index 0000000..03e7dc2
--- /dev/null
+++ b/man/addMemoization.Rd
@@ -0,0 +1,53 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  addMemoization.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{addMemoization}
+\alias{addMemoization.default}
+\alias{addMemoization}
+
+\title{Creates a copy of an existing function such that its results are memoized}
+
+\description{
+ Creates a copy of an existing function such that its results are memoized.
+}
+
+\usage{
+\method{addMemoization}{default}(fcn, envir=parent.frame(), ...)
+}
+
+\arguments{
+  \item{fcn}{A \code{\link[base]{function}} (or the name of a function) that should be
+    copied and have memoization added.}
+  \item{envir}{The \code{\link[base]{environment}} from where to look for the function.}
+  \item{...}{Additional arguments for controlling the memoization,
+    i.e. all arguments of \code{\link{memoizedCall}}() that are not passed
+    to \code{\link[base]{do.call}}().}
+}
+
+\value{
+  Returns a \code{\link[base]{function}}.
+}
+
+\details{
+ The new function is setup such that the the memoized call is done
+ in the environment of the caller (the parent frame of the function).
+
+  If the \code{\link[base]{function}} returns \code{\link[base]{NULL}}, that particular function call is
+  \emph{not} memoized.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ The returned function utilized \code{\link{memoizedCall}}() internally.
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/clearCache.Rd b/man/clearCache.Rd
new file mode 100644
index 0000000..30f4743
--- /dev/null
+++ b/man/clearCache.Rd
@@ -0,0 +1,51 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  clearCache.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{clearCache}
+\alias{clearCache.default}
+\alias{clearCache}
+
+\title{Removes all files in a cache file directory}
+
+\description{
+ Removes all files in a cache file directory.
+}
+
+\usage{
+\method{clearCache}{default}(path=getCachePath(...), ..., recursive=FALSE, prompt=TRUE && interactive())
+}
+
+\arguments{
+  \item{path}{A \code{\link[base]{character}} string specifying the directory to be cleared.
+    By default, the path is what is returned by \code{\link{getCachePath}}()
+    which arguments \code{...} are also passed.}
+  \item{...}{Arguments passed to \code{\link{getCachePath}}(), especially
+    argument \code{dirs} to specify subdirectories.}
+  \item{recursive}{If \code{\link[base:logical]{TRUE}}, subdirectories are also removed, otherwise
+    just the files in the specified directory.}
+  \item{prompt}{If \code{\link[base:logical]{TRUE}}, the user will be prompted to confirm that
+    the directory will cleared before files are removed.}
+}
+
+\value{
+  Returns (invisibly) a \code{\link[base]{character}} \code{\link[base]{vector}} of pathnames of the
+  files removed.  If no files were removed, \code{\link[base]{NULL}} is returned.
+}
+
+\author{Henrik Bengtsson}
+
+\details{
+  If the specified directory does not exists, an exception is thrown.
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/evalWithMemoization.Rd b/man/evalWithMemoization.Rd
new file mode 100644
index 0000000..b646392
--- /dev/null
+++ b/man/evalWithMemoization.Rd
@@ -0,0 +1,127 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  evalWithMemoization.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{evalWithMemoization}
+\alias{evalWithMemoization}
+
+
+\title{Evaluates an R expression with memoization}
+
+\description{
+ Evaluates an R expression with memoization such that the same objects are assigned to the
+ current environment and the same result is returned, if any.
+}
+
+\usage{
+evalWithMemoization(expr, key=NULL, ..., envir=parent.frame(), force=FALSE)
+}
+
+\arguments{
+  \item{expr}{The \code{\link[base]{expression}} to be evaluated.}
+  \item{key}{Additional objects to uniquely identify the evaluation.}
+  \item{...}{Additional arguments passed to \code{\link{loadCache}}()
+    and \code{\link{saveCache}}().}
+  \item{envir}{The \code{\link[base]{environment}} in which the expression should
+    be evaluated.}
+  \item{force}{If \code{\link[base:logical]{TRUE}}, existing cached results are ignored.}
+}
+
+\value{
+  Returns the value of the evaluated \code{expr} \code{\link[base]{expression}}, if any.
+}
+
+\examples{
+for (kk in 1:5) {
+  cat(sprintf("Iteration #\%d:\n", kk))
+  res <- evalWithMemoization({
+    cat("Evaluating expression...")
+    a <- 1
+    b <- 2
+    c <- 4
+    Sys.sleep(1)
+    cat("done\n")
+    b
+  })
+  print(res)
+
+  # Sanity checks
+  stopifnot(a == 1 && b == 2 && c == 4)
+
+  # Clean up
+  rm(a, b, c)
+} # for (kk ...)
+
+
+## OUTPUTS:
+## Iteration #1:
+## Evaluating expression...done
+## [1] 2
+## Iteration #2:
+## [1] 2
+## Iteration #3:
+## [1] 2
+## Iteration #4:
+## [1] 2
+## Iteration #5:
+## [1] 2
+
+
+############################################################
+# WARNING
+############################################################
+# If the expression being evaluated depends on
+# "input" objects, then these must be be specified
+# explicitly as "key" objects.
+for (ii in 1:2) {
+  for (kk in 1:3) {
+    cat(sprintf("Iteration #\%d:\n", kk))
+    res <- evalWithMemoization({
+      cat("Evaluating expression...")
+      a <- kk
+      Sys.sleep(1)
+      cat("done\n")
+      a
+    }, key=list(kk=kk))
+    print(res)
+
+    # Sanity checks
+    stopifnot(a == kk)
+
+    # Clean up
+    rm(a)
+  } # for (kk ...)
+} # for (ii ...)
+
+## OUTPUTS:
+## Iteration #1:
+## Evaluating expression...done
+## [1] 1
+## Iteration #2:
+## Evaluating expression...done
+## [1] 2
+## Iteration #3:
+## Evaluating expression...done
+## [1] 3
+## Iteration #1:
+## [1] 1
+## Iteration #2:
+## [1] 2
+## Iteration #3:
+## [1] 3
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ Internally, \code{\link[base]{eval}}() is used to evaluate the expression.
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/findCache.Rd b/man/findCache.Rd
new file mode 100644
index 0000000..1d0bf2c
--- /dev/null
+++ b/man/findCache.Rd
@@ -0,0 +1,46 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  findCache.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{findCache}
+\alias{findCache.default}
+\alias{findCache}
+
+\title{Locates a cache file}
+
+\description{
+ Locates a cache file from a key object.
+}
+
+\usage{
+\method{findCache}{default}(key=NULL, ...)
+}
+
+\arguments{
+  \item{key}{An optional object from which a hexadecimal hash
+    code will be generated and appended to the filename.}
+  \item{...}{Additional argument passed to \code{\link{generateCache}}.}
+}
+
+\value{
+  Returns the pathname as a \code{\link[base]{character}}, or \code{\link[base]{NULL}} if the no cached
+  data exists.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ \code{\link{generateCache}}.
+ \code{\link{loadCache}}().
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/generateCache.Rd b/man/generateCache.Rd
new file mode 100644
index 0000000..a8934a0
--- /dev/null
+++ b/man/generateCache.Rd
@@ -0,0 +1,48 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  generateCache.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{generateCache}
+\alias{generateCache.default}
+\alias{generateCache}
+
+\title{Generates a cache pathname from a key object}
+
+\description{
+ Generates a cache pathname from a key object.
+}
+
+\usage{
+\method{generateCache}{default}(key, suffix=".Rcache", ...)
+}
+
+\arguments{
+  \item{key}{A \code{\link[base]{list}} or an \code{\link[base]{environment}} from which a \code{\link[base]{character}} string
+    checksum will be calculated and that will constitute the name part
+    of the cache filename.}
+  \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the
+    filename.}
+  \item{...}{Arguments passed to \code{\link{getCachePath}}().}
+}
+
+\value{
+  Returns the pathname as a \code{\link[base]{character}} string.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+  Internally, the generic function \code{\link{getChecksum}}() is used to
+  calculate the checksum of argument \code{key}.
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/getCachePath.Rd b/man/getCachePath.Rd
new file mode 100644
index 0000000..18e0ede
--- /dev/null
+++ b/man/getCachePath.Rd
@@ -0,0 +1,49 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  getCachePath.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{getCachePath}
+\alias{getCachePath.default}
+\alias{getCachePath}
+
+\title{Gets the path to the file cache directory}
+
+\description{
+ Gets the path to the file cache directory.
+ If missing, the directory is created.
+}
+
+\usage{
+\method{getCachePath}{default}(dirs=NULL, path=NULL, rootPath=getCacheRootPath(), ...)
+}
+
+\arguments{
+  \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the
+     cache subdirectory (of the \emph{cache root directory}
+     as returned by \code{\link{getCacheRootPath}}()) to be used.
+     If \code{\link[base]{NULL}}, the path will be the cache root path.}
+  \item{path, rootPath}{(Advanced) \code{\link[base]{character}} strings specifying the
+     explicit/default cache path and root cache path.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns the path as a \code{\link[base]{character}} string.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+  \code{\link{setCachePath}}.
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/getCacheRootPath.Rd b/man/getCacheRootPath.Rd
new file mode 100644
index 0000000..7291c48
--- /dev/null
+++ b/man/getCacheRootPath.Rd
@@ -0,0 +1,47 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  getCacheRootPath.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{getCacheRootPath}
+\alias{getCacheRootPath.default}
+\alias{getCacheRootPath}
+
+\title{Gets the root path to the file cache directory}
+
+\description{
+ Gets the root path to the file cache directory.
+}
+
+\usage{
+\method{getCacheRootPath}{default}(defaultPath="~/.Rcache", ...)
+}
+
+\arguments{
+  \item{defaultPath}{The default path, if no user-specified directory
+    has been given.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns the path as a \code{\link[base]{character}} string.
+}
+
+\examples{
+  print(getCacheRootPath())
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ Too set the directory where cache files are stored,
+ see \code{\link{setCacheRootPath}}().
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/getChecksum.Rd b/man/getChecksum.Rd
new file mode 100644
index 0000000..eaec06c
--- /dev/null
+++ b/man/getChecksum.Rd
@@ -0,0 +1,61 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  getChecksum.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{getChecksum}
+\alias{getChecksum.default}
+\alias{getChecksum}
+
+\title{Generates a deterministic checksum for an R object}
+
+\description{
+ Generates a deterministic checksum for an R object such that (i) if the same object is used again, then
+ the same checksum is obtained, and (ii) if another object is used,
+ then a different checksum is obtained with extremely high probability.
+ In other words, it is highly unlikely that two different objects
+ have the same checksum.
+}
+
+\usage{
+\method{getChecksum}{default}(object, ...)
+}
+
+\arguments{
+  \item{object}{The object for which a checksum should be calculated.}
+  \item{...}{Additional arguments passed to \code{\link[digest]{digest}}.}
+}
+
+\value{
+  Returns checksum represented as a \code{\link[base]{character}} string.
+}
+
+\details{
+  Because \code{getChecksum()} is a generic function,
+  it is possible to provide custom methods for specific
+  classes of objects.  This means that, if a certain class
+  specifies fields that carry auxillary data, then these
+  can be excluded from the checksum calculation.
+  For instance, assume that all objects of class 'TimestampedObject'
+  contain timestamps specifying when each object was created.
+  Then a custom \code{getChecksum()} method for this class can
+  first drop the timestamp and then call the default
+  \code{getChecksum()} function.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+  Internally, the \code{\link[digest]{digest}} method is used to calculate
+  the checksum.
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/loadCache.Rd b/man/loadCache.Rd
new file mode 100755
index 0000000..a296e72
--- /dev/null
+++ b/man/loadCache.Rd
@@ -0,0 +1,96 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  loadCache.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{loadCache}
+\alias{loadCache.default}
+\alias{loadCache}
+
+\title{Loads data from file cache}
+
+\description{
+ Loads data from file cache, which is unique for an optional key object.
+}
+
+\usage{
+\method{loadCache}{default}(key=NULL, sources=NULL, suffix=".Rcache", removeOldCache=TRUE, pathname=NULL,
+  dirs=NULL, ..., onError=c("warning", "print", "quiet", "error"))
+}
+
+\arguments{
+  \item{key}{An optional object from which a hexadecimal hash
+    code will be generated and appended to the filename.}
+  \item{sources}{Optional source objects.  If the cache object has a
+    timestamp older than one of the source objects, it will be ignored
+    and removed.}
+  \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the
+    filename.}
+  \item{removeOldCache}{If \code{\link[base:logical]{TRUE}} and the cache is older than the
+    \code{sources}, the cache file is removed, otherwise not.}
+  \item{pathname}{The pathname to the cache file.  If specified,
+    arguments \code{key} and \code{suffix} are ignored.  Note that
+    this is only needed in order to read a cache file for which
+    the key is unknown, for instance, in order to investigate
+    an unknown cache file.}
+  \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the
+     cache subdirectory (of the \emph{cache root directory}
+     as returned by \code{\link{getCacheRootPath}}()) to be used.
+     If \code{\link[base]{NULL}}, the path will be the cache root path.}
+  \item{...}{Not used.}
+  \item{onError}{A \code{\link[base]{character}} string specifying what the action is
+     if an exception is thrown.}
+}
+
+\value{
+  Returns an \R object or \code{\link[base]{NULL}}, if cache does not exist.
+}
+
+\details{
+  The hash code calculated from the \code{key} object is a
+  32 characters long hexadecimal MD5 hash code.
+  For more details, see \code{\link{getChecksum}}().
+}
+
+\author{Henrik Bengtsson}
+
+\examples{
+simulate <- function(mean, sd) {
+  # 1. Try to load cached data, if already generated
+  key <- list(mean, sd)
+  data <- loadCache(key)
+  if (!is.null(data)) {
+    cat("Loaded cached data\n")
+    return(data);
+  }
+
+  # 2. If not available, generate it.
+  cat("Generating data from scratch...")
+  data <- rnorm(1000, mean=mean, sd=sd)
+  Sys.sleep(1)             # Emulate slow algorithm
+  cat("ok\n")
+  saveCache(data, key=key, comment="simulate()")
+
+  data;
+}
+
+data <- simulate(2.3, 3.0)
+data <- simulate(2.3, 3.5)
+data <- simulate(2.3, 3.0) # Will load cached data
+
+# Clean up
+file.remove(findCache(key=list(2.3,3.0)))
+file.remove(findCache(key=list(2.3,3.5)))
+}
+
+\seealso{
+ \code{\link{saveCache}}().
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/memoizedCall.Rd b/man/memoizedCall.Rd
new file mode 100644
index 0000000..a088796
--- /dev/null
+++ b/man/memoizedCall.Rd
@@ -0,0 +1,56 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  memoizedCall.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{memoizedCall}
+\alias{memoizedCall.default}
+\alias{memoizedCall}
+
+\title{Calls a function with memoization}
+
+\description{
+ Calls a function with memoization, that is, caches the results to be retrieved if
+ the function is called again with the exact same arguments.
+}
+
+\usage{
+\method{memoizedCall}{default}(what, ..., envir=parent.frame(), force=FALSE, sources=NULL, dirs=NULL)
+}
+
+\arguments{
+  \item{what}{The \code{\link[base]{function}} to be called, or a \code{\link[base]{character}} string
+    specifying the name of the function to be called,
+    cf. \code{\link[base]{do.call}}().}
+  \item{...}{Arguments passed to the function.}
+  \item{envir}{The \code{\link[base]{environment}} in which the function is evaluated.}
+  \item{force}{If \code{\link[base:logical]{TRUE}}, any cached results are ignored, otherwise not.}
+  \item{sources, dirs}{Optional arguments passed to
+    \code{\link{loadCache}}() and \code{\link{saveCache}}().}
+}
+
+\value{
+  Returns the result of the function call.
+}
+
+\details{
+  If the \code{\link[base]{function}} returns \code{\link[base]{NULL}}, that particular function call is
+  \emph{not} memoized.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ Internally, \code{\link{loadCache}}() is used to load memoized results,
+ if available.  If not available, then \code{\link{do.call}}() is used to
+ evaluate the function call,
+ and \code{\link{saveCache}}() is used to save the results to cache.
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/readCacheHeader.Rd b/man/readCacheHeader.Rd
new file mode 100755
index 0000000..8fde31b
--- /dev/null
+++ b/man/readCacheHeader.Rd
@@ -0,0 +1,61 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  readCacheHeader.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{readCacheHeader}
+\alias{readCacheHeader.default}
+\alias{readCacheHeader}
+
+\title{Loads data from file cache}
+
+\description{
+ Loads data from file cache, which is unique for an optional key object.
+}
+
+\usage{
+\method{readCacheHeader}{default}(file, ...)
+}
+
+\arguments{
+  \item{file}{A filename or a \code{\link[base:connections]{connection}}.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns a named \code{\link[base]{list}} structure with element \code{identifier},
+  \code{version}, \code{comment} (optional), \code{sources} (optional),
+  and \code{timestamp}.
+}
+
+\author{Henrik Bengtsson}
+
+\examples{
+
+data <- 1:120
+key <- list(some=1, vari=2, ables=3)
+
+saveCache(key=key, data, comment="A simple example of a cached object.")
+
+header <- readCacheHeader(findCache(key=key))
+print(header)
+
+# Clean up
+file.remove(findCache(key=key))
+}
+
+\seealso{
+ \code{\link{findCache}}().
+ \code{\link{loadCache}}().
+ \code{\link{saveCache}}().
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/saveCache.Rd b/man/saveCache.Rd
new file mode 100755
index 0000000..876cd14
--- /dev/null
+++ b/man/saveCache.Rd
@@ -0,0 +1,69 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  saveCache.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{saveCache}
+\alias{saveCache.default}
+\alias{saveCache}
+
+\title{Saves data to file cache}
+
+\description{
+ Saves data to file cache, which is unique for an optional key object.
+}
+
+\usage{
+\method{saveCache}{default}(object, key=NULL, sources=NULL, suffix=".Rcache", comment=NULL, pathname=NULL,
+  dirs=NULL, compress=getOption("R.cache::compress", FALSE), ...)
+}
+
+\arguments{
+  \item{object}{The object to be saved to file.}
+  \item{key}{An optional object from which a hexadecimal hash
+    code will be generated and appended to the filename.}
+  \item{sources}{Source objects used for comparison of timestamps when
+    cache is loaded later.}
+  \item{suffix}{A \code{\link[base]{character}} string to be appended to the end of the
+    filename.}
+  \item{comment}{An optional \code{\link[base]{character}} string written in ASCII at the
+    beginning of the file.}
+  \item{pathname}{(Advanced) An optional \code{\link[base]{character}} string specifying
+    the pathname to the cache file.  If not specified (default), a unique
+    one is automatically generated from arguments \code{key} and
+    \code{suffix} among other things.}
+  \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the
+     cache subdirectory (of the \emph{cache root directory}
+     as returned by \code{\link{getCacheRootPath}}()) to be used.
+     If \code{\link[base]{NULL}}, the path will be the cache root path.}
+  \item{compress}{If \code{\link[base:logical]{TRUE}}, the cache file will be saved using
+     gzip compression, otherwise not.}
+  \item{...}{Additional argument passed to \code{\link[base]{save}}().}
+}
+
+\value{
+  Returns (invisible) the pathname of the cache file.
+}
+
+\section{Compression}{
+ The \code{saveCache()} method saves a compressed cache file
+ (with filename extension *.gz) if argument \code{compress} is \code{\link[base:logical]{TRUE}}.
+ The \code{\link{loadCache}}() method locates (via \code{\link{findCache}}()) and
+ loads such cache files as well.
+}
+
+\author{Henrik Bengtsson}
+
+\examples{\dontrun{For an example, see ?loadCache}}
+
+\seealso{
+ For more details on how the hash code is generated etc, \code{\link{loadCache}}().
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/setCachePath.Rd b/man/setCachePath.Rd
new file mode 100644
index 0000000..c6d2284
--- /dev/null
+++ b/man/setCachePath.Rd
@@ -0,0 +1,46 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  setCachePath.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{setCachePath}
+\alias{setCachePath.default}
+\alias{setCachePath}
+
+\title{Sets the path to the file cache directory}
+
+\description{
+ Sets the path to the file cache directory.
+}
+
+\usage{
+\method{setCachePath}{default}(dirs=NULL, path=NULL, ...)
+}
+
+\arguments{
+  \item{dirs}{A \code{\link[base]{character}} \code{\link[base]{vector}} constituting the path to the
+     cache subdirectory of interest.}
+  \item{path}{The path to override the path according to the
+     \code{dirs} argument.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns nothing.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+  \code{\link{getCachePath}}().
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/man/setCacheRootPath.Rd b/man/setCacheRootPath.Rd
new file mode 100644
index 0000000..9a1f46f
--- /dev/null
+++ b/man/setCacheRootPath.Rd
@@ -0,0 +1,42 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  setCacheRootPath.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{setCacheRootPath}
+\alias{setCacheRootPath.default}
+\alias{setCacheRootPath}
+
+\title{Sets the root path to the file cache directory}
+
+\description{
+ Sets the root path to the file cache directory.
+ By default, this function will set it to \code{~/.Rcache/}.
+}
+
+\usage{
+\method{setCacheRootPath}{default}(path="~/.Rcache", ...)
+}
+
+\arguments{
+  \item{path}{The path.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns (invisibly) the old root path.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ \code{\link{getCacheRootPath}}().
+}
+
+
+
+\keyword{programming}
+\keyword{IO}
diff --git a/man/setupCacheRootPath.Rd b/man/setupCacheRootPath.Rd
new file mode 100644
index 0000000..b3eee94
--- /dev/null
+++ b/man/setupCacheRootPath.Rd
@@ -0,0 +1,55 @@
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% Do not modify this file since it was automatically generated from:
+% 
+%  setupCacheRootPath.R
+% 
+% by the Rdoc compiler part of the R.oo package.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+\name{setupCacheRootPath}
+\alias{setupCacheRootPath.default}
+\alias{setupCacheRootPath}
+
+\title{Interactively offers the user to set up the default root path}
+
+\description{
+ Interactively offers the user to set up the default root path.
+}
+
+\usage{
+\method{setupCacheRootPath}{default}(defaultPath="~/.Rcache/", ...)
+}
+
+\arguments{
+  \item{defaultPath}{Default root path to set.}
+  \item{...}{Not used.}
+}
+
+\value{
+  Returns (invisibly) the root path,
+  or \code{\link[base]{NULL}} if running a non-interactive session.
+}
+
+\details{
+  If the cache root path is already set, it is used and nothing is done.
+  If the "default" root path (\code{defaultPath}) exists, it is used,
+  otherwise, if running interactively, the user is asked to approve
+  the usage (and creation) of the default root path.
+  In all other cases, the cache root path is set to a session-specific
+  temporary directory.
+}
+
+\author{Henrik Bengtsson}
+
+\seealso{
+ Internally, \code{\link{setCacheRootPath}}() is used to set the cache root path.
+ The \code{\link[base]{interactive}}() function is used to test whether \R is
+ running interactively or not.
+}
+
+
+
+
+\keyword{programming}
+\keyword{IO}
+\keyword{internal}
diff --git a/tests/Object.getChecksum.R b/tests/Object.getChecksum.R
new file mode 100644
index 0000000..98062f0
--- /dev/null
+++ b/tests/Object.getChecksum.R
@@ -0,0 +1,5 @@
+library("R.cache")
+
+obj <- R.oo::Object()
+obj$value <- 42L
+print(getChecksum(obj))
diff --git a/tests/StaticMethodsAndNamespaces.R b/tests/StaticMethodsAndNamespaces.R
new file mode 100644
index 0000000..508ff33
--- /dev/null
+++ b/tests/StaticMethodsAndNamespaces.R
@@ -0,0 +1 @@
+R.cache::clearCache(dirs=sample(1:10))
diff --git a/tests/addMemoization.R b/tests/addMemoization.R
new file mode 100644
index 0000000..a229bae
--- /dev/null
+++ b/tests/addMemoization.R
@@ -0,0 +1,55 @@
+library("R.cache")
+
+# Use an empty temporary file cache
+setCacheRootPath(path=file.path(tempdir()))
+clearCache(recursive=TRUE, prompt=FALSE)
+dirs <- c("tests", "addMemoization")
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Define function to be memoized
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sleep <- function(time) {
+  cat(sprintf("Sleeping for %g seconds...\n", time))
+  Sys.sleep(time)
+  cat(sprintf("Sleeping for %g seconds...done\n", time))
+  time
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Test memoization
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sleep <- addMemoization(sleep)
+
+# There will be no cache hit for the first call
+t0 <- system.time({
+  res0 <- sleep(1.5)
+})[3]
+print(t0)
+
+# The second will have a cache hit and therefore
+# return the memoized results momentarily.
+t1 <- system.time({
+  res1 <- sleep(1.5)
+})[3]
+print(t1)
+print(t1/t0)
+
+# Sanity check
+stopifnot(identical(res1, res0))
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Don't memoize already memoized functions
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sleep2 <- addMemoization(sleep)
+stopifnot(identical(sleep2, sleep))
+
+sleep3 <- addMemoization("sleep")
+stopifnot(identical(sleep3, sleep))
+
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Exception handling
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+res <- try(addMemoization("non-existing-function"), silent=TRUE)
+stopifnot(inherits(res, "try-error"))
diff --git a/tests/assertDigest.R b/tests/assertDigest.R
new file mode 100644
index 0000000..79da6b6
--- /dev/null
+++ b/tests/assertDigest.R
@@ -0,0 +1,4 @@
+R.cache:::.assertDigest()
+
+library("R.cache")
+R.cache:::.assertDigest()
diff --git a/tests/clearCache.R b/tests/clearCache.R
new file mode 100644
index 0000000..399d0a8
--- /dev/null
+++ b/tests/clearCache.R
@@ -0,0 +1,16 @@
+library("R.cache")
+
+## Use an empty temporary file cache
+setCacheRootPath(path=file.path(tempdir()))
+
+## Try to clear it
+clearCache(recursive=TRUE, prompt=FALSE)
+clearCache(recursive=TRUE, prompt=TRUE)
+
+dirs <- c("tests", "clearCache")
+saveCache(1, key=list("clearCache"), dirs=dirs)
+
+clearCache(recursive=FALSE, prompt=TRUE)
+clearCache(recursive=TRUE, prompt=TRUE)
+clearCache(recursive=FALSE, prompt=FALSE)
+clearCache(recursive=TRUE, prompt=FALSE)
diff --git a/tests/evalWithMemoization.R b/tests/evalWithMemoization.R
new file mode 100644
index 0000000..881b6e6
--- /dev/null
+++ b/tests/evalWithMemoization.R
@@ -0,0 +1,46 @@
+library("R.cache")
+
+for (kk in 1:5) {
+  cat(sprintf("Iteration #%d:\n", kk))
+  res <- evalWithMemoization({
+    cat("Evaluating expression...")
+    a <- 1
+    b <- 2
+    c <- 4
+    cat("done\n")
+    b
+  })
+  print(res)
+
+  # Sanity checks
+  stopifnot(a == 1 && b == 2 && c == 4)
+
+  # Clean up
+  rm(list=c("a", "b", "c"))
+} # for (kk ...)
+
+
+############################################################
+# WARNING
+############################################################
+# If the expression being evaluated depends on
+# "input" objects, then these must be be specified
+# explicitly as "key" objects.
+for (ii in 1:2) {
+  for (kk in 1:3) {
+    cat(sprintf("Iteration #%d:\n", kk))
+    res <- evalWithMemoization({
+      cat("Evaluating expression...")
+      a <- kk
+      cat("done\n")
+      a
+    }, key=list(kk=kk))
+    print(res)
+
+    # Sanity checks
+    stopifnot(a == kk)
+
+    # Clean up
+    rm(list=c("a"))
+  } # for (kk ...)
+} # for (ii ...)
diff --git a/tests/getCachePath.R b/tests/getCachePath.R
new file mode 100644
index 0000000..5e13aee
--- /dev/null
+++ b/tests/getCachePath.R
@@ -0,0 +1,10 @@
+library("R.cache")
+
+root <- getCacheRootPath()
+print(root)
+
+path <- getCachePath(dirs=c("abc", "def"))
+print(path)
+
+path <- getCachePath(dirs=c("abc", "def"), path="subdir")
+print(path)
diff --git a/tests/getCacheRootPath.R b/tests/getCacheRootPath.R
new file mode 100644
index 0000000..189c880
--- /dev/null
+++ b/tests/getCacheRootPath.R
@@ -0,0 +1,43 @@
+library("R.cache")
+setupCacheRootPath <- R.cache:::setupCacheRootPath
+
+oopts <- options()
+
+tmpdir <- tempdir()
+setCacheRootPath(path=tmpdir)
+
+print(getCacheRootPath())
+
+setupCacheRootPath(defaultPath=tmpdir)
+path <- getCacheRootPath(NULL)
+print(path)
+stopifnot(identical(path, tmpdir))
+
+options("R.cache::rootPath"=NULL)
+print(getCacheRootPath())
+
+options("R.cache.path"="foo")
+print(getCacheRootPath())
+
+options("R.cache.path"=NULL)
+print(getCacheRootPath())
+
+oenv <- Sys.getenv("R_CACHE_PATH")
+Sys.setenv("R_CACHE_PATH"="")
+print(getCacheRootPath())
+
+path <- getCacheRootPath(NULL)
+print(path)
+stopifnot(is.null(path))
+setupCacheRootPath(defaultPath=tmpdir)
+
+path <- getCacheRootPath(NULL)
+print(path)
+stopifnot(identical(path, tmpdir))
+
+
+## Cleanup
+options(oopts)
+args <- list(oenv)
+names(args) <- "R_CACHE_PATH"
+do.call(Sys.setenv, args)
diff --git a/tests/loadCache.R b/tests/loadCache.R
new file mode 100644
index 0000000..8684052
--- /dev/null
+++ b/tests/loadCache.R
@@ -0,0 +1,37 @@
+library("R.cache")
+oopts <- options("R.cache::compress")
+
+simulate <- function(mean, sd) {
+  # 1. Try to load cached data, if already generated
+  key <- list(mean, sd)
+  data <- loadCache(key)
+  if (!is.null(data)) {
+    cat("Loaded cached data\n")
+    return(data)
+  }
+
+  # 2. If not available, generate it.
+  cat("Generating data from scratch...")
+  data <- rnorm(1000, mean=mean, sd=sd)
+  Sys.sleep(1)             # Emulate slow algorithm
+  cat("ok\n")
+  saveCache(data, key=key, comment="simulate()")
+
+  data
+}
+
+
+for (compress in c(FALSE, TRUE)) {
+  options("R.cache::compress"=compress)
+
+  data <- simulate(2.3, 3.0)
+  data <- simulate(2.3, 3.5)
+  data <- simulate(2.3, 3.0) # Will load cached data
+
+  # Clean up
+  file.remove(findCache(key=list(2.3,3.0)))
+  file.remove(findCache(key=list(2.3,3.5)))
+}
+
+## Cleanup
+options(oopts)
diff --git a/tests/memoizedCall.R b/tests/memoizedCall.R
new file mode 100644
index 0000000..02ed905
--- /dev/null
+++ b/tests/memoizedCall.R
@@ -0,0 +1,40 @@
+library("R.cache")
+
+# Use an empty temporary file cache
+setCacheRootPath(path=file.path(tempdir()))
+clearCache(recursive=TRUE, prompt=FALSE)
+dirs <- c("tests", "memoizedCall")
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Define function to be memoized
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+sleep <- function(time) {
+  cat(sprintf("Sleeping for %g seconds...\n", time))
+  Sys.sleep(time)
+  cat(sprintf("Sleeping for %g seconds...done\n", time))
+  time
+}
+
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# Test memoization
+# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+# There will be no cache hit for the first call
+t0 <- system.time({
+  res0 <- memoizedCall(sleep, time=1.5, dirs=dirs)
+})[3]
+print(t0)
+
+# The second will have a cache hit and therefore
+# return the memoized results momentarily.
+t1 <- system.time({
+  res1 <- memoizedCall(sleep, time=1.5, dirs=dirs)
+})[3]
+print(t1)
+if (t1 >= t0) {
+  warning("Second call to memoizedCall() took longer than the first: ",
+          t1, " >= ", t0)
+}
+
+# Sanity check
+stopifnot(identical(res1, res0))
+clearCache(recursive=TRUE)
diff --git a/tests/readCacheHeader.R b/tests/readCacheHeader.R
new file mode 100644
index 0000000..7271810
--- /dev/null
+++ b/tests/readCacheHeader.R
@@ -0,0 +1,24 @@
+library("R.cache")
+
+## Use an empty temporary file cache
+setCacheRootPath(path=file.path(tempdir()))
+
+dirs <- c("tests", "readCacheHeader")
+
+for (compress in c(FALSE, TRUE)) {
+  pathname <- saveCache(1, key=list("readCacheHeader"), dirs=dirs, compress=compress)
+
+  for (byName in c(FALSE, TRUE)) {
+    if (byName) {
+      hdr <- readCacheHeader(pathname)
+    } else {
+      con <- gzfile(pathname, open="rb")
+      hdr <- readCacheHeader(con)
+      close(con)
+    }
+    str(list(pathname=pathname, hdr=hdr))
+  }
+}
+
+## Cleanup
+clearCache(recursive=TRUE)
diff --git a/tests/setCachePath.R b/tests/setCachePath.R
new file mode 100644
index 0000000..191551d
--- /dev/null
+++ b/tests/setCachePath.R
@@ -0,0 +1,12 @@
+library("R.cache")
+setCachePath <- R.cache:::setCachePath
+
+## Use an empty temporary file cache
+tmpdir <- tempdir()
+setCacheRootPath(path=tmpdir)
+
+dirs <- c("tests", "readCacheHeader")
+setCachePath(dirs=dirs, path=tmpdir)
+
+## Cleanup
+clearCache(recursive=TRUE)
diff --git a/tests/setCacheRootPath.R b/tests/setCacheRootPath.R
new file mode 100644
index 0000000..f18f241
--- /dev/null
+++ b/tests/setCacheRootPath.R
@@ -0,0 +1,9 @@
+library("R.cache")
+
+tmpdir <- tempdir()
+setCacheRootPath(path=tmpdir)
+setCacheRootPath(path=file.path(tmpdir, "subdir"))
+setCacheRootPath(path=tmpdir)
+
+## Cleanup
+clearCache(recursive=TRUE)
diff --git a/tests/textPrompt.R b/tests/textPrompt.R
new file mode 100644
index 0000000..453c3ad
--- /dev/null
+++ b/tests/textPrompt.R
@@ -0,0 +1,15 @@
+textPrompt <- R.cache:::.textPrompt
+
+ans <- textPrompt("Do you have a minute?")
+print(ans)
+
+ans <- textPrompt("Do you have a minute?", options=c("yes", "no"))
+print(ans)
+
+## Output to standard error
+ans <- textPrompt("Do you have a minute?", type="message")
+print(ans)
+
+## Output to standard output
+ans <- textPrompt("Do you have a minute?", type="output")
+print(ans)

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/debian-med/r-cran-r.cache.git



More information about the debian-med-commit mailing list